Use IP and MAC API types for neighbors
[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 <vnet/ipsec/ikev2.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/dhcp/dhcp_proxy.h>
55 #include <vnet/bonding/node.h>
56 #include <vnet/qos/qos_types.h>
57 #include <vnet/ethernet/ethernet_types_api.h>
58 #include <vnet/ip/ip_types_api.h>
59 #include "vat/json_format.h"
60 #include <vnet/ip/ip_types_api.h>
61 #include <vnet/ethernet/ethernet_types_api.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 #define vl_print(handle, ...)
78 #define vl_printfun
79 #include <vpp/api/vpe_all_api_h.h>
80 #undef vl_printfun
81
82 #define __plugin_msg_base 0
83 #include <vlibapi/vat_helper_macros.h>
84
85 #if VPP_API_TEST_BUILTIN == 0
86 #include <netdb.h>
87
88 u32
89 vl (void *p)
90 {
91   return vec_len (p);
92 }
93
94 int
95 vat_socket_connect (vat_main_t * vam)
96 {
97   int rv;
98   vam->socket_client_main = &socket_client_main;
99   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
100                                       "vpp_api_test",
101                                       0 /* default socket rx, tx buffer */ )))
102     return rv;
103   /* vpp expects the client index in network order */
104   vam->my_client_index = htonl (socket_client_main.client_index);
105   return 0;
106 }
107 #else /* vpp built-in case, we don't do sockets... */
108 int
109 vat_socket_connect (vat_main_t * vam)
110 {
111   return 0;
112 }
113
114 int
115 vl_socket_client_read (int wait)
116 {
117   return -1;
118 };
119
120 int
121 vl_socket_client_write ()
122 {
123   return -1;
124 };
125
126 void *
127 vl_socket_client_msg_alloc (int nbytes)
128 {
129   return 0;
130 }
131 #endif
132
133
134 f64
135 vat_time_now (vat_main_t * vam)
136 {
137 #if VPP_API_TEST_BUILTIN
138   return vlib_time_now (vam->vlib_main);
139 #else
140   return clib_time_now (&vam->clib_time);
141 #endif
142 }
143
144 void
145 errmsg (char *fmt, ...)
146 {
147   vat_main_t *vam = &vat_main;
148   va_list va;
149   u8 *s;
150
151   va_start (va, fmt);
152   s = va_format (0, fmt, &va);
153   va_end (va);
154
155   vec_add1 (s, 0);
156
157 #if VPP_API_TEST_BUILTIN
158   vlib_cli_output (vam->vlib_main, (char *) s);
159 #else
160   {
161     if (vam->ifp != stdin)
162       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
163                vam->input_line_number);
164     fformat (vam->ofp, (char *) s);
165     fflush (vam->ofp);
166   }
167 #endif
168
169   vec_free (s);
170 }
171
172 #if VPP_API_TEST_BUILTIN == 0
173 static uword
174 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
175 {
176   vat_main_t *vam = va_arg (*args, vat_main_t *);
177   u32 *result = va_arg (*args, u32 *);
178   u8 *if_name;
179   uword *p;
180
181   if (!unformat (input, "%s", &if_name))
182     return 0;
183
184   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
185   if (p == 0)
186     return 0;
187   *result = p[0];
188   return 1;
189 }
190
191 static uword
192 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
193 {
194   return 0;
195 }
196
197 /* Parse an IP4 address %d.%d.%d.%d. */
198 uword
199 unformat_ip4_address (unformat_input_t * input, va_list * args)
200 {
201   u8 *result = va_arg (*args, u8 *);
202   unsigned a[4];
203
204   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
205     return 0;
206
207   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
208     return 0;
209
210   result[0] = a[0];
211   result[1] = a[1];
212   result[2] = a[2];
213   result[3] = a[3];
214
215   return 1;
216 }
217
218 uword
219 unformat_ethernet_address (unformat_input_t * input, va_list * args)
220 {
221   u8 *result = va_arg (*args, u8 *);
222   u32 i, a[6];
223
224   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
225                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
226     return 0;
227
228   /* Check range. */
229   for (i = 0; i < 6; i++)
230     if (a[i] >= (1 << 8))
231       return 0;
232
233   for (i = 0; i < 6; i++)
234     result[i] = a[i];
235
236   return 1;
237 }
238
239 /* Returns ethernet type as an int in host byte order. */
240 uword
241 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
242                                         va_list * args)
243 {
244   u16 *result = va_arg (*args, u16 *);
245   int type;
246
247   /* Numeric type. */
248   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
249     {
250       if (type >= (1 << 16))
251         return 0;
252       *result = type;
253       return 1;
254     }
255   return 0;
256 }
257
258 /* Parse an IP6 address. */
259 uword
260 unformat_ip6_address (unformat_input_t * input, va_list * args)
261 {
262   ip6_address_t *result = va_arg (*args, ip6_address_t *);
263   u16 hex_quads[8];
264   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
265   uword c, n_colon, double_colon_index;
266
267   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
268   double_colon_index = ARRAY_LEN (hex_quads);
269   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
270     {
271       hex_digit = 16;
272       if (c >= '0' && c <= '9')
273         hex_digit = c - '0';
274       else if (c >= 'a' && c <= 'f')
275         hex_digit = c + 10 - 'a';
276       else if (c >= 'A' && c <= 'F')
277         hex_digit = c + 10 - 'A';
278       else if (c == ':' && n_colon < 2)
279         n_colon++;
280       else
281         {
282           unformat_put_input (input);
283           break;
284         }
285
286       /* Too many hex quads. */
287       if (n_hex_quads >= ARRAY_LEN (hex_quads))
288         return 0;
289
290       if (hex_digit < 16)
291         {
292           hex_quad = (hex_quad << 4) | hex_digit;
293
294           /* Hex quad must fit in 16 bits. */
295           if (n_hex_digits >= 4)
296             return 0;
297
298           n_colon = 0;
299           n_hex_digits++;
300         }
301
302       /* Save position of :: */
303       if (n_colon == 2)
304         {
305           /* More than one :: ? */
306           if (double_colon_index < ARRAY_LEN (hex_quads))
307             return 0;
308           double_colon_index = n_hex_quads;
309         }
310
311       if (n_colon > 0 && n_hex_digits > 0)
312         {
313           hex_quads[n_hex_quads++] = hex_quad;
314           hex_quad = 0;
315           n_hex_digits = 0;
316         }
317     }
318
319   if (n_hex_digits > 0)
320     hex_quads[n_hex_quads++] = hex_quad;
321
322   {
323     word i;
324
325     /* Expand :: to appropriate number of zero hex quads. */
326     if (double_colon_index < ARRAY_LEN (hex_quads))
327       {
328         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
329
330         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
331           hex_quads[n_zero + i] = hex_quads[i];
332
333         for (i = 0; i < n_zero; i++)
334           hex_quads[double_colon_index + i] = 0;
335
336         n_hex_quads = ARRAY_LEN (hex_quads);
337       }
338
339     /* Too few hex quads given. */
340     if (n_hex_quads < ARRAY_LEN (hex_quads))
341       return 0;
342
343     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
344       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
345
346     return 1;
347   }
348 }
349
350 uword
351 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
352 {
353   u32 *r = va_arg (*args, u32 *);
354
355   if (0);
356 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
357   foreach_ipsec_policy_action
358 #undef _
359     else
360     return 0;
361   return 1;
362 }
363
364 uword
365 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
366 {
367   u32 *r = va_arg (*args, u32 *);
368
369   if (0);
370 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
371   foreach_ipsec_crypto_alg
372 #undef _
373     else
374     return 0;
375   return 1;
376 }
377
378 u8 *
379 format_ipsec_crypto_alg (u8 * s, va_list * args)
380 {
381   u32 i = va_arg (*args, u32);
382   u8 *t = 0;
383
384   switch (i)
385     {
386 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
387       foreach_ipsec_crypto_alg
388 #undef _
389     default:
390       return format (s, "unknown");
391     }
392   return format (s, "%s", t);
393 }
394
395 uword
396 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
397 {
398   u32 *r = va_arg (*args, u32 *);
399
400   if (0);
401 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
402   foreach_ipsec_integ_alg
403 #undef _
404     else
405     return 0;
406   return 1;
407 }
408
409 u8 *
410 format_ipsec_integ_alg (u8 * s, va_list * args)
411 {
412   u32 i = va_arg (*args, u32);
413   u8 *t = 0;
414
415   switch (i)
416     {
417 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
418       foreach_ipsec_integ_alg
419 #undef _
420     default:
421       return format (s, "unknown");
422     }
423   return format (s, "%s", t);
424 }
425
426 uword
427 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
428 {
429   u32 *r = va_arg (*args, u32 *);
430
431   if (0);
432 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
433   foreach_ikev2_auth_method
434 #undef _
435     else
436     return 0;
437   return 1;
438 }
439
440 uword
441 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
442 {
443   u32 *r = va_arg (*args, u32 *);
444
445   if (0);
446 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
447   foreach_ikev2_id_type
448 #undef _
449     else
450     return 0;
451   return 1;
452 }
453 #else /* VPP_API_TEST_BUILTIN == 1 */
454 static uword
455 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
456 {
457   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
458   vnet_main_t *vnm = vnet_get_main ();
459   u32 *result = va_arg (*args, u32 *);
460
461   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
462 }
463
464 static uword
465 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
466 {
467   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
468   vnet_main_t *vnm = vnet_get_main ();
469   u32 *result = va_arg (*args, u32 *);
470
471   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
472 }
473
474 #endif /* VPP_API_TEST_BUILTIN */
475
476 static uword
477 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
478 {
479   u8 *r = va_arg (*args, u8 *);
480
481   if (unformat (input, "kbps"))
482     *r = SSE2_QOS_RATE_KBPS;
483   else if (unformat (input, "pps"))
484     *r = SSE2_QOS_RATE_PPS;
485   else
486     return 0;
487   return 1;
488 }
489
490 static uword
491 unformat_policer_round_type (unformat_input_t * input, va_list * args)
492 {
493   u8 *r = va_arg (*args, u8 *);
494
495   if (unformat (input, "closest"))
496     *r = SSE2_QOS_ROUND_TO_CLOSEST;
497   else if (unformat (input, "up"))
498     *r = SSE2_QOS_ROUND_TO_UP;
499   else if (unformat (input, "down"))
500     *r = SSE2_QOS_ROUND_TO_DOWN;
501   else
502     return 0;
503   return 1;
504 }
505
506 static uword
507 unformat_policer_type (unformat_input_t * input, va_list * args)
508 {
509   u8 *r = va_arg (*args, u8 *);
510
511   if (unformat (input, "1r2c"))
512     *r = SSE2_QOS_POLICER_TYPE_1R2C;
513   else if (unformat (input, "1r3c"))
514     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
515   else if (unformat (input, "2r3c-2698"))
516     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
517   else if (unformat (input, "2r3c-4115"))
518     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
519   else if (unformat (input, "2r3c-mef5cf1"))
520     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
521   else
522     return 0;
523   return 1;
524 }
525
526 static uword
527 unformat_dscp (unformat_input_t * input, va_list * va)
528 {
529   u8 *r = va_arg (*va, u8 *);
530
531   if (0);
532 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
533   foreach_vnet_dscp
534 #undef _
535     else
536     return 0;
537   return 1;
538 }
539
540 static uword
541 unformat_policer_action_type (unformat_input_t * input, va_list * va)
542 {
543   sse2_qos_pol_action_params_st *a
544     = va_arg (*va, sse2_qos_pol_action_params_st *);
545
546   if (unformat (input, "drop"))
547     a->action_type = SSE2_QOS_ACTION_DROP;
548   else if (unformat (input, "transmit"))
549     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
550   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
551     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
552   else
553     return 0;
554   return 1;
555 }
556
557 static uword
558 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
559 {
560   u32 *r = va_arg (*va, u32 *);
561   u32 tid;
562
563   if (unformat (input, "ip4"))
564     tid = POLICER_CLASSIFY_TABLE_IP4;
565   else if (unformat (input, "ip6"))
566     tid = POLICER_CLASSIFY_TABLE_IP6;
567   else if (unformat (input, "l2"))
568     tid = POLICER_CLASSIFY_TABLE_L2;
569   else
570     return 0;
571
572   *r = tid;
573   return 1;
574 }
575
576 static uword
577 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
578 {
579   u32 *r = va_arg (*va, u32 *);
580   u32 tid;
581
582   if (unformat (input, "ip4"))
583     tid = FLOW_CLASSIFY_TABLE_IP4;
584   else if (unformat (input, "ip6"))
585     tid = FLOW_CLASSIFY_TABLE_IP6;
586   else
587     return 0;
588
589   *r = tid;
590   return 1;
591 }
592
593 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
594 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
595 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
596 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
597
598 #if (VPP_API_TEST_BUILTIN==0)
599 uword
600 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
601 {
602   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
603   mfib_itf_attribute_t attr;
604
605   old = *iflags;
606   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
607   {
608     if (unformat (input, mfib_itf_flag_long_names[attr]))
609       *iflags |= (1 << attr);
610   }
611   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
612   {
613     if (unformat (input, mfib_itf_flag_names[attr]))
614       *iflags |= (1 << attr);
615   }
616
617   return (old == *iflags ? 0 : 1);
618 }
619
620 uword
621 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
622 {
623   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
624   mfib_entry_attribute_t attr;
625
626   old = *eflags;
627   FOR_EACH_MFIB_ATTRIBUTE (attr)
628   {
629     if (unformat (input, mfib_flag_long_names[attr]))
630       *eflags |= (1 << attr);
631   }
632   FOR_EACH_MFIB_ATTRIBUTE (attr)
633   {
634     if (unformat (input, mfib_flag_names[attr]))
635       *eflags |= (1 << attr);
636   }
637
638   return (old == *eflags ? 0 : 1);
639 }
640
641 u8 *
642 format_ip4_address (u8 * s, va_list * args)
643 {
644   u8 *a = va_arg (*args, u8 *);
645   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
646 }
647
648 u8 *
649 format_ip6_address (u8 * s, va_list * args)
650 {
651   ip6_address_t *a = va_arg (*args, ip6_address_t *);
652   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
653
654   i_max_n_zero = ARRAY_LEN (a->as_u16);
655   max_n_zeros = 0;
656   i_first_zero = i_max_n_zero;
657   n_zeros = 0;
658   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
659     {
660       u32 is_zero = a->as_u16[i] == 0;
661       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
662         {
663           i_first_zero = i;
664           n_zeros = 0;
665         }
666       n_zeros += is_zero;
667       if ((!is_zero && n_zeros > max_n_zeros)
668           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
669         {
670           i_max_n_zero = i_first_zero;
671           max_n_zeros = n_zeros;
672           i_first_zero = ARRAY_LEN (a->as_u16);
673           n_zeros = 0;
674         }
675     }
676
677   last_double_colon = 0;
678   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
679     {
680       if (i == i_max_n_zero && max_n_zeros > 1)
681         {
682           s = format (s, "::");
683           i += max_n_zeros - 1;
684           last_double_colon = 1;
685         }
686       else
687         {
688           s = format (s, "%s%x",
689                       (last_double_colon || i == 0) ? "" : ":",
690                       clib_net_to_host_u16 (a->as_u16[i]));
691           last_double_colon = 0;
692         }
693     }
694
695   return s;
696 }
697
698 /* Format an IP46 address. */
699 u8 *
700 format_ip46_address (u8 * s, va_list * args)
701 {
702   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
703   ip46_type_t type = va_arg (*args, ip46_type_t);
704   int is_ip4 = 1;
705
706   switch (type)
707     {
708     case IP46_TYPE_ANY:
709       is_ip4 = ip46_address_is_ip4 (ip46);
710       break;
711     case IP46_TYPE_IP4:
712       is_ip4 = 1;
713       break;
714     case IP46_TYPE_IP6:
715       is_ip4 = 0;
716       break;
717     }
718
719   return is_ip4 ?
720     format (s, "%U", format_ip4_address, &ip46->ip4) :
721     format (s, "%U", format_ip6_address, &ip46->ip6);
722 }
723
724 u8 *
725 format_ethernet_address (u8 * s, va_list * args)
726 {
727   u8 *a = va_arg (*args, u8 *);
728
729   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
730                  a[0], a[1], a[2], a[3], a[4], a[5]);
731 }
732 #endif
733
734 static void
735 increment_v4_address (ip4_address_t * a)
736 {
737   u32 v;
738
739   v = ntohl (a->as_u32) + 1;
740   a->as_u32 = ntohl (v);
741 }
742
743 static void
744 increment_v6_address (ip6_address_t * a)
745 {
746   u64 v0, v1;
747
748   v0 = clib_net_to_host_u64 (a->as_u64[0]);
749   v1 = clib_net_to_host_u64 (a->as_u64[1]);
750
751   v1 += 1;
752   if (v1 == 0)
753     v0 += 1;
754   a->as_u64[0] = clib_net_to_host_u64 (v0);
755   a->as_u64[1] = clib_net_to_host_u64 (v1);
756 }
757
758 static void
759 increment_mac_address (u8 * mac)
760 {
761   u64 tmp = *((u64 *) mac);
762   tmp = clib_net_to_host_u64 (tmp);
763   tmp += 1 << 16;               /* skip unused (least significant) octets */
764   tmp = clib_host_to_net_u64 (tmp);
765
766   clib_memcpy (mac, &tmp, 6);
767 }
768
769 static void vl_api_create_loopback_reply_t_handler
770   (vl_api_create_loopback_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   i32 retval = ntohl (mp->retval);
774
775   vam->retval = retval;
776   vam->regenerate_interface_table = 1;
777   vam->sw_if_index = ntohl (mp->sw_if_index);
778   vam->result_ready = 1;
779 }
780
781 static void vl_api_create_loopback_reply_t_handler_json
782   (vl_api_create_loopback_reply_t * mp)
783 {
784   vat_main_t *vam = &vat_main;
785   vat_json_node_t node;
786
787   vat_json_init_object (&node);
788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
790
791   vat_json_print (vam->ofp, &node);
792   vat_json_free (&node);
793   vam->retval = ntohl (mp->retval);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_create_loopback_instance_reply_t_handler
798   (vl_api_create_loopback_instance_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   i32 retval = ntohl (mp->retval);
802
803   vam->retval = retval;
804   vam->regenerate_interface_table = 1;
805   vam->sw_if_index = ntohl (mp->sw_if_index);
806   vam->result_ready = 1;
807 }
808
809 static void vl_api_create_loopback_instance_reply_t_handler_json
810   (vl_api_create_loopback_instance_reply_t * mp)
811 {
812   vat_main_t *vam = &vat_main;
813   vat_json_node_t node;
814
815   vat_json_init_object (&node);
816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
818
819   vat_json_print (vam->ofp, &node);
820   vat_json_free (&node);
821   vam->retval = ntohl (mp->retval);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_af_packet_create_reply_t_handler
826   (vl_api_af_packet_create_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   i32 retval = ntohl (mp->retval);
830
831   vam->retval = retval;
832   vam->regenerate_interface_table = 1;
833   vam->sw_if_index = ntohl (mp->sw_if_index);
834   vam->result_ready = 1;
835 }
836
837 static void vl_api_af_packet_create_reply_t_handler_json
838   (vl_api_af_packet_create_reply_t * mp)
839 {
840   vat_main_t *vam = &vat_main;
841   vat_json_node_t node;
842
843   vat_json_init_object (&node);
844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
845   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
846
847   vat_json_print (vam->ofp, &node);
848   vat_json_free (&node);
849
850   vam->retval = ntohl (mp->retval);
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_create_vlan_subif_reply_t_handler
855   (vl_api_create_vlan_subif_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   i32 retval = ntohl (mp->retval);
859
860   vam->retval = retval;
861   vam->regenerate_interface_table = 1;
862   vam->sw_if_index = ntohl (mp->sw_if_index);
863   vam->result_ready = 1;
864 }
865
866 static void vl_api_create_vlan_subif_reply_t_handler_json
867   (vl_api_create_vlan_subif_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871
872   vat_json_init_object (&node);
873   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
874   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
875
876   vat_json_print (vam->ofp, &node);
877   vat_json_free (&node);
878
879   vam->retval = ntohl (mp->retval);
880   vam->result_ready = 1;
881 }
882
883 static void vl_api_create_subif_reply_t_handler
884   (vl_api_create_subif_reply_t * mp)
885 {
886   vat_main_t *vam = &vat_main;
887   i32 retval = ntohl (mp->retval);
888
889   vam->retval = retval;
890   vam->regenerate_interface_table = 1;
891   vam->sw_if_index = ntohl (mp->sw_if_index);
892   vam->result_ready = 1;
893 }
894
895 static void vl_api_create_subif_reply_t_handler_json
896   (vl_api_create_subif_reply_t * mp)
897 {
898   vat_main_t *vam = &vat_main;
899   vat_json_node_t node;
900
901   vat_json_init_object (&node);
902   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
903   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
904
905   vat_json_print (vam->ofp, &node);
906   vat_json_free (&node);
907
908   vam->retval = ntohl (mp->retval);
909   vam->result_ready = 1;
910 }
911
912 static void vl_api_interface_name_renumber_reply_t_handler
913   (vl_api_interface_name_renumber_reply_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   i32 retval = ntohl (mp->retval);
917
918   vam->retval = retval;
919   vam->regenerate_interface_table = 1;
920   vam->result_ready = 1;
921 }
922
923 static void vl_api_interface_name_renumber_reply_t_handler_json
924   (vl_api_interface_name_renumber_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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 /*
940  * Special-case: build the interface table, maintain
941  * the next loopback sw_if_index vbl.
942  */
943 static void vl_api_sw_interface_details_t_handler
944   (vl_api_sw_interface_details_t * mp)
945 {
946   vat_main_t *vam = &vat_main;
947   u8 *s = format (0, "%s%c", mp->interface_name, 0);
948
949   hash_set_mem (vam->sw_if_index_by_interface_name, s,
950                 ntohl (mp->sw_if_index));
951
952   /* In sub interface case, fill the sub interface table entry */
953   if (mp->sw_if_index != mp->sup_sw_if_index)
954     {
955       sw_interface_subif_t *sub = NULL;
956
957       vec_add2 (vam->sw_if_subif_table, sub, 1);
958
959       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
960       strncpy ((char *) sub->interface_name, (char *) s,
961                vec_len (sub->interface_name));
962       sub->sw_if_index = ntohl (mp->sw_if_index);
963       sub->sub_id = ntohl (mp->sub_id);
964
965       sub->sub_dot1ad = mp->sub_dot1ad;
966       sub->sub_number_of_tags = mp->sub_number_of_tags;
967       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
968       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
969       sub->sub_exact_match = mp->sub_exact_match;
970       sub->sub_default = mp->sub_default;
971       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
972       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
973
974       /* vlan tag rewrite */
975       sub->vtr_op = ntohl (mp->vtr_op);
976       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
977       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
978       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
979     }
980 }
981
982 static void vl_api_sw_interface_details_t_handler_json
983   (vl_api_sw_interface_details_t * mp)
984 {
985   vat_main_t *vam = &vat_main;
986   vat_json_node_t *node = NULL;
987
988   if (VAT_JSON_ARRAY != vam->json_tree.type)
989     {
990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
991       vat_json_init_array (&vam->json_tree);
992     }
993   node = vat_json_array_add (&vam->json_tree);
994
995   vat_json_init_object (node);
996   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
997   vat_json_object_add_uint (node, "sup_sw_if_index",
998                             ntohl (mp->sup_sw_if_index));
999   vat_json_object_add_uint (node, "l2_address_length",
1000                             ntohl (mp->l2_address_length));
1001   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1002                              sizeof (mp->l2_address));
1003   vat_json_object_add_string_copy (node, "interface_name",
1004                                    mp->interface_name);
1005   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1006   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1007   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1008   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1009   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1010   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1011   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1012   vat_json_object_add_uint (node, "sub_number_of_tags",
1013                             mp->sub_number_of_tags);
1014   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1015                             ntohs (mp->sub_outer_vlan_id));
1016   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1017                             ntohs (mp->sub_inner_vlan_id));
1018   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1019   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1020   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1021                             mp->sub_outer_vlan_id_any);
1022   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1023                             mp->sub_inner_vlan_id_any);
1024   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1025   vat_json_object_add_uint (node, "vtr_push_dot1q",
1026                             ntohl (mp->vtr_push_dot1q));
1027   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1028   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1029   if (mp->sub_dot1ah)
1030     {
1031       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1032                                        format (0, "%U",
1033                                                format_ethernet_address,
1034                                                &mp->b_dmac));
1035       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1036                                        format (0, "%U",
1037                                                format_ethernet_address,
1038                                                &mp->b_smac));
1039       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1040       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1041     }
1042 }
1043
1044 #if VPP_API_TEST_BUILTIN == 0
1045 static void vl_api_sw_interface_event_t_handler
1046   (vl_api_sw_interface_event_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   if (vam->interface_event_display)
1050     errmsg ("interface flags: sw_if_index %d %s %s",
1051             ntohl (mp->sw_if_index),
1052             mp->admin_up_down ? "admin-up" : "admin-down",
1053             mp->link_up_down ? "link-up" : "link-down");
1054 }
1055 #endif
1056
1057 static void vl_api_sw_interface_event_t_handler_json
1058   (vl_api_sw_interface_event_t * mp)
1059 {
1060   /* JSON output not supported */
1061 }
1062
1063 static void
1064 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1065 {
1066   vat_main_t *vam = &vat_main;
1067   i32 retval = ntohl (mp->retval);
1068
1069   vam->retval = retval;
1070   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1071   vam->result_ready = 1;
1072 }
1073
1074 static void
1075 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1076 {
1077   vat_main_t *vam = &vat_main;
1078   vat_json_node_t node;
1079   api_main_t *am = &api_main;
1080   void *oldheap;
1081   u8 *reply;
1082
1083   vat_json_init_object (&node);
1084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1085   vat_json_object_add_uint (&node, "reply_in_shmem",
1086                             ntohl (mp->reply_in_shmem));
1087   /* Toss the shared-memory original... */
1088   pthread_mutex_lock (&am->vlib_rp->mutex);
1089   oldheap = svm_push_data_heap (am->vlib_rp);
1090
1091   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1092   vec_free (reply);
1093
1094   svm_pop_heap (oldheap);
1095   pthread_mutex_unlock (&am->vlib_rp->mutex);
1096
1097   vat_json_print (vam->ofp, &node);
1098   vat_json_free (&node);
1099
1100   vam->retval = ntohl (mp->retval);
1101   vam->result_ready = 1;
1102 }
1103
1104 static void
1105 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1106 {
1107   vat_main_t *vam = &vat_main;
1108   i32 retval = ntohl (mp->retval);
1109   u32 length = vl_api_string_len (&mp->reply);
1110
1111   vec_reset_length (vam->cmd_reply);
1112
1113   vam->retval = retval;
1114   if (retval == 0)
1115     {
1116       vec_validate (vam->cmd_reply, length);
1117       clib_memcpy ((char *) (vam->cmd_reply),
1118                    vl_api_from_api_string (&mp->reply), length);
1119       vam->cmd_reply[length] = 0;
1120     }
1121   vam->result_ready = 1;
1122 }
1123
1124 static void
1125 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1126 {
1127   vat_main_t *vam = &vat_main;
1128   vat_json_node_t node;
1129
1130   vec_reset_length (vam->cmd_reply);
1131
1132   vat_json_init_object (&node);
1133   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1134   vat_json_object_add_string_copy (&node, "reply",
1135                                    vl_api_from_api_string (&mp->reply));
1136
1137   vat_json_print (vam->ofp, &node);
1138   vat_json_free (&node);
1139
1140   vam->retval = ntohl (mp->retval);
1141   vam->result_ready = 1;
1142 }
1143
1144 static void vl_api_classify_add_del_table_reply_t_handler
1145   (vl_api_classify_add_del_table_reply_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   i32 retval = ntohl (mp->retval);
1149   if (vam->async_mode)
1150     {
1151       vam->async_errors += (retval < 0);
1152     }
1153   else
1154     {
1155       vam->retval = retval;
1156       if (retval == 0 &&
1157           ((mp->new_table_index != 0xFFFFFFFF) ||
1158            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1159            (mp->match_n_vectors != 0xFFFFFFFF)))
1160         /*
1161          * Note: this is just barely thread-safe, depends on
1162          * the main thread spinning waiting for an answer...
1163          */
1164         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1165                 ntohl (mp->new_table_index),
1166                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1167       vam->result_ready = 1;
1168     }
1169 }
1170
1171 static void vl_api_classify_add_del_table_reply_t_handler_json
1172   (vl_api_classify_add_del_table_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176
1177   vat_json_init_object (&node);
1178   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1179   vat_json_object_add_uint (&node, "new_table_index",
1180                             ntohl (mp->new_table_index));
1181   vat_json_object_add_uint (&node, "skip_n_vectors",
1182                             ntohl (mp->skip_n_vectors));
1183   vat_json_object_add_uint (&node, "match_n_vectors",
1184                             ntohl (mp->match_n_vectors));
1185
1186   vat_json_print (vam->ofp, &node);
1187   vat_json_free (&node);
1188
1189   vam->retval = ntohl (mp->retval);
1190   vam->result_ready = 1;
1191 }
1192
1193 static void vl_api_get_node_index_reply_t_handler
1194   (vl_api_get_node_index_reply_t * mp)
1195 {
1196   vat_main_t *vam = &vat_main;
1197   i32 retval = ntohl (mp->retval);
1198   if (vam->async_mode)
1199     {
1200       vam->async_errors += (retval < 0);
1201     }
1202   else
1203     {
1204       vam->retval = retval;
1205       if (retval == 0)
1206         errmsg ("node index %d", ntohl (mp->node_index));
1207       vam->result_ready = 1;
1208     }
1209 }
1210
1211 static void vl_api_get_node_index_reply_t_handler_json
1212   (vl_api_get_node_index_reply_t * mp)
1213 {
1214   vat_main_t *vam = &vat_main;
1215   vat_json_node_t node;
1216
1217   vat_json_init_object (&node);
1218   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1219   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1220
1221   vat_json_print (vam->ofp, &node);
1222   vat_json_free (&node);
1223
1224   vam->retval = ntohl (mp->retval);
1225   vam->result_ready = 1;
1226 }
1227
1228 static void vl_api_get_next_index_reply_t_handler
1229   (vl_api_get_next_index_reply_t * mp)
1230 {
1231   vat_main_t *vam = &vat_main;
1232   i32 retval = ntohl (mp->retval);
1233   if (vam->async_mode)
1234     {
1235       vam->async_errors += (retval < 0);
1236     }
1237   else
1238     {
1239       vam->retval = retval;
1240       if (retval == 0)
1241         errmsg ("next node index %d", ntohl (mp->next_index));
1242       vam->result_ready = 1;
1243     }
1244 }
1245
1246 static void vl_api_get_next_index_reply_t_handler_json
1247   (vl_api_get_next_index_reply_t * mp)
1248 {
1249   vat_main_t *vam = &vat_main;
1250   vat_json_node_t node;
1251
1252   vat_json_init_object (&node);
1253   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1254   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1255
1256   vat_json_print (vam->ofp, &node);
1257   vat_json_free (&node);
1258
1259   vam->retval = ntohl (mp->retval);
1260   vam->result_ready = 1;
1261 }
1262
1263 static void vl_api_add_node_next_reply_t_handler
1264   (vl_api_add_node_next_reply_t * mp)
1265 {
1266   vat_main_t *vam = &vat_main;
1267   i32 retval = ntohl (mp->retval);
1268   if (vam->async_mode)
1269     {
1270       vam->async_errors += (retval < 0);
1271     }
1272   else
1273     {
1274       vam->retval = retval;
1275       if (retval == 0)
1276         errmsg ("next index %d", ntohl (mp->next_index));
1277       vam->result_ready = 1;
1278     }
1279 }
1280
1281 static void vl_api_add_node_next_reply_t_handler_json
1282   (vl_api_add_node_next_reply_t * mp)
1283 {
1284   vat_main_t *vam = &vat_main;
1285   vat_json_node_t node;
1286
1287   vat_json_init_object (&node);
1288   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1289   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1290
1291   vat_json_print (vam->ofp, &node);
1292   vat_json_free (&node);
1293
1294   vam->retval = ntohl (mp->retval);
1295   vam->result_ready = 1;
1296 }
1297
1298 static void vl_api_show_version_reply_t_handler
1299   (vl_api_show_version_reply_t * mp)
1300 {
1301   vat_main_t *vam = &vat_main;
1302   i32 retval = ntohl (mp->retval);
1303
1304   if (retval >= 0)
1305     {
1306       char *s;
1307       char *p = (char *) &mp->program;
1308
1309       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1310       errmsg ("        program: %s\n", s);
1311       free (s);
1312
1313       p +=
1314         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1315       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1316       errmsg ("        version: %s\n", s);
1317       free (s);
1318
1319       p +=
1320         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1321       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1322       errmsg ("     build date: %s\n", s);
1323       free (s);
1324
1325       p +=
1326         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1327       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1328       errmsg ("build directory: %s\n", s);
1329       free (s);
1330     }
1331   vam->retval = retval;
1332   vam->result_ready = 1;
1333 }
1334
1335 static void vl_api_show_version_reply_t_handler_json
1336   (vl_api_show_version_reply_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   vat_json_node_t node;
1340
1341   vat_json_init_object (&node);
1342   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1343   char *p = (char *) &mp->program;
1344   vat_json_object_add_string_copy (&node, "program",
1345                                    vl_api_from_api_string ((vl_api_string_t *)
1346                                                            p));
1347   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1348   vat_json_object_add_string_copy (&node, "version",
1349                                    vl_api_from_api_string ((vl_api_string_t *)
1350                                                            p));
1351   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1352   vat_json_object_add_string_copy (&node, "build_date",
1353                                    vl_api_from_api_string ((vl_api_string_t *)
1354                                                            p));
1355   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1356   vat_json_object_add_string_copy (&node, "build_directory",
1357                                    vl_api_from_api_string ((vl_api_string_t *)
1358                                                            p));
1359
1360   vat_json_print (vam->ofp, &node);
1361   vat_json_free (&node);
1362
1363   vam->retval = ntohl (mp->retval);
1364   vam->result_ready = 1;
1365 }
1366
1367 static void vl_api_show_threads_reply_t_handler
1368   (vl_api_show_threads_reply_t * mp)
1369 {
1370   vat_main_t *vam = &vat_main;
1371   i32 retval = ntohl (mp->retval);
1372   int i, count = 0;
1373
1374   if (retval >= 0)
1375     count = ntohl (mp->count);
1376
1377   for (i = 0; i < count; i++)
1378     print (vam->ofp,
1379            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1380            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1381            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1382            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1383            ntohl (mp->thread_data[i].cpu_socket));
1384
1385   vam->retval = retval;
1386   vam->result_ready = 1;
1387 }
1388
1389 static void vl_api_show_threads_reply_t_handler_json
1390   (vl_api_show_threads_reply_t * mp)
1391 {
1392   vat_main_t *vam = &vat_main;
1393   vat_json_node_t node;
1394   vl_api_thread_data_t *td;
1395   i32 retval = ntohl (mp->retval);
1396   int i, count = 0;
1397
1398   if (retval >= 0)
1399     count = ntohl (mp->count);
1400
1401   vat_json_init_object (&node);
1402   vat_json_object_add_int (&node, "retval", retval);
1403   vat_json_object_add_uint (&node, "count", count);
1404
1405   for (i = 0; i < count; i++)
1406     {
1407       td = &mp->thread_data[i];
1408       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1409       vat_json_object_add_string_copy (&node, "name", td->name);
1410       vat_json_object_add_string_copy (&node, "type", td->type);
1411       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1412       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1413       vat_json_object_add_int (&node, "core", ntohl (td->id));
1414       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1415     }
1416
1417   vat_json_print (vam->ofp, &node);
1418   vat_json_free (&node);
1419
1420   vam->retval = retval;
1421   vam->result_ready = 1;
1422 }
1423
1424 static int
1425 api_show_threads (vat_main_t * vam)
1426 {
1427   vl_api_show_threads_t *mp;
1428   int ret;
1429
1430   print (vam->ofp,
1431          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1432          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1433
1434   M (SHOW_THREADS, mp);
1435
1436   S (mp);
1437   W (ret);
1438   return ret;
1439 }
1440
1441 static void
1442 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1443 {
1444   u32 sw_if_index = ntohl (mp->sw_if_index);
1445   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1446           mp->mac_ip ? "mac/ip binding" : "address resolution",
1447           ntohl (mp->pid), format_ip4_address, mp->ip,
1448           format_vl_api_mac_address, &mp->mac, sw_if_index);
1449 }
1450
1451 static void
1452 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1453 {
1454   /* JSON output not supported */
1455 }
1456
1457 static void
1458 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1459 {
1460   u32 sw_if_index = ntohl (mp->sw_if_index);
1461   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1462           mp->mac_ip ? "mac/ip binding" : "address resolution",
1463           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1464           format_vl_api_mac_address, mp->mac, sw_if_index);
1465 }
1466
1467 static void
1468 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1469 {
1470   /* JSON output not supported */
1471 }
1472
1473 static void
1474 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1475 {
1476   u32 n_macs = ntohl (mp->n_macs);
1477   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1478           ntohl (mp->pid), mp->client_index, n_macs);
1479   int i;
1480   for (i = 0; i < n_macs; i++)
1481     {
1482       vl_api_mac_entry_t *mac = &mp->mac[i];
1483       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1484               i + 1, ntohl (mac->sw_if_index),
1485               format_ethernet_address, mac->mac_addr, mac->action);
1486       if (i == 1000)
1487         break;
1488     }
1489 }
1490
1491 static void
1492 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1493 {
1494   /* JSON output not supported */
1495 }
1496
1497 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1498 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1499
1500 /*
1501  * Special-case: build the bridge domain table, maintain
1502  * the next bd id vbl.
1503  */
1504 static void vl_api_bridge_domain_details_t_handler
1505   (vl_api_bridge_domain_details_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1509   int i;
1510
1511   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1512          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1513
1514   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1515          ntohl (mp->bd_id), mp->learn, mp->forward,
1516          mp->flood, ntohl (mp->bvi_sw_if_index),
1517          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1518
1519   if (n_sw_ifs)
1520     {
1521       vl_api_bridge_domain_sw_if_t *sw_ifs;
1522       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1523              "Interface Name");
1524
1525       sw_ifs = mp->sw_if_details;
1526       for (i = 0; i < n_sw_ifs; i++)
1527         {
1528           u8 *sw_if_name = 0;
1529           u32 sw_if_index;
1530           hash_pair_t *p;
1531
1532           sw_if_index = ntohl (sw_ifs->sw_if_index);
1533
1534           /* *INDENT-OFF* */
1535           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1536                              ({
1537                                if ((u32) p->value[0] == sw_if_index)
1538                                  {
1539                                    sw_if_name = (u8 *)(p->key);
1540                                    break;
1541                                  }
1542                              }));
1543           /* *INDENT-ON* */
1544           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1545                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1546                  "sw_if_index not found!");
1547
1548           sw_ifs++;
1549         }
1550     }
1551 }
1552
1553 static void vl_api_bridge_domain_details_t_handler_json
1554   (vl_api_bridge_domain_details_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   vat_json_node_t *node, *array = NULL;
1558   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1559
1560   if (VAT_JSON_ARRAY != vam->json_tree.type)
1561     {
1562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1563       vat_json_init_array (&vam->json_tree);
1564     }
1565   node = vat_json_array_add (&vam->json_tree);
1566
1567   vat_json_init_object (node);
1568   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1569   vat_json_object_add_uint (node, "flood", mp->flood);
1570   vat_json_object_add_uint (node, "forward", mp->forward);
1571   vat_json_object_add_uint (node, "learn", mp->learn);
1572   vat_json_object_add_uint (node, "bvi_sw_if_index",
1573                             ntohl (mp->bvi_sw_if_index));
1574   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1575   array = vat_json_object_add (node, "sw_if");
1576   vat_json_init_array (array);
1577
1578
1579
1580   if (n_sw_ifs)
1581     {
1582       vl_api_bridge_domain_sw_if_t *sw_ifs;
1583       int i;
1584
1585       sw_ifs = mp->sw_if_details;
1586       for (i = 0; i < n_sw_ifs; i++)
1587         {
1588           node = vat_json_array_add (array);
1589           vat_json_init_object (node);
1590           vat_json_object_add_uint (node, "sw_if_index",
1591                                     ntohl (sw_ifs->sw_if_index));
1592           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1593           sw_ifs++;
1594         }
1595     }
1596 }
1597
1598 static void vl_api_control_ping_reply_t_handler
1599   (vl_api_control_ping_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   i32 retval = ntohl (mp->retval);
1603   if (vam->async_mode)
1604     {
1605       vam->async_errors += (retval < 0);
1606     }
1607   else
1608     {
1609       vam->retval = retval;
1610       vam->result_ready = 1;
1611     }
1612   if (vam->socket_client_main)
1613     vam->socket_client_main->control_pings_outstanding--;
1614 }
1615
1616 static void vl_api_control_ping_reply_t_handler_json
1617   (vl_api_control_ping_reply_t * mp)
1618 {
1619   vat_main_t *vam = &vat_main;
1620   i32 retval = ntohl (mp->retval);
1621
1622   if (VAT_JSON_NONE != vam->json_tree.type)
1623     {
1624       vat_json_print (vam->ofp, &vam->json_tree);
1625       vat_json_free (&vam->json_tree);
1626       vam->json_tree.type = VAT_JSON_NONE;
1627     }
1628   else
1629     {
1630       /* just print [] */
1631       vat_json_init_array (&vam->json_tree);
1632       vat_json_print (vam->ofp, &vam->json_tree);
1633       vam->json_tree.type = VAT_JSON_NONE;
1634     }
1635
1636   vam->retval = retval;
1637   vam->result_ready = 1;
1638 }
1639
1640 static void
1641   vl_api_bridge_domain_set_mac_age_reply_t_handler
1642   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   i32 retval = ntohl (mp->retval);
1646   if (vam->async_mode)
1647     {
1648       vam->async_errors += (retval < 0);
1649     }
1650   else
1651     {
1652       vam->retval = retval;
1653       vam->result_ready = 1;
1654     }
1655 }
1656
1657 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1658   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   vat_json_node_t node;
1662
1663   vat_json_init_object (&node);
1664   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1665
1666   vat_json_print (vam->ofp, &node);
1667   vat_json_free (&node);
1668
1669   vam->retval = ntohl (mp->retval);
1670   vam->result_ready = 1;
1671 }
1672
1673 static void
1674 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1675 {
1676   vat_main_t *vam = &vat_main;
1677   i32 retval = ntohl (mp->retval);
1678   if (vam->async_mode)
1679     {
1680       vam->async_errors += (retval < 0);
1681     }
1682   else
1683     {
1684       vam->retval = retval;
1685       vam->result_ready = 1;
1686     }
1687 }
1688
1689 static void vl_api_l2_flags_reply_t_handler_json
1690   (vl_api_l2_flags_reply_t * mp)
1691 {
1692   vat_main_t *vam = &vat_main;
1693   vat_json_node_t node;
1694
1695   vat_json_init_object (&node);
1696   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1697   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1698                             ntohl (mp->resulting_feature_bitmap));
1699
1700   vat_json_print (vam->ofp, &node);
1701   vat_json_free (&node);
1702
1703   vam->retval = ntohl (mp->retval);
1704   vam->result_ready = 1;
1705 }
1706
1707 static void vl_api_bridge_flags_reply_t_handler
1708   (vl_api_bridge_flags_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   i32 retval = ntohl (mp->retval);
1712   if (vam->async_mode)
1713     {
1714       vam->async_errors += (retval < 0);
1715     }
1716   else
1717     {
1718       vam->retval = retval;
1719       vam->result_ready = 1;
1720     }
1721 }
1722
1723 static void vl_api_bridge_flags_reply_t_handler_json
1724   (vl_api_bridge_flags_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   vat_json_node_t node;
1728
1729   vat_json_init_object (&node);
1730   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1731   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1732                             ntohl (mp->resulting_feature_bitmap));
1733
1734   vat_json_print (vam->ofp, &node);
1735   vat_json_free (&node);
1736
1737   vam->retval = ntohl (mp->retval);
1738   vam->result_ready = 1;
1739 }
1740
1741 static void
1742 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   i32 retval = ntohl (mp->retval);
1746   if (vam->async_mode)
1747     {
1748       vam->async_errors += (retval < 0);
1749     }
1750   else
1751     {
1752       vam->retval = retval;
1753       vam->sw_if_index = ntohl (mp->sw_if_index);
1754       vam->result_ready = 1;
1755     }
1756
1757 }
1758
1759 static void vl_api_tap_create_v2_reply_t_handler_json
1760   (vl_api_tap_create_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   vat_json_node_t node;
1764
1765   vat_json_init_object (&node);
1766   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1767   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1768
1769   vat_json_print (vam->ofp, &node);
1770   vat_json_free (&node);
1771
1772   vam->retval = ntohl (mp->retval);
1773   vam->result_ready = 1;
1774
1775 }
1776
1777 static void
1778 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1779 {
1780   vat_main_t *vam = &vat_main;
1781   i32 retval = ntohl (mp->retval);
1782   if (vam->async_mode)
1783     {
1784       vam->async_errors += (retval < 0);
1785     }
1786   else
1787     {
1788       vam->retval = retval;
1789       vam->result_ready = 1;
1790     }
1791 }
1792
1793 static void vl_api_tap_delete_v2_reply_t_handler_json
1794   (vl_api_tap_delete_v2_reply_t * mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   vat_json_node_t node;
1798
1799   vat_json_init_object (&node);
1800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1801
1802   vat_json_print (vam->ofp, &node);
1803   vat_json_free (&node);
1804
1805   vam->retval = ntohl (mp->retval);
1806   vam->result_ready = 1;
1807 }
1808
1809 static void
1810 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1811                                           mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   i32 retval = ntohl (mp->retval);
1815   if (vam->async_mode)
1816     {
1817       vam->async_errors += (retval < 0);
1818     }
1819   else
1820     {
1821       vam->retval = retval;
1822       vam->sw_if_index = ntohl (mp->sw_if_index);
1823       vam->result_ready = 1;
1824     }
1825 }
1826
1827 static void vl_api_virtio_pci_create_reply_t_handler_json
1828   (vl_api_virtio_pci_create_reply_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   vat_json_node_t node;
1832
1833   vat_json_init_object (&node);
1834   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1835   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1836
1837   vat_json_print (vam->ofp, &node);
1838   vat_json_free (&node);
1839
1840   vam->retval = ntohl (mp->retval);
1841   vam->result_ready = 1;
1842
1843 }
1844
1845 static void
1846 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1847                                           mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851   if (vam->async_mode)
1852     {
1853       vam->async_errors += (retval < 0);
1854     }
1855   else
1856     {
1857       vam->retval = retval;
1858       vam->result_ready = 1;
1859     }
1860 }
1861
1862 static void vl_api_virtio_pci_delete_reply_t_handler_json
1863   (vl_api_virtio_pci_delete_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   vat_json_node_t node;
1867
1868   vat_json_init_object (&node);
1869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1870
1871   vat_json_print (vam->ofp, &node);
1872   vat_json_free (&node);
1873
1874   vam->retval = ntohl (mp->retval);
1875   vam->result_ready = 1;
1876 }
1877
1878 static void
1879 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1880 {
1881   vat_main_t *vam = &vat_main;
1882   i32 retval = ntohl (mp->retval);
1883
1884   if (vam->async_mode)
1885     {
1886       vam->async_errors += (retval < 0);
1887     }
1888   else
1889     {
1890       vam->retval = retval;
1891       vam->sw_if_index = ntohl (mp->sw_if_index);
1892       vam->result_ready = 1;
1893     }
1894 }
1895
1896 static void vl_api_bond_create_reply_t_handler_json
1897   (vl_api_bond_create_reply_t * mp)
1898 {
1899   vat_main_t *vam = &vat_main;
1900   vat_json_node_t node;
1901
1902   vat_json_init_object (&node);
1903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1904   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1905
1906   vat_json_print (vam->ofp, &node);
1907   vat_json_free (&node);
1908
1909   vam->retval = ntohl (mp->retval);
1910   vam->result_ready = 1;
1911 }
1912
1913 static void
1914 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1915 {
1916   vat_main_t *vam = &vat_main;
1917   i32 retval = ntohl (mp->retval);
1918
1919   if (vam->async_mode)
1920     {
1921       vam->async_errors += (retval < 0);
1922     }
1923   else
1924     {
1925       vam->retval = retval;
1926       vam->result_ready = 1;
1927     }
1928 }
1929
1930 static void vl_api_bond_delete_reply_t_handler_json
1931   (vl_api_bond_delete_reply_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   vat_json_node_t node;
1935
1936   vat_json_init_object (&node);
1937   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1938
1939   vat_json_print (vam->ofp, &node);
1940   vat_json_free (&node);
1941
1942   vam->retval = ntohl (mp->retval);
1943   vam->result_ready = 1;
1944 }
1945
1946 static void
1947 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   i32 retval = ntohl (mp->retval);
1951
1952   if (vam->async_mode)
1953     {
1954       vam->async_errors += (retval < 0);
1955     }
1956   else
1957     {
1958       vam->retval = retval;
1959       vam->result_ready = 1;
1960     }
1961 }
1962
1963 static void vl_api_bond_enslave_reply_t_handler_json
1964   (vl_api_bond_enslave_reply_t * mp)
1965 {
1966   vat_main_t *vam = &vat_main;
1967   vat_json_node_t node;
1968
1969   vat_json_init_object (&node);
1970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1971
1972   vat_json_print (vam->ofp, &node);
1973   vat_json_free (&node);
1974
1975   vam->retval = ntohl (mp->retval);
1976   vam->result_ready = 1;
1977 }
1978
1979 static void
1980 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1981                                           mp)
1982 {
1983   vat_main_t *vam = &vat_main;
1984   i32 retval = ntohl (mp->retval);
1985
1986   if (vam->async_mode)
1987     {
1988       vam->async_errors += (retval < 0);
1989     }
1990   else
1991     {
1992       vam->retval = retval;
1993       vam->result_ready = 1;
1994     }
1995 }
1996
1997 static void vl_api_bond_detach_slave_reply_t_handler_json
1998   (vl_api_bond_detach_slave_reply_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001   vat_json_node_t node;
2002
2003   vat_json_init_object (&node);
2004   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2005
2006   vat_json_print (vam->ofp, &node);
2007   vat_json_free (&node);
2008
2009   vam->retval = ntohl (mp->retval);
2010   vam->result_ready = 1;
2011 }
2012
2013 static void vl_api_sw_interface_bond_details_t_handler
2014   (vl_api_sw_interface_bond_details_t * mp)
2015 {
2016   vat_main_t *vam = &vat_main;
2017
2018   print (vam->ofp,
2019          "%-16s %-12d %-12U %-13U %-14u %-14u",
2020          mp->interface_name, ntohl (mp->sw_if_index),
2021          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2022          ntohl (mp->active_slaves), ntohl (mp->slaves));
2023 }
2024
2025 static void vl_api_sw_interface_bond_details_t_handler_json
2026   (vl_api_sw_interface_bond_details_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   vat_json_node_t *node = NULL;
2030
2031   if (VAT_JSON_ARRAY != vam->json_tree.type)
2032     {
2033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2034       vat_json_init_array (&vam->json_tree);
2035     }
2036   node = vat_json_array_add (&vam->json_tree);
2037
2038   vat_json_init_object (node);
2039   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2040   vat_json_object_add_string_copy (node, "interface_name",
2041                                    mp->interface_name);
2042   vat_json_object_add_uint (node, "mode", mp->mode);
2043   vat_json_object_add_uint (node, "load_balance", mp->lb);
2044   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2045   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2046 }
2047
2048 static int
2049 api_sw_interface_bond_dump (vat_main_t * vam)
2050 {
2051   vl_api_sw_interface_bond_dump_t *mp;
2052   vl_api_control_ping_t *mp_ping;
2053   int ret;
2054
2055   print (vam->ofp,
2056          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2057          "interface name", "sw_if_index", "mode", "load balance",
2058          "active slaves", "slaves");
2059
2060   /* Get list of bond interfaces */
2061   M (SW_INTERFACE_BOND_DUMP, mp);
2062   S (mp);
2063
2064   /* Use a control ping for synchronization */
2065   MPING (CONTROL_PING, mp_ping);
2066   S (mp_ping);
2067
2068   W (ret);
2069   return ret;
2070 }
2071
2072 static void vl_api_sw_interface_slave_details_t_handler
2073   (vl_api_sw_interface_slave_details_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076
2077   print (vam->ofp,
2078          "%-25s %-12d %-12d %d", mp->interface_name,
2079          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2080 }
2081
2082 static void vl_api_sw_interface_slave_details_t_handler_json
2083   (vl_api_sw_interface_slave_details_t * mp)
2084 {
2085   vat_main_t *vam = &vat_main;
2086   vat_json_node_t *node = NULL;
2087
2088   if (VAT_JSON_ARRAY != vam->json_tree.type)
2089     {
2090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2091       vat_json_init_array (&vam->json_tree);
2092     }
2093   node = vat_json_array_add (&vam->json_tree);
2094
2095   vat_json_init_object (node);
2096   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2097   vat_json_object_add_string_copy (node, "interface_name",
2098                                    mp->interface_name);
2099   vat_json_object_add_uint (node, "passive", mp->is_passive);
2100   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2101 }
2102
2103 static int
2104 api_sw_interface_slave_dump (vat_main_t * vam)
2105 {
2106   unformat_input_t *i = vam->input;
2107   vl_api_sw_interface_slave_dump_t *mp;
2108   vl_api_control_ping_t *mp_ping;
2109   u32 sw_if_index = ~0;
2110   u8 sw_if_index_set = 0;
2111   int ret;
2112
2113   /* Parse args required to build the message */
2114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2115     {
2116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2117         sw_if_index_set = 1;
2118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2119         sw_if_index_set = 1;
2120       else
2121         break;
2122     }
2123
2124   if (sw_if_index_set == 0)
2125     {
2126       errmsg ("missing vpp interface name. ");
2127       return -99;
2128     }
2129
2130   print (vam->ofp,
2131          "\n%-25s %-12s %-12s %s",
2132          "slave interface name", "sw_if_index", "passive", "long_timeout");
2133
2134   /* Get list of bond interfaces */
2135   M (SW_INTERFACE_SLAVE_DUMP, mp);
2136   mp->sw_if_index = ntohl (sw_if_index);
2137   S (mp);
2138
2139   /* Use a control ping for synchronization */
2140   MPING (CONTROL_PING, mp_ping);
2141   S (mp_ping);
2142
2143   W (ret);
2144   return ret;
2145 }
2146
2147 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2148   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2149 {
2150   vat_main_t *vam = &vat_main;
2151   i32 retval = ntohl (mp->retval);
2152   if (vam->async_mode)
2153     {
2154       vam->async_errors += (retval < 0);
2155     }
2156   else
2157     {
2158       vam->retval = retval;
2159       vam->sw_if_index = ntohl (mp->sw_if_index);
2160       vam->result_ready = 1;
2161     }
2162   vam->regenerate_interface_table = 1;
2163 }
2164
2165 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2166   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   vat_json_node_t node;
2170
2171   vat_json_init_object (&node);
2172   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2173   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2174                             ntohl (mp->sw_if_index));
2175
2176   vat_json_print (vam->ofp, &node);
2177   vat_json_free (&node);
2178
2179   vam->retval = ntohl (mp->retval);
2180   vam->result_ready = 1;
2181 }
2182
2183 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2184   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2185 {
2186   vat_main_t *vam = &vat_main;
2187   i32 retval = ntohl (mp->retval);
2188   if (vam->async_mode)
2189     {
2190       vam->async_errors += (retval < 0);
2191     }
2192   else
2193     {
2194       vam->retval = retval;
2195       vam->sw_if_index = ntohl (mp->sw_if_index);
2196       vam->result_ready = 1;
2197     }
2198 }
2199
2200 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2201   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2202 {
2203   vat_main_t *vam = &vat_main;
2204   vat_json_node_t node;
2205
2206   vat_json_init_object (&node);
2207   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2208   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2209
2210   vat_json_print (vam->ofp, &node);
2211   vat_json_free (&node);
2212
2213   vam->retval = ntohl (mp->retval);
2214   vam->result_ready = 1;
2215 }
2216
2217 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2218   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2219 {
2220   vat_main_t *vam = &vat_main;
2221   i32 retval = ntohl (mp->retval);
2222   if (vam->async_mode)
2223     {
2224       vam->async_errors += (retval < 0);
2225     }
2226   else
2227     {
2228       vam->retval = retval;
2229       vam->result_ready = 1;
2230     }
2231 }
2232
2233 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2234   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2235 {
2236   vat_main_t *vam = &vat_main;
2237   vat_json_node_t node;
2238
2239   vat_json_init_object (&node);
2240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2241   vat_json_object_add_uint (&node, "fwd_entry_index",
2242                             clib_net_to_host_u32 (mp->fwd_entry_index));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 u8 *
2252 format_lisp_transport_protocol (u8 * s, va_list * args)
2253 {
2254   u32 proto = va_arg (*args, u32);
2255
2256   switch (proto)
2257     {
2258     case 1:
2259       return format (s, "udp");
2260     case 2:
2261       return format (s, "api");
2262     default:
2263       return 0;
2264     }
2265   return 0;
2266 }
2267
2268 static void vl_api_one_get_transport_protocol_reply_t_handler
2269   (vl_api_one_get_transport_protocol_reply_t * mp)
2270 {
2271   vat_main_t *vam = &vat_main;
2272   i32 retval = ntohl (mp->retval);
2273   if (vam->async_mode)
2274     {
2275       vam->async_errors += (retval < 0);
2276     }
2277   else
2278     {
2279       u32 proto = mp->protocol;
2280       print (vam->ofp, "Transport protocol: %U",
2281              format_lisp_transport_protocol, proto);
2282       vam->retval = retval;
2283       vam->result_ready = 1;
2284     }
2285 }
2286
2287 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2288   (vl_api_one_get_transport_protocol_reply_t * mp)
2289 {
2290   vat_main_t *vam = &vat_main;
2291   vat_json_node_t node;
2292   u8 *s;
2293
2294   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2295   vec_add1 (s, 0);
2296
2297   vat_json_init_object (&node);
2298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2299   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2300
2301   vec_free (s);
2302   vat_json_print (vam->ofp, &node);
2303   vat_json_free (&node);
2304
2305   vam->retval = ntohl (mp->retval);
2306   vam->result_ready = 1;
2307 }
2308
2309 static void vl_api_one_add_del_locator_set_reply_t_handler
2310   (vl_api_one_add_del_locator_set_reply_t * mp)
2311 {
2312   vat_main_t *vam = &vat_main;
2313   i32 retval = ntohl (mp->retval);
2314   if (vam->async_mode)
2315     {
2316       vam->async_errors += (retval < 0);
2317     }
2318   else
2319     {
2320       vam->retval = retval;
2321       vam->result_ready = 1;
2322     }
2323 }
2324
2325 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2326   (vl_api_one_add_del_locator_set_reply_t * mp)
2327 {
2328   vat_main_t *vam = &vat_main;
2329   vat_json_node_t node;
2330
2331   vat_json_init_object (&node);
2332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2333   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2334
2335   vat_json_print (vam->ofp, &node);
2336   vat_json_free (&node);
2337
2338   vam->retval = ntohl (mp->retval);
2339   vam->result_ready = 1;
2340 }
2341
2342 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2343   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2344 {
2345   vat_main_t *vam = &vat_main;
2346   i32 retval = ntohl (mp->retval);
2347   if (vam->async_mode)
2348     {
2349       vam->async_errors += (retval < 0);
2350     }
2351   else
2352     {
2353       vam->retval = retval;
2354       vam->sw_if_index = ntohl (mp->sw_if_index);
2355       vam->result_ready = 1;
2356     }
2357   vam->regenerate_interface_table = 1;
2358 }
2359
2360 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2361   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2362 {
2363   vat_main_t *vam = &vat_main;
2364   vat_json_node_t node;
2365
2366   vat_json_init_object (&node);
2367   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2368   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2369
2370   vat_json_print (vam->ofp, &node);
2371   vat_json_free (&node);
2372
2373   vam->retval = ntohl (mp->retval);
2374   vam->result_ready = 1;
2375 }
2376
2377 static void vl_api_vxlan_offload_rx_reply_t_handler
2378   (vl_api_vxlan_offload_rx_reply_t * mp)
2379 {
2380   vat_main_t *vam = &vat_main;
2381   i32 retval = ntohl (mp->retval);
2382   if (vam->async_mode)
2383     {
2384       vam->async_errors += (retval < 0);
2385     }
2386   else
2387     {
2388       vam->retval = retval;
2389       vam->result_ready = 1;
2390     }
2391 }
2392
2393 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2394   (vl_api_vxlan_offload_rx_reply_t * mp)
2395 {
2396   vat_main_t *vam = &vat_main;
2397   vat_json_node_t node;
2398
2399   vat_json_init_object (&node);
2400   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2401
2402   vat_json_print (vam->ofp, &node);
2403   vat_json_free (&node);
2404
2405   vam->retval = ntohl (mp->retval);
2406   vam->result_ready = 1;
2407 }
2408
2409 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2410   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2411 {
2412   vat_main_t *vam = &vat_main;
2413   i32 retval = ntohl (mp->retval);
2414   if (vam->async_mode)
2415     {
2416       vam->async_errors += (retval < 0);
2417     }
2418   else
2419     {
2420       vam->retval = retval;
2421       vam->sw_if_index = ntohl (mp->sw_if_index);
2422       vam->result_ready = 1;
2423     }
2424 }
2425
2426 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2427   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   vat_json_node_t node;
2431
2432   vat_json_init_object (&node);
2433   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2434   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2435
2436   vat_json_print (vam->ofp, &node);
2437   vat_json_free (&node);
2438
2439   vam->retval = ntohl (mp->retval);
2440   vam->result_ready = 1;
2441 }
2442
2443 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2444   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447   i32 retval = ntohl (mp->retval);
2448   if (vam->async_mode)
2449     {
2450       vam->async_errors += (retval < 0);
2451     }
2452   else
2453     {
2454       vam->retval = retval;
2455       vam->sw_if_index = ntohl (mp->sw_if_index);
2456       vam->result_ready = 1;
2457     }
2458   vam->regenerate_interface_table = 1;
2459 }
2460
2461 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2462   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2463 {
2464   vat_main_t *vam = &vat_main;
2465   vat_json_node_t node;
2466
2467   vat_json_init_object (&node);
2468   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2469   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2470
2471   vat_json_print (vam->ofp, &node);
2472   vat_json_free (&node);
2473
2474   vam->retval = ntohl (mp->retval);
2475   vam->result_ready = 1;
2476 }
2477
2478 static void vl_api_gre_add_del_tunnel_reply_t_handler
2479   (vl_api_gre_add_del_tunnel_reply_t * mp)
2480 {
2481   vat_main_t *vam = &vat_main;
2482   i32 retval = ntohl (mp->retval);
2483   if (vam->async_mode)
2484     {
2485       vam->async_errors += (retval < 0);
2486     }
2487   else
2488     {
2489       vam->retval = retval;
2490       vam->sw_if_index = ntohl (mp->sw_if_index);
2491       vam->result_ready = 1;
2492     }
2493 }
2494
2495 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2496   (vl_api_gre_add_del_tunnel_reply_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t node;
2500
2501   vat_json_init_object (&node);
2502   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2503   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2504
2505   vat_json_print (vam->ofp, &node);
2506   vat_json_free (&node);
2507
2508   vam->retval = ntohl (mp->retval);
2509   vam->result_ready = 1;
2510 }
2511
2512 static void vl_api_create_vhost_user_if_reply_t_handler
2513   (vl_api_create_vhost_user_if_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   i32 retval = ntohl (mp->retval);
2517   if (vam->async_mode)
2518     {
2519       vam->async_errors += (retval < 0);
2520     }
2521   else
2522     {
2523       vam->retval = retval;
2524       vam->sw_if_index = ntohl (mp->sw_if_index);
2525       vam->result_ready = 1;
2526     }
2527   vam->regenerate_interface_table = 1;
2528 }
2529
2530 static void vl_api_create_vhost_user_if_reply_t_handler_json
2531   (vl_api_create_vhost_user_if_reply_t * mp)
2532 {
2533   vat_main_t *vam = &vat_main;
2534   vat_json_node_t node;
2535
2536   vat_json_init_object (&node);
2537   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2538   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2539
2540   vat_json_print (vam->ofp, &node);
2541   vat_json_free (&node);
2542
2543   vam->retval = ntohl (mp->retval);
2544   vam->result_ready = 1;
2545 }
2546
2547 static void vl_api_dns_resolve_name_reply_t_handler
2548   (vl_api_dns_resolve_name_reply_t * mp)
2549 {
2550   vat_main_t *vam = &vat_main;
2551   i32 retval = ntohl (mp->retval);
2552   if (vam->async_mode)
2553     {
2554       vam->async_errors += (retval < 0);
2555     }
2556   else
2557     {
2558       vam->retval = retval;
2559       vam->result_ready = 1;
2560
2561       if (retval == 0)
2562         {
2563           if (mp->ip4_set)
2564             clib_warning ("ip4 address %U", format_ip4_address,
2565                           (ip4_address_t *) mp->ip4_address);
2566           if (mp->ip6_set)
2567             clib_warning ("ip6 address %U", format_ip6_address,
2568                           (ip6_address_t *) mp->ip6_address);
2569         }
2570       else
2571         clib_warning ("retval %d", retval);
2572     }
2573 }
2574
2575 static void vl_api_dns_resolve_name_reply_t_handler_json
2576   (vl_api_dns_resolve_name_reply_t * mp)
2577 {
2578   clib_warning ("not implemented");
2579 }
2580
2581 static void vl_api_dns_resolve_ip_reply_t_handler
2582   (vl_api_dns_resolve_ip_reply_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   i32 retval = ntohl (mp->retval);
2586   if (vam->async_mode)
2587     {
2588       vam->async_errors += (retval < 0);
2589     }
2590   else
2591     {
2592       vam->retval = retval;
2593       vam->result_ready = 1;
2594
2595       if (retval == 0)
2596         {
2597           clib_warning ("canonical name %s", mp->name);
2598         }
2599       else
2600         clib_warning ("retval %d", retval);
2601     }
2602 }
2603
2604 static void vl_api_dns_resolve_ip_reply_t_handler_json
2605   (vl_api_dns_resolve_ip_reply_t * mp)
2606 {
2607   clib_warning ("not implemented");
2608 }
2609
2610
2611 static void vl_api_ip_address_details_t_handler
2612   (vl_api_ip_address_details_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   static ip_address_details_t empty_ip_address_details = { {0} };
2616   ip_address_details_t *address = NULL;
2617   ip_details_t *current_ip_details = NULL;
2618   ip_details_t *details = NULL;
2619
2620   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2621
2622   if (!details || vam->current_sw_if_index >= vec_len (details)
2623       || !details[vam->current_sw_if_index].present)
2624     {
2625       errmsg ("ip address details arrived but not stored");
2626       errmsg ("ip_dump should be called first");
2627       return;
2628     }
2629
2630   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2631
2632 #define addresses (current_ip_details->addr)
2633
2634   vec_validate_init_empty (addresses, vec_len (addresses),
2635                            empty_ip_address_details);
2636
2637   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2638
2639   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2640   address->prefix_length = mp->prefix_length;
2641 #undef addresses
2642 }
2643
2644 static void vl_api_ip_address_details_t_handler_json
2645   (vl_api_ip_address_details_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vat_json_node_t *node = NULL;
2649   struct in6_addr ip6;
2650   struct in_addr ip4;
2651
2652   if (VAT_JSON_ARRAY != vam->json_tree.type)
2653     {
2654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2655       vat_json_init_array (&vam->json_tree);
2656     }
2657   node = vat_json_array_add (&vam->json_tree);
2658
2659   vat_json_init_object (node);
2660   if (vam->is_ipv6)
2661     {
2662       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2663       vat_json_object_add_ip6 (node, "ip", ip6);
2664     }
2665   else
2666     {
2667       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2668       vat_json_object_add_ip4 (node, "ip", ip4);
2669     }
2670   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2671 }
2672
2673 static void
2674 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   static ip_details_t empty_ip_details = { 0 };
2678   ip_details_t *ip = NULL;
2679   u32 sw_if_index = ~0;
2680
2681   sw_if_index = ntohl (mp->sw_if_index);
2682
2683   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2684                            sw_if_index, empty_ip_details);
2685
2686   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2687                          sw_if_index);
2688
2689   ip->present = 1;
2690 }
2691
2692 static void
2693 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2694 {
2695   vat_main_t *vam = &vat_main;
2696
2697   if (VAT_JSON_ARRAY != vam->json_tree.type)
2698     {
2699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2700       vat_json_init_array (&vam->json_tree);
2701     }
2702   vat_json_array_add_uint (&vam->json_tree,
2703                            clib_net_to_host_u32 (mp->sw_if_index));
2704 }
2705
2706 static void
2707 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2708 {
2709   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2710           "router_addr %U host_mac %U",
2711           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2712           mp->lease.hostname,
2713           format_ip4_address, &mp->lease.host_address,
2714           format_ip4_address, &mp->lease.router_address,
2715           format_ethernet_address, mp->lease.host_mac);
2716 }
2717
2718 static void vl_api_dhcp_compl_event_t_handler_json
2719   (vl_api_dhcp_compl_event_t * mp)
2720 {
2721   /* JSON output not supported */
2722 }
2723
2724 static void vl_api_get_first_msg_id_reply_t_handler
2725   (vl_api_get_first_msg_id_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   i32 retval = ntohl (mp->retval);
2729
2730   if (vam->async_mode)
2731     {
2732       vam->async_errors += (retval < 0);
2733     }
2734   else
2735     {
2736       vam->retval = retval;
2737       vam->result_ready = 1;
2738     }
2739   if (retval >= 0)
2740     {
2741       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2742     }
2743 }
2744
2745 static void vl_api_get_first_msg_id_reply_t_handler_json
2746   (vl_api_get_first_msg_id_reply_t * mp)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   vat_json_node_t node;
2750
2751   vat_json_init_object (&node);
2752   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2753   vat_json_object_add_uint (&node, "first_msg_id",
2754                             (uint) ntohs (mp->first_msg_id));
2755
2756   vat_json_print (vam->ofp, &node);
2757   vat_json_free (&node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static void vl_api_get_node_graph_reply_t_handler
2764   (vl_api_get_node_graph_reply_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   api_main_t *am = &api_main;
2768   i32 retval = ntohl (mp->retval);
2769   u8 *pvt_copy, *reply;
2770   void *oldheap;
2771   vlib_node_t *node;
2772   int i;
2773
2774   if (vam->async_mode)
2775     {
2776       vam->async_errors += (retval < 0);
2777     }
2778   else
2779     {
2780       vam->retval = retval;
2781       vam->result_ready = 1;
2782     }
2783
2784   /* "Should never happen..." */
2785   if (retval != 0)
2786     return;
2787
2788   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2789   pvt_copy = vec_dup (reply);
2790
2791   /* Toss the shared-memory original... */
2792   pthread_mutex_lock (&am->vlib_rp->mutex);
2793   oldheap = svm_push_data_heap (am->vlib_rp);
2794
2795   vec_free (reply);
2796
2797   svm_pop_heap (oldheap);
2798   pthread_mutex_unlock (&am->vlib_rp->mutex);
2799
2800   if (vam->graph_nodes)
2801     {
2802       hash_free (vam->graph_node_index_by_name);
2803
2804       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2805         {
2806           node = vam->graph_nodes[0][i];
2807           vec_free (node->name);
2808           vec_free (node->next_nodes);
2809           vec_free (node);
2810         }
2811       vec_free (vam->graph_nodes[0]);
2812       vec_free (vam->graph_nodes);
2813     }
2814
2815   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2816   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2817   vec_free (pvt_copy);
2818
2819   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2820     {
2821       node = vam->graph_nodes[0][i];
2822       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2823     }
2824 }
2825
2826 static void vl_api_get_node_graph_reply_t_handler_json
2827   (vl_api_get_node_graph_reply_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   api_main_t *am = &api_main;
2831   void *oldheap;
2832   vat_json_node_t node;
2833   u8 *reply;
2834
2835   /* $$$$ make this real? */
2836   vat_json_init_object (&node);
2837   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2838   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2839
2840   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2841
2842   /* Toss the shared-memory original... */
2843   pthread_mutex_lock (&am->vlib_rp->mutex);
2844   oldheap = svm_push_data_heap (am->vlib_rp);
2845
2846   vec_free (reply);
2847
2848   svm_pop_heap (oldheap);
2849   pthread_mutex_unlock (&am->vlib_rp->mutex);
2850
2851   vat_json_print (vam->ofp, &node);
2852   vat_json_free (&node);
2853
2854   vam->retval = ntohl (mp->retval);
2855   vam->result_ready = 1;
2856 }
2857
2858 static void
2859 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2860 {
2861   vat_main_t *vam = &vat_main;
2862   u8 *s = 0;
2863
2864   if (mp->local)
2865     {
2866       s = format (s, "%=16d%=16d%=16d",
2867                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2868     }
2869   else
2870     {
2871       s = format (s, "%=16U%=16d%=16d",
2872                   mp->is_ipv6 ? format_ip6_address :
2873                   format_ip4_address,
2874                   mp->ip_address, mp->priority, mp->weight);
2875     }
2876
2877   print (vam->ofp, "%v", s);
2878   vec_free (s);
2879 }
2880
2881 static void
2882 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2883 {
2884   vat_main_t *vam = &vat_main;
2885   vat_json_node_t *node = NULL;
2886   struct in6_addr ip6;
2887   struct in_addr ip4;
2888
2889   if (VAT_JSON_ARRAY != vam->json_tree.type)
2890     {
2891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2892       vat_json_init_array (&vam->json_tree);
2893     }
2894   node = vat_json_array_add (&vam->json_tree);
2895   vat_json_init_object (node);
2896
2897   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2898   vat_json_object_add_uint (node, "priority", mp->priority);
2899   vat_json_object_add_uint (node, "weight", mp->weight);
2900
2901   if (mp->local)
2902     vat_json_object_add_uint (node, "sw_if_index",
2903                               clib_net_to_host_u32 (mp->sw_if_index));
2904   else
2905     {
2906       if (mp->is_ipv6)
2907         {
2908           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2909           vat_json_object_add_ip6 (node, "address", ip6);
2910         }
2911       else
2912         {
2913           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2914           vat_json_object_add_ip4 (node, "address", ip4);
2915         }
2916     }
2917 }
2918
2919 static void
2920 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2921                                           mp)
2922 {
2923   vat_main_t *vam = &vat_main;
2924   u8 *ls_name = 0;
2925
2926   ls_name = format (0, "%s", mp->ls_name);
2927
2928   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2929          ls_name);
2930   vec_free (ls_name);
2931 }
2932
2933 static void
2934   vl_api_one_locator_set_details_t_handler_json
2935   (vl_api_one_locator_set_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t *node = 0;
2939   u8 *ls_name = 0;
2940
2941   ls_name = format (0, "%s", mp->ls_name);
2942   vec_add1 (ls_name, 0);
2943
2944   if (VAT_JSON_ARRAY != vam->json_tree.type)
2945     {
2946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2947       vat_json_init_array (&vam->json_tree);
2948     }
2949   node = vat_json_array_add (&vam->json_tree);
2950
2951   vat_json_init_object (node);
2952   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2953   vat_json_object_add_uint (node, "ls_index",
2954                             clib_net_to_host_u32 (mp->ls_index));
2955   vec_free (ls_name);
2956 }
2957
2958 typedef struct
2959 {
2960   u32 spi;
2961   u8 si;
2962 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2963
2964 uword
2965 unformat_nsh_address (unformat_input_t * input, va_list * args)
2966 {
2967   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2968   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2969 }
2970
2971 u8 *
2972 format_nsh_address_vat (u8 * s, va_list * args)
2973 {
2974   nsh_t *a = va_arg (*args, nsh_t *);
2975   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2976 }
2977
2978 static u8 *
2979 format_lisp_flat_eid (u8 * s, va_list * args)
2980 {
2981   u32 type = va_arg (*args, u32);
2982   u8 *eid = va_arg (*args, u8 *);
2983   u32 eid_len = va_arg (*args, u32);
2984
2985   switch (type)
2986     {
2987     case 0:
2988       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2989     case 1:
2990       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2991     case 2:
2992       return format (s, "%U", format_ethernet_address, eid);
2993     case 3:
2994       return format (s, "%U", format_nsh_address_vat, eid);
2995     }
2996   return 0;
2997 }
2998
2999 static u8 *
3000 format_lisp_eid_vat (u8 * s, va_list * args)
3001 {
3002   u32 type = va_arg (*args, u32);
3003   u8 *eid = va_arg (*args, u8 *);
3004   u32 eid_len = va_arg (*args, u32);
3005   u8 *seid = va_arg (*args, u8 *);
3006   u32 seid_len = va_arg (*args, u32);
3007   u32 is_src_dst = va_arg (*args, u32);
3008
3009   if (is_src_dst)
3010     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3011
3012   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3013
3014   return s;
3015 }
3016
3017 static void
3018 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   u8 *s = 0, *eid = 0;
3022
3023   if (~0 == mp->locator_set_index)
3024     s = format (0, "action: %d", mp->action);
3025   else
3026     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3027
3028   eid = format (0, "%U", format_lisp_eid_vat,
3029                 mp->eid_type,
3030                 mp->eid,
3031                 mp->eid_prefix_len,
3032                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3033   vec_add1 (eid, 0);
3034
3035   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3036          clib_net_to_host_u32 (mp->vni),
3037          eid,
3038          mp->is_local ? "local" : "remote",
3039          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3040          clib_net_to_host_u16 (mp->key_id), mp->key);
3041
3042   vec_free (s);
3043   vec_free (eid);
3044 }
3045
3046 static void
3047 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3048                                              * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   vat_json_node_t *node = 0;
3052   u8 *eid = 0;
3053
3054   if (VAT_JSON_ARRAY != vam->json_tree.type)
3055     {
3056       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3057       vat_json_init_array (&vam->json_tree);
3058     }
3059   node = vat_json_array_add (&vam->json_tree);
3060
3061   vat_json_init_object (node);
3062   if (~0 == mp->locator_set_index)
3063     vat_json_object_add_uint (node, "action", mp->action);
3064   else
3065     vat_json_object_add_uint (node, "locator_set_index",
3066                               clib_net_to_host_u32 (mp->locator_set_index));
3067
3068   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3069   if (mp->eid_type == 3)
3070     {
3071       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3072       vat_json_init_object (nsh_json);
3073       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3074       vat_json_object_add_uint (nsh_json, "spi",
3075                                 clib_net_to_host_u32 (nsh->spi));
3076       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3077     }
3078   else
3079     {
3080       eid = format (0, "%U", format_lisp_eid_vat,
3081                     mp->eid_type,
3082                     mp->eid,
3083                     mp->eid_prefix_len,
3084                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3085       vec_add1 (eid, 0);
3086       vat_json_object_add_string_copy (node, "eid", eid);
3087       vec_free (eid);
3088     }
3089   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3090   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3091   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3092
3093   if (mp->key_id)
3094     {
3095       vat_json_object_add_uint (node, "key_id",
3096                                 clib_net_to_host_u16 (mp->key_id));
3097       vat_json_object_add_string_copy (node, "key", mp->key);
3098     }
3099 }
3100
3101 static void
3102 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   u8 *seid = 0, *deid = 0;
3106   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3107
3108   deid = format (0, "%U", format_lisp_eid_vat,
3109                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3110
3111   seid = format (0, "%U", format_lisp_eid_vat,
3112                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3113
3114   vec_add1 (deid, 0);
3115   vec_add1 (seid, 0);
3116
3117   if (mp->is_ip4)
3118     format_ip_address_fcn = format_ip4_address;
3119   else
3120     format_ip_address_fcn = format_ip6_address;
3121
3122
3123   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3124          clib_net_to_host_u32 (mp->vni),
3125          seid, deid,
3126          format_ip_address_fcn, mp->lloc,
3127          format_ip_address_fcn, mp->rloc,
3128          clib_net_to_host_u32 (mp->pkt_count),
3129          clib_net_to_host_u32 (mp->bytes));
3130
3131   vec_free (deid);
3132   vec_free (seid);
3133 }
3134
3135 static void
3136 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3137 {
3138   struct in6_addr ip6;
3139   struct in_addr ip4;
3140   vat_main_t *vam = &vat_main;
3141   vat_json_node_t *node = 0;
3142   u8 *deid = 0, *seid = 0;
3143
3144   if (VAT_JSON_ARRAY != vam->json_tree.type)
3145     {
3146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3147       vat_json_init_array (&vam->json_tree);
3148     }
3149   node = vat_json_array_add (&vam->json_tree);
3150
3151   vat_json_init_object (node);
3152   deid = format (0, "%U", format_lisp_eid_vat,
3153                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3154
3155   seid = format (0, "%U", format_lisp_eid_vat,
3156                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3157
3158   vec_add1 (deid, 0);
3159   vec_add1 (seid, 0);
3160
3161   vat_json_object_add_string_copy (node, "seid", seid);
3162   vat_json_object_add_string_copy (node, "deid", deid);
3163   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3164
3165   if (mp->is_ip4)
3166     {
3167       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3168       vat_json_object_add_ip4 (node, "lloc", ip4);
3169       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3170       vat_json_object_add_ip4 (node, "rloc", ip4);
3171     }
3172   else
3173     {
3174       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3175       vat_json_object_add_ip6 (node, "lloc", ip6);
3176       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3177       vat_json_object_add_ip6 (node, "rloc", ip6);
3178     }
3179   vat_json_object_add_uint (node, "pkt_count",
3180                             clib_net_to_host_u32 (mp->pkt_count));
3181   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3182
3183   vec_free (deid);
3184   vec_free (seid);
3185 }
3186
3187 static void
3188   vl_api_one_eid_table_map_details_t_handler
3189   (vl_api_one_eid_table_map_details_t * mp)
3190 {
3191   vat_main_t *vam = &vat_main;
3192
3193   u8 *line = format (0, "%=10d%=10d",
3194                      clib_net_to_host_u32 (mp->vni),
3195                      clib_net_to_host_u32 (mp->dp_table));
3196   print (vam->ofp, "%v", line);
3197   vec_free (line);
3198 }
3199
3200 static void
3201   vl_api_one_eid_table_map_details_t_handler_json
3202   (vl_api_one_eid_table_map_details_t * mp)
3203 {
3204   vat_main_t *vam = &vat_main;
3205   vat_json_node_t *node = NULL;
3206
3207   if (VAT_JSON_ARRAY != vam->json_tree.type)
3208     {
3209       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3210       vat_json_init_array (&vam->json_tree);
3211     }
3212   node = vat_json_array_add (&vam->json_tree);
3213   vat_json_init_object (node);
3214   vat_json_object_add_uint (node, "dp_table",
3215                             clib_net_to_host_u32 (mp->dp_table));
3216   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3217 }
3218
3219 static void
3220   vl_api_one_eid_table_vni_details_t_handler
3221   (vl_api_one_eid_table_vni_details_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224
3225   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3226   print (vam->ofp, "%v", line);
3227   vec_free (line);
3228 }
3229
3230 static void
3231   vl_api_one_eid_table_vni_details_t_handler_json
3232   (vl_api_one_eid_table_vni_details_t * mp)
3233 {
3234   vat_main_t *vam = &vat_main;
3235   vat_json_node_t *node = NULL;
3236
3237   if (VAT_JSON_ARRAY != vam->json_tree.type)
3238     {
3239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3240       vat_json_init_array (&vam->json_tree);
3241     }
3242   node = vat_json_array_add (&vam->json_tree);
3243   vat_json_init_object (node);
3244   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3245 }
3246
3247 static void
3248   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3249   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   int retval = clib_net_to_host_u32 (mp->retval);
3253
3254   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3255   print (vam->ofp, "fallback threshold value: %d", mp->value);
3256
3257   vam->retval = retval;
3258   vam->result_ready = 1;
3259 }
3260
3261 static void
3262   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3263   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3264 {
3265   vat_main_t *vam = &vat_main;
3266   vat_json_node_t _node, *node = &_node;
3267   int retval = clib_net_to_host_u32 (mp->retval);
3268
3269   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3270   vat_json_init_object (node);
3271   vat_json_object_add_uint (node, "value", mp->value);
3272
3273   vat_json_print (vam->ofp, node);
3274   vat_json_free (node);
3275
3276   vam->retval = retval;
3277   vam->result_ready = 1;
3278 }
3279
3280 static void
3281   vl_api_show_one_map_register_state_reply_t_handler
3282   (vl_api_show_one_map_register_state_reply_t * mp)
3283 {
3284   vat_main_t *vam = &vat_main;
3285   int retval = clib_net_to_host_u32 (mp->retval);
3286
3287   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3288
3289   vam->retval = retval;
3290   vam->result_ready = 1;
3291 }
3292
3293 static void
3294   vl_api_show_one_map_register_state_reply_t_handler_json
3295   (vl_api_show_one_map_register_state_reply_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   vat_json_node_t _node, *node = &_node;
3299   int retval = clib_net_to_host_u32 (mp->retval);
3300
3301   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3302
3303   vat_json_init_object (node);
3304   vat_json_object_add_string_copy (node, "state", s);
3305
3306   vat_json_print (vam->ofp, node);
3307   vat_json_free (node);
3308
3309   vam->retval = retval;
3310   vam->result_ready = 1;
3311   vec_free (s);
3312 }
3313
3314 static void
3315   vl_api_show_one_rloc_probe_state_reply_t_handler
3316   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3317 {
3318   vat_main_t *vam = &vat_main;
3319   int retval = clib_net_to_host_u32 (mp->retval);
3320
3321   if (retval)
3322     goto end;
3323
3324   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3325 end:
3326   vam->retval = retval;
3327   vam->result_ready = 1;
3328 }
3329
3330 static void
3331   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3332   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3333 {
3334   vat_main_t *vam = &vat_main;
3335   vat_json_node_t _node, *node = &_node;
3336   int retval = clib_net_to_host_u32 (mp->retval);
3337
3338   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3339   vat_json_init_object (node);
3340   vat_json_object_add_string_copy (node, "state", s);
3341
3342   vat_json_print (vam->ofp, node);
3343   vat_json_free (node);
3344
3345   vam->retval = retval;
3346   vam->result_ready = 1;
3347   vec_free (s);
3348 }
3349
3350 static void
3351   vl_api_show_one_stats_enable_disable_reply_t_handler
3352   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3353 {
3354   vat_main_t *vam = &vat_main;
3355   int retval = clib_net_to_host_u32 (mp->retval);
3356
3357   if (retval)
3358     goto end;
3359
3360   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3361 end:
3362   vam->retval = retval;
3363   vam->result_ready = 1;
3364 }
3365
3366 static void
3367   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3368   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3369 {
3370   vat_main_t *vam = &vat_main;
3371   vat_json_node_t _node, *node = &_node;
3372   int retval = clib_net_to_host_u32 (mp->retval);
3373
3374   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3375   vat_json_init_object (node);
3376   vat_json_object_add_string_copy (node, "state", s);
3377
3378   vat_json_print (vam->ofp, node);
3379   vat_json_free (node);
3380
3381   vam->retval = retval;
3382   vam->result_ready = 1;
3383   vec_free (s);
3384 }
3385
3386 static void
3387 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3388 {
3389   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3390   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3391   e->vni = clib_net_to_host_u32 (e->vni);
3392 }
3393
3394 static void
3395   gpe_fwd_entries_get_reply_t_net_to_host
3396   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3397 {
3398   u32 i;
3399
3400   mp->count = clib_net_to_host_u32 (mp->count);
3401   for (i = 0; i < mp->count; i++)
3402     {
3403       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3404     }
3405 }
3406
3407 static u8 *
3408 format_gpe_encap_mode (u8 * s, va_list * args)
3409 {
3410   u32 mode = va_arg (*args, u32);
3411
3412   switch (mode)
3413     {
3414     case 0:
3415       return format (s, "lisp");
3416     case 1:
3417       return format (s, "vxlan");
3418     }
3419   return 0;
3420 }
3421
3422 static void
3423   vl_api_gpe_get_encap_mode_reply_t_handler
3424   (vl_api_gpe_get_encap_mode_reply_t * mp)
3425 {
3426   vat_main_t *vam = &vat_main;
3427
3428   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3429   vam->retval = ntohl (mp->retval);
3430   vam->result_ready = 1;
3431 }
3432
3433 static void
3434   vl_api_gpe_get_encap_mode_reply_t_handler_json
3435   (vl_api_gpe_get_encap_mode_reply_t * mp)
3436 {
3437   vat_main_t *vam = &vat_main;
3438   vat_json_node_t node;
3439
3440   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3441   vec_add1 (encap_mode, 0);
3442
3443   vat_json_init_object (&node);
3444   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3445
3446   vec_free (encap_mode);
3447   vat_json_print (vam->ofp, &node);
3448   vat_json_free (&node);
3449
3450   vam->retval = ntohl (mp->retval);
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_gpe_fwd_entry_path_details_t_handler
3456   (vl_api_gpe_fwd_entry_path_details_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3460
3461   if (mp->lcl_loc.is_ip4)
3462     format_ip_address_fcn = format_ip4_address;
3463   else
3464     format_ip_address_fcn = format_ip6_address;
3465
3466   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3467          format_ip_address_fcn, &mp->lcl_loc,
3468          format_ip_address_fcn, &mp->rmt_loc);
3469 }
3470
3471 static void
3472 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3473 {
3474   struct in6_addr ip6;
3475   struct in_addr ip4;
3476
3477   if (loc->is_ip4)
3478     {
3479       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3480       vat_json_object_add_ip4 (n, "address", ip4);
3481     }
3482   else
3483     {
3484       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3485       vat_json_object_add_ip6 (n, "address", ip6);
3486     }
3487   vat_json_object_add_uint (n, "weight", loc->weight);
3488 }
3489
3490 static void
3491   vl_api_gpe_fwd_entry_path_details_t_handler_json
3492   (vl_api_gpe_fwd_entry_path_details_t * mp)
3493 {
3494   vat_main_t *vam = &vat_main;
3495   vat_json_node_t *node = NULL;
3496   vat_json_node_t *loc_node;
3497
3498   if (VAT_JSON_ARRAY != vam->json_tree.type)
3499     {
3500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3501       vat_json_init_array (&vam->json_tree);
3502     }
3503   node = vat_json_array_add (&vam->json_tree);
3504   vat_json_init_object (node);
3505
3506   loc_node = vat_json_object_add (node, "local_locator");
3507   vat_json_init_object (loc_node);
3508   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3509
3510   loc_node = vat_json_object_add (node, "remote_locator");
3511   vat_json_init_object (loc_node);
3512   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3513 }
3514
3515 static void
3516   vl_api_gpe_fwd_entries_get_reply_t_handler
3517   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3518 {
3519   vat_main_t *vam = &vat_main;
3520   u32 i;
3521   int retval = clib_net_to_host_u32 (mp->retval);
3522   vl_api_gpe_fwd_entry_t *e;
3523
3524   if (retval)
3525     goto end;
3526
3527   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3528
3529   for (i = 0; i < mp->count; i++)
3530     {
3531       e = &mp->entries[i];
3532       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3533              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3534              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3535     }
3536
3537 end:
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540 }
3541
3542 static void
3543   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3544   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3545 {
3546   u8 *s = 0;
3547   vat_main_t *vam = &vat_main;
3548   vat_json_node_t *e = 0, root;
3549   u32 i;
3550   int retval = clib_net_to_host_u32 (mp->retval);
3551   vl_api_gpe_fwd_entry_t *fwd;
3552
3553   if (retval)
3554     goto end;
3555
3556   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3557   vat_json_init_array (&root);
3558
3559   for (i = 0; i < mp->count; i++)
3560     {
3561       e = vat_json_array_add (&root);
3562       fwd = &mp->entries[i];
3563
3564       vat_json_init_object (e);
3565       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3566       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3567       vat_json_object_add_int (e, "vni", fwd->vni);
3568       vat_json_object_add_int (e, "action", fwd->action);
3569
3570       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3571                   fwd->leid_prefix_len);
3572       vec_add1 (s, 0);
3573       vat_json_object_add_string_copy (e, "leid", s);
3574       vec_free (s);
3575
3576       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3577                   fwd->reid_prefix_len);
3578       vec_add1 (s, 0);
3579       vat_json_object_add_string_copy (e, "reid", s);
3580       vec_free (s);
3581     }
3582
3583   vat_json_print (vam->ofp, &root);
3584   vat_json_free (&root);
3585
3586 end:
3587   vam->retval = retval;
3588   vam->result_ready = 1;
3589 }
3590
3591 static void
3592   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3593   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   u32 i, n;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_native_fwd_rpath_t *r;
3599
3600   if (retval)
3601     goto end;
3602
3603   n = clib_net_to_host_u32 (mp->count);
3604
3605   for (i = 0; i < n; i++)
3606     {
3607       r = &mp->entries[i];
3608       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3609              clib_net_to_host_u32 (r->fib_index),
3610              clib_net_to_host_u32 (r->nh_sw_if_index),
3611              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3612     }
3613
3614 end:
3615   vam->retval = retval;
3616   vam->result_ready = 1;
3617 }
3618
3619 static void
3620   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3621   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t root, *e;
3625   u32 i, n;
3626   int retval = clib_net_to_host_u32 (mp->retval);
3627   vl_api_gpe_native_fwd_rpath_t *r;
3628   u8 *s;
3629
3630   if (retval)
3631     goto end;
3632
3633   n = clib_net_to_host_u32 (mp->count);
3634   vat_json_init_array (&root);
3635
3636   for (i = 0; i < n; i++)
3637     {
3638       e = vat_json_array_add (&root);
3639       vat_json_init_object (e);
3640       r = &mp->entries[i];
3641       s =
3642         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3643                 r->nh_addr);
3644       vec_add1 (s, 0);
3645       vat_json_object_add_string_copy (e, "ip4", s);
3646       vec_free (s);
3647
3648       vat_json_object_add_uint (e, "fib_index",
3649                                 clib_net_to_host_u32 (r->fib_index));
3650       vat_json_object_add_uint (e, "nh_sw_if_index",
3651                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3652     }
3653
3654   vat_json_print (vam->ofp, &root);
3655   vat_json_free (&root);
3656
3657 end:
3658   vam->retval = retval;
3659   vam->result_ready = 1;
3660 }
3661
3662 static void
3663   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3664   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3665 {
3666   vat_main_t *vam = &vat_main;
3667   u32 i, n;
3668   int retval = clib_net_to_host_u32 (mp->retval);
3669
3670   if (retval)
3671     goto end;
3672
3673   n = clib_net_to_host_u32 (mp->count);
3674
3675   for (i = 0; i < n; i++)
3676     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3677
3678 end:
3679   vam->retval = retval;
3680   vam->result_ready = 1;
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3685   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t root;
3689   u32 i, n;
3690   int retval = clib_net_to_host_u32 (mp->retval);
3691
3692   if (retval)
3693     goto end;
3694
3695   n = clib_net_to_host_u32 (mp->count);
3696   vat_json_init_array (&root);
3697
3698   for (i = 0; i < n; i++)
3699     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3700
3701   vat_json_print (vam->ofp, &root);
3702   vat_json_free (&root);
3703
3704 end:
3705   vam->retval = retval;
3706   vam->result_ready = 1;
3707 }
3708
3709 static void
3710   vl_api_one_ndp_entries_get_reply_t_handler
3711   (vl_api_one_ndp_entries_get_reply_t * mp)
3712 {
3713   vat_main_t *vam = &vat_main;
3714   u32 i, n;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716
3717   if (retval)
3718     goto end;
3719
3720   n = clib_net_to_host_u32 (mp->count);
3721
3722   for (i = 0; i < n; i++)
3723     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3724            format_ethernet_address, mp->entries[i].mac);
3725
3726 end:
3727   vam->retval = retval;
3728   vam->result_ready = 1;
3729 }
3730
3731 static void
3732   vl_api_one_ndp_entries_get_reply_t_handler_json
3733   (vl_api_one_ndp_entries_get_reply_t * mp)
3734 {
3735   u8 *s = 0;
3736   vat_main_t *vam = &vat_main;
3737   vat_json_node_t *e = 0, root;
3738   u32 i, n;
3739   int retval = clib_net_to_host_u32 (mp->retval);
3740   vl_api_one_ndp_entry_t *arp_entry;
3741
3742   if (retval)
3743     goto end;
3744
3745   n = clib_net_to_host_u32 (mp->count);
3746   vat_json_init_array (&root);
3747
3748   for (i = 0; i < n; i++)
3749     {
3750       e = vat_json_array_add (&root);
3751       arp_entry = &mp->entries[i];
3752
3753       vat_json_init_object (e);
3754       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3755       vec_add1 (s, 0);
3756
3757       vat_json_object_add_string_copy (e, "mac", s);
3758       vec_free (s);
3759
3760       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3761       vec_add1 (s, 0);
3762       vat_json_object_add_string_copy (e, "ip6", s);
3763       vec_free (s);
3764     }
3765
3766   vat_json_print (vam->ofp, &root);
3767   vat_json_free (&root);
3768
3769 end:
3770   vam->retval = retval;
3771   vam->result_ready = 1;
3772 }
3773
3774 static void
3775   vl_api_one_l2_arp_entries_get_reply_t_handler
3776   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3777 {
3778   vat_main_t *vam = &vat_main;
3779   u32 i, n;
3780   int retval = clib_net_to_host_u32 (mp->retval);
3781
3782   if (retval)
3783     goto end;
3784
3785   n = clib_net_to_host_u32 (mp->count);
3786
3787   for (i = 0; i < n; i++)
3788     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3789            format_ethernet_address, mp->entries[i].mac);
3790
3791 end:
3792   vam->retval = retval;
3793   vam->result_ready = 1;
3794 }
3795
3796 static void
3797   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3798   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3799 {
3800   u8 *s = 0;
3801   vat_main_t *vam = &vat_main;
3802   vat_json_node_t *e = 0, root;
3803   u32 i, n;
3804   int retval = clib_net_to_host_u32 (mp->retval);
3805   vl_api_one_l2_arp_entry_t *arp_entry;
3806
3807   if (retval)
3808     goto end;
3809
3810   n = clib_net_to_host_u32 (mp->count);
3811   vat_json_init_array (&root);
3812
3813   for (i = 0; i < n; i++)
3814     {
3815       e = vat_json_array_add (&root);
3816       arp_entry = &mp->entries[i];
3817
3818       vat_json_init_object (e);
3819       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3820       vec_add1 (s, 0);
3821
3822       vat_json_object_add_string_copy (e, "mac", s);
3823       vec_free (s);
3824
3825       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3826       vec_add1 (s, 0);
3827       vat_json_object_add_string_copy (e, "ip4", s);
3828       vec_free (s);
3829     }
3830
3831   vat_json_print (vam->ofp, &root);
3832   vat_json_free (&root);
3833
3834 end:
3835   vam->retval = retval;
3836   vam->result_ready = 1;
3837 }
3838
3839 static void
3840 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3841 {
3842   vat_main_t *vam = &vat_main;
3843   u32 i, n;
3844   int retval = clib_net_to_host_u32 (mp->retval);
3845
3846   if (retval)
3847     goto end;
3848
3849   n = clib_net_to_host_u32 (mp->count);
3850
3851   for (i = 0; i < n; i++)
3852     {
3853       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3854     }
3855
3856 end:
3857   vam->retval = retval;
3858   vam->result_ready = 1;
3859 }
3860
3861 static void
3862   vl_api_one_ndp_bd_get_reply_t_handler_json
3863   (vl_api_one_ndp_bd_get_reply_t * mp)
3864 {
3865   vat_main_t *vam = &vat_main;
3866   vat_json_node_t root;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874   vat_json_init_array (&root);
3875
3876   for (i = 0; i < n; i++)
3877     {
3878       vat_json_array_add_uint (&root,
3879                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3880     }
3881
3882   vat_json_print (vam->ofp, &root);
3883   vat_json_free (&root);
3884
3885 end:
3886   vam->retval = retval;
3887   vam->result_ready = 1;
3888 }
3889
3890 static void
3891   vl_api_one_l2_arp_bd_get_reply_t_handler
3892   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3893 {
3894   vat_main_t *vam = &vat_main;
3895   u32 i, n;
3896   int retval = clib_net_to_host_u32 (mp->retval);
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902
3903   for (i = 0; i < n; i++)
3904     {
3905       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3906     }
3907
3908 end:
3909   vam->retval = retval;
3910   vam->result_ready = 1;
3911 }
3912
3913 static void
3914   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3915   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3916 {
3917   vat_main_t *vam = &vat_main;
3918   vat_json_node_t root;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926   vat_json_init_array (&root);
3927
3928   for (i = 0; i < n; i++)
3929     {
3930       vat_json_array_add_uint (&root,
3931                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3932     }
3933
3934   vat_json_print (vam->ofp, &root);
3935   vat_json_free (&root);
3936
3937 end:
3938   vam->retval = retval;
3939   vam->result_ready = 1;
3940 }
3941
3942 static void
3943   vl_api_one_adjacencies_get_reply_t_handler
3944   (vl_api_one_adjacencies_get_reply_t * mp)
3945 {
3946   vat_main_t *vam = &vat_main;
3947   u32 i, n;
3948   int retval = clib_net_to_host_u32 (mp->retval);
3949   vl_api_one_adjacency_t *a;
3950
3951   if (retval)
3952     goto end;
3953
3954   n = clib_net_to_host_u32 (mp->count);
3955
3956   for (i = 0; i < n; i++)
3957     {
3958       a = &mp->adjacencies[i];
3959       print (vam->ofp, "%U %40U",
3960              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3961              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3962     }
3963
3964 end:
3965   vam->retval = retval;
3966   vam->result_ready = 1;
3967 }
3968
3969 static void
3970   vl_api_one_adjacencies_get_reply_t_handler_json
3971   (vl_api_one_adjacencies_get_reply_t * mp)
3972 {
3973   u8 *s = 0;
3974   vat_main_t *vam = &vat_main;
3975   vat_json_node_t *e = 0, root;
3976   u32 i, n;
3977   int retval = clib_net_to_host_u32 (mp->retval);
3978   vl_api_one_adjacency_t *a;
3979
3980   if (retval)
3981     goto end;
3982
3983   n = clib_net_to_host_u32 (mp->count);
3984   vat_json_init_array (&root);
3985
3986   for (i = 0; i < n; i++)
3987     {
3988       e = vat_json_array_add (&root);
3989       a = &mp->adjacencies[i];
3990
3991       vat_json_init_object (e);
3992       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3993                   a->leid_prefix_len);
3994       vec_add1 (s, 0);
3995       vat_json_object_add_string_copy (e, "leid", s);
3996       vec_free (s);
3997
3998       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3999                   a->reid_prefix_len);
4000       vec_add1 (s, 0);
4001       vat_json_object_add_string_copy (e, "reid", s);
4002       vec_free (s);
4003     }
4004
4005   vat_json_print (vam->ofp, &root);
4006   vat_json_free (&root);
4007
4008 end:
4009   vam->retval = retval;
4010   vam->result_ready = 1;
4011 }
4012
4013 static void
4014 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4015 {
4016   vat_main_t *vam = &vat_main;
4017
4018   print (vam->ofp, "%=20U",
4019          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4020          mp->ip_address);
4021 }
4022
4023 static void
4024   vl_api_one_map_server_details_t_handler_json
4025   (vl_api_one_map_server_details_t * mp)
4026 {
4027   vat_main_t *vam = &vat_main;
4028   vat_json_node_t *node = NULL;
4029   struct in6_addr ip6;
4030   struct in_addr ip4;
4031
4032   if (VAT_JSON_ARRAY != vam->json_tree.type)
4033     {
4034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4035       vat_json_init_array (&vam->json_tree);
4036     }
4037   node = vat_json_array_add (&vam->json_tree);
4038
4039   vat_json_init_object (node);
4040   if (mp->is_ipv6)
4041     {
4042       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4043       vat_json_object_add_ip6 (node, "map-server", ip6);
4044     }
4045   else
4046     {
4047       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4048       vat_json_object_add_ip4 (node, "map-server", ip4);
4049     }
4050 }
4051
4052 static void
4053 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4054                                            * mp)
4055 {
4056   vat_main_t *vam = &vat_main;
4057
4058   print (vam->ofp, "%=20U",
4059          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4060          mp->ip_address);
4061 }
4062
4063 static void
4064   vl_api_one_map_resolver_details_t_handler_json
4065   (vl_api_one_map_resolver_details_t * mp)
4066 {
4067   vat_main_t *vam = &vat_main;
4068   vat_json_node_t *node = NULL;
4069   struct in6_addr ip6;
4070   struct in_addr ip4;
4071
4072   if (VAT_JSON_ARRAY != vam->json_tree.type)
4073     {
4074       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4075       vat_json_init_array (&vam->json_tree);
4076     }
4077   node = vat_json_array_add (&vam->json_tree);
4078
4079   vat_json_init_object (node);
4080   if (mp->is_ipv6)
4081     {
4082       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4083       vat_json_object_add_ip6 (node, "map resolver", ip6);
4084     }
4085   else
4086     {
4087       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4088       vat_json_object_add_ip4 (node, "map resolver", ip4);
4089     }
4090 }
4091
4092 static void
4093 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4094 {
4095   vat_main_t *vam = &vat_main;
4096   i32 retval = ntohl (mp->retval);
4097
4098   if (0 <= retval)
4099     {
4100       print (vam->ofp, "feature: %s\ngpe: %s",
4101              mp->feature_status ? "enabled" : "disabled",
4102              mp->gpe_status ? "enabled" : "disabled");
4103     }
4104
4105   vam->retval = retval;
4106   vam->result_ready = 1;
4107 }
4108
4109 static void
4110   vl_api_show_one_status_reply_t_handler_json
4111   (vl_api_show_one_status_reply_t * mp)
4112 {
4113   vat_main_t *vam = &vat_main;
4114   vat_json_node_t node;
4115   u8 *gpe_status = NULL;
4116   u8 *feature_status = NULL;
4117
4118   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4119   feature_status = format (0, "%s",
4120                            mp->feature_status ? "enabled" : "disabled");
4121   vec_add1 (gpe_status, 0);
4122   vec_add1 (feature_status, 0);
4123
4124   vat_json_init_object (&node);
4125   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4126   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4127
4128   vec_free (gpe_status);
4129   vec_free (feature_status);
4130
4131   vat_json_print (vam->ofp, &node);
4132   vat_json_free (&node);
4133
4134   vam->retval = ntohl (mp->retval);
4135   vam->result_ready = 1;
4136 }
4137
4138 static void
4139   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4140   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4141 {
4142   vat_main_t *vam = &vat_main;
4143   i32 retval = ntohl (mp->retval);
4144
4145   if (retval >= 0)
4146     {
4147       print (vam->ofp, "%=20s", mp->locator_set_name);
4148     }
4149
4150   vam->retval = retval;
4151   vam->result_ready = 1;
4152 }
4153
4154 static void
4155   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4156   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   vat_json_node_t *node = NULL;
4160
4161   if (VAT_JSON_ARRAY != vam->json_tree.type)
4162     {
4163       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4164       vat_json_init_array (&vam->json_tree);
4165     }
4166   node = vat_json_array_add (&vam->json_tree);
4167
4168   vat_json_init_object (node);
4169   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4170
4171   vat_json_print (vam->ofp, node);
4172   vat_json_free (node);
4173
4174   vam->retval = ntohl (mp->retval);
4175   vam->result_ready = 1;
4176 }
4177
4178 static u8 *
4179 format_lisp_map_request_mode (u8 * s, va_list * args)
4180 {
4181   u32 mode = va_arg (*args, u32);
4182
4183   switch (mode)
4184     {
4185     case 0:
4186       return format (0, "dst-only");
4187     case 1:
4188       return format (0, "src-dst");
4189     }
4190   return 0;
4191 }
4192
4193 static void
4194   vl_api_show_one_map_request_mode_reply_t_handler
4195   (vl_api_show_one_map_request_mode_reply_t * mp)
4196 {
4197   vat_main_t *vam = &vat_main;
4198   i32 retval = ntohl (mp->retval);
4199
4200   if (0 <= retval)
4201     {
4202       u32 mode = mp->mode;
4203       print (vam->ofp, "map_request_mode: %U",
4204              format_lisp_map_request_mode, mode);
4205     }
4206
4207   vam->retval = retval;
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_show_one_map_request_mode_reply_t_handler_json
4213   (vl_api_show_one_map_request_mode_reply_t * mp)
4214 {
4215   vat_main_t *vam = &vat_main;
4216   vat_json_node_t node;
4217   u8 *s = 0;
4218   u32 mode;
4219
4220   mode = mp->mode;
4221   s = format (0, "%U", format_lisp_map_request_mode, mode);
4222   vec_add1 (s, 0);
4223
4224   vat_json_init_object (&node);
4225   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4226   vat_json_print (vam->ofp, &node);
4227   vat_json_free (&node);
4228
4229   vec_free (s);
4230   vam->retval = ntohl (mp->retval);
4231   vam->result_ready = 1;
4232 }
4233
4234 static void
4235   vl_api_one_show_xtr_mode_reply_t_handler
4236   (vl_api_one_show_xtr_mode_reply_t * mp)
4237 {
4238   vat_main_t *vam = &vat_main;
4239   i32 retval = ntohl (mp->retval);
4240
4241   if (0 <= retval)
4242     {
4243       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4244     }
4245
4246   vam->retval = retval;
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_show_xtr_mode_reply_t_handler_json
4252   (vl_api_one_show_xtr_mode_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   vat_json_node_t node;
4256   u8 *status = 0;
4257
4258   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4259   vec_add1 (status, 0);
4260
4261   vat_json_init_object (&node);
4262   vat_json_object_add_string_copy (&node, "status", status);
4263
4264   vec_free (status);
4265
4266   vat_json_print (vam->ofp, &node);
4267   vat_json_free (&node);
4268
4269   vam->retval = ntohl (mp->retval);
4270   vam->result_ready = 1;
4271 }
4272
4273 static void
4274   vl_api_one_show_pitr_mode_reply_t_handler
4275   (vl_api_one_show_pitr_mode_reply_t * mp)
4276 {
4277   vat_main_t *vam = &vat_main;
4278   i32 retval = ntohl (mp->retval);
4279
4280   if (0 <= retval)
4281     {
4282       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4283     }
4284
4285   vam->retval = retval;
4286   vam->result_ready = 1;
4287 }
4288
4289 static void
4290   vl_api_one_show_pitr_mode_reply_t_handler_json
4291   (vl_api_one_show_pitr_mode_reply_t * mp)
4292 {
4293   vat_main_t *vam = &vat_main;
4294   vat_json_node_t node;
4295   u8 *status = 0;
4296
4297   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4298   vec_add1 (status, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "status", status);
4302
4303   vec_free (status);
4304
4305   vat_json_print (vam->ofp, &node);
4306   vat_json_free (&node);
4307
4308   vam->retval = ntohl (mp->retval);
4309   vam->result_ready = 1;
4310 }
4311
4312 static void
4313   vl_api_one_show_petr_mode_reply_t_handler
4314   (vl_api_one_show_petr_mode_reply_t * mp)
4315 {
4316   vat_main_t *vam = &vat_main;
4317   i32 retval = ntohl (mp->retval);
4318
4319   if (0 <= retval)
4320     {
4321       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4322     }
4323
4324   vam->retval = retval;
4325   vam->result_ready = 1;
4326 }
4327
4328 static void
4329   vl_api_one_show_petr_mode_reply_t_handler_json
4330   (vl_api_one_show_petr_mode_reply_t * mp)
4331 {
4332   vat_main_t *vam = &vat_main;
4333   vat_json_node_t node;
4334   u8 *status = 0;
4335
4336   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4337   vec_add1 (status, 0);
4338
4339   vat_json_init_object (&node);
4340   vat_json_object_add_string_copy (&node, "status", status);
4341
4342   vec_free (status);
4343
4344   vat_json_print (vam->ofp, &node);
4345   vat_json_free (&node);
4346
4347   vam->retval = ntohl (mp->retval);
4348   vam->result_ready = 1;
4349 }
4350
4351 static void
4352   vl_api_show_one_use_petr_reply_t_handler
4353   (vl_api_show_one_use_petr_reply_t * mp)
4354 {
4355   vat_main_t *vam = &vat_main;
4356   i32 retval = ntohl (mp->retval);
4357
4358   if (0 <= retval)
4359     {
4360       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4361       if (mp->status)
4362         {
4363           print (vam->ofp, "Proxy-ETR address; %U",
4364                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4365                  mp->address);
4366         }
4367     }
4368
4369   vam->retval = retval;
4370   vam->result_ready = 1;
4371 }
4372
4373 static void
4374   vl_api_show_one_use_petr_reply_t_handler_json
4375   (vl_api_show_one_use_petr_reply_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378   vat_json_node_t node;
4379   u8 *status = 0;
4380   struct in_addr ip4;
4381   struct in6_addr ip6;
4382
4383   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4384   vec_add1 (status, 0);
4385
4386   vat_json_init_object (&node);
4387   vat_json_object_add_string_copy (&node, "status", status);
4388   if (mp->status)
4389     {
4390       if (mp->is_ip4)
4391         {
4392           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4393           vat_json_object_add_ip6 (&node, "address", ip6);
4394         }
4395       else
4396         {
4397           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4398           vat_json_object_add_ip4 (&node, "address", ip4);
4399         }
4400     }
4401
4402   vec_free (status);
4403
4404   vat_json_print (vam->ofp, &node);
4405   vat_json_free (&node);
4406
4407   vam->retval = ntohl (mp->retval);
4408   vam->result_ready = 1;
4409 }
4410
4411 static void
4412   vl_api_show_one_nsh_mapping_reply_t_handler
4413   (vl_api_show_one_nsh_mapping_reply_t * mp)
4414 {
4415   vat_main_t *vam = &vat_main;
4416   i32 retval = ntohl (mp->retval);
4417
4418   if (0 <= retval)
4419     {
4420       print (vam->ofp, "%-20s%-16s",
4421              mp->is_set ? "set" : "not-set",
4422              mp->is_set ? (char *) mp->locator_set_name : "");
4423     }
4424
4425   vam->retval = retval;
4426   vam->result_ready = 1;
4427 }
4428
4429 static void
4430   vl_api_show_one_nsh_mapping_reply_t_handler_json
4431   (vl_api_show_one_nsh_mapping_reply_t * mp)
4432 {
4433   vat_main_t *vam = &vat_main;
4434   vat_json_node_t node;
4435   u8 *status = 0;
4436
4437   status = format (0, "%s", mp->is_set ? "yes" : "no");
4438   vec_add1 (status, 0);
4439
4440   vat_json_init_object (&node);
4441   vat_json_object_add_string_copy (&node, "is_set", status);
4442   if (mp->is_set)
4443     {
4444       vat_json_object_add_string_copy (&node, "locator_set",
4445                                        mp->locator_set_name);
4446     }
4447
4448   vec_free (status);
4449
4450   vat_json_print (vam->ofp, &node);
4451   vat_json_free (&node);
4452
4453   vam->retval = ntohl (mp->retval);
4454   vam->result_ready = 1;
4455 }
4456
4457 static void
4458   vl_api_show_one_map_register_ttl_reply_t_handler
4459   (vl_api_show_one_map_register_ttl_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462   i32 retval = ntohl (mp->retval);
4463
4464   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4465
4466   if (0 <= retval)
4467     {
4468       print (vam->ofp, "ttl: %u", mp->ttl);
4469     }
4470
4471   vam->retval = retval;
4472   vam->result_ready = 1;
4473 }
4474
4475 static void
4476   vl_api_show_one_map_register_ttl_reply_t_handler_json
4477   (vl_api_show_one_map_register_ttl_reply_t * mp)
4478 {
4479   vat_main_t *vam = &vat_main;
4480   vat_json_node_t node;
4481
4482   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4483   vat_json_init_object (&node);
4484   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4485
4486   vat_json_print (vam->ofp, &node);
4487   vat_json_free (&node);
4488
4489   vam->retval = ntohl (mp->retval);
4490   vam->result_ready = 1;
4491 }
4492
4493 static void
4494 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4495 {
4496   vat_main_t *vam = &vat_main;
4497   i32 retval = ntohl (mp->retval);
4498
4499   if (0 <= retval)
4500     {
4501       print (vam->ofp, "%-20s%-16s",
4502              mp->status ? "enabled" : "disabled",
4503              mp->status ? (char *) mp->locator_set_name : "");
4504     }
4505
4506   vam->retval = retval;
4507   vam->result_ready = 1;
4508 }
4509
4510 static void
4511 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4512 {
4513   vat_main_t *vam = &vat_main;
4514   vat_json_node_t node;
4515   u8 *status = 0;
4516
4517   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4518   vec_add1 (status, 0);
4519
4520   vat_json_init_object (&node);
4521   vat_json_object_add_string_copy (&node, "status", status);
4522   if (mp->status)
4523     {
4524       vat_json_object_add_string_copy (&node, "locator_set",
4525                                        mp->locator_set_name);
4526     }
4527
4528   vec_free (status);
4529
4530   vat_json_print (vam->ofp, &node);
4531   vat_json_free (&node);
4532
4533   vam->retval = ntohl (mp->retval);
4534   vam->result_ready = 1;
4535 }
4536
4537 static u8 *
4538 format_policer_type (u8 * s, va_list * va)
4539 {
4540   u32 i = va_arg (*va, u32);
4541
4542   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4543     s = format (s, "1r2c");
4544   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4545     s = format (s, "1r3c");
4546   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4547     s = format (s, "2r3c-2698");
4548   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4549     s = format (s, "2r3c-4115");
4550   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4551     s = format (s, "2r3c-mef5cf1");
4552   else
4553     s = format (s, "ILLEGAL");
4554   return s;
4555 }
4556
4557 static u8 *
4558 format_policer_rate_type (u8 * s, va_list * va)
4559 {
4560   u32 i = va_arg (*va, u32);
4561
4562   if (i == SSE2_QOS_RATE_KBPS)
4563     s = format (s, "kbps");
4564   else if (i == SSE2_QOS_RATE_PPS)
4565     s = format (s, "pps");
4566   else
4567     s = format (s, "ILLEGAL");
4568   return s;
4569 }
4570
4571 static u8 *
4572 format_policer_round_type (u8 * s, va_list * va)
4573 {
4574   u32 i = va_arg (*va, u32);
4575
4576   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4577     s = format (s, "closest");
4578   else if (i == SSE2_QOS_ROUND_TO_UP)
4579     s = format (s, "up");
4580   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4581     s = format (s, "down");
4582   else
4583     s = format (s, "ILLEGAL");
4584   return s;
4585 }
4586
4587 static u8 *
4588 format_policer_action_type (u8 * s, va_list * va)
4589 {
4590   u32 i = va_arg (*va, u32);
4591
4592   if (i == SSE2_QOS_ACTION_DROP)
4593     s = format (s, "drop");
4594   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4595     s = format (s, "transmit");
4596   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4597     s = format (s, "mark-and-transmit");
4598   else
4599     s = format (s, "ILLEGAL");
4600   return s;
4601 }
4602
4603 static u8 *
4604 format_dscp (u8 * s, va_list * va)
4605 {
4606   u32 i = va_arg (*va, u32);
4607   char *t = 0;
4608
4609   switch (i)
4610     {
4611 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4612       foreach_vnet_dscp
4613 #undef _
4614     default:
4615       return format (s, "ILLEGAL");
4616     }
4617   s = format (s, "%s", t);
4618   return s;
4619 }
4620
4621 static void
4622 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4623 {
4624   vat_main_t *vam = &vat_main;
4625   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4626
4627   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4628     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4629   else
4630     conform_dscp_str = format (0, "");
4631
4632   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4633     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4634   else
4635     exceed_dscp_str = format (0, "");
4636
4637   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4638     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4639   else
4640     violate_dscp_str = format (0, "");
4641
4642   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4643          "rate type %U, round type %U, %s rate, %s color-aware, "
4644          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4645          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4646          "conform action %U%s, exceed action %U%s, violate action %U%s",
4647          mp->name,
4648          format_policer_type, mp->type,
4649          ntohl (mp->cir),
4650          ntohl (mp->eir),
4651          clib_net_to_host_u64 (mp->cb),
4652          clib_net_to_host_u64 (mp->eb),
4653          format_policer_rate_type, mp->rate_type,
4654          format_policer_round_type, mp->round_type,
4655          mp->single_rate ? "single" : "dual",
4656          mp->color_aware ? "is" : "not",
4657          ntohl (mp->cir_tokens_per_period),
4658          ntohl (mp->pir_tokens_per_period),
4659          ntohl (mp->scale),
4660          ntohl (mp->current_limit),
4661          ntohl (mp->current_bucket),
4662          ntohl (mp->extended_limit),
4663          ntohl (mp->extended_bucket),
4664          clib_net_to_host_u64 (mp->last_update_time),
4665          format_policer_action_type, mp->conform_action_type,
4666          conform_dscp_str,
4667          format_policer_action_type, mp->exceed_action_type,
4668          exceed_dscp_str,
4669          format_policer_action_type, mp->violate_action_type,
4670          violate_dscp_str);
4671
4672   vec_free (conform_dscp_str);
4673   vec_free (exceed_dscp_str);
4674   vec_free (violate_dscp_str);
4675 }
4676
4677 static void vl_api_policer_details_t_handler_json
4678   (vl_api_policer_details_t * mp)
4679 {
4680   vat_main_t *vam = &vat_main;
4681   vat_json_node_t *node;
4682   u8 *rate_type_str, *round_type_str, *type_str;
4683   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4684
4685   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4686   round_type_str =
4687     format (0, "%U", format_policer_round_type, mp->round_type);
4688   type_str = format (0, "%U", format_policer_type, mp->type);
4689   conform_action_str = format (0, "%U", format_policer_action_type,
4690                                mp->conform_action_type);
4691   exceed_action_str = format (0, "%U", format_policer_action_type,
4692                               mp->exceed_action_type);
4693   violate_action_str = format (0, "%U", format_policer_action_type,
4694                                mp->violate_action_type);
4695
4696   if (VAT_JSON_ARRAY != vam->json_tree.type)
4697     {
4698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4699       vat_json_init_array (&vam->json_tree);
4700     }
4701   node = vat_json_array_add (&vam->json_tree);
4702
4703   vat_json_init_object (node);
4704   vat_json_object_add_string_copy (node, "name", mp->name);
4705   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4706   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4707   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4708   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4709   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4710   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4711   vat_json_object_add_string_copy (node, "type", type_str);
4712   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4713   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4714   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4715   vat_json_object_add_uint (node, "cir_tokens_per_period",
4716                             ntohl (mp->cir_tokens_per_period));
4717   vat_json_object_add_uint (node, "eir_tokens_per_period",
4718                             ntohl (mp->pir_tokens_per_period));
4719   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4720   vat_json_object_add_uint (node, "current_bucket",
4721                             ntohl (mp->current_bucket));
4722   vat_json_object_add_uint (node, "extended_limit",
4723                             ntohl (mp->extended_limit));
4724   vat_json_object_add_uint (node, "extended_bucket",
4725                             ntohl (mp->extended_bucket));
4726   vat_json_object_add_uint (node, "last_update_time",
4727                             ntohl (mp->last_update_time));
4728   vat_json_object_add_string_copy (node, "conform_action",
4729                                    conform_action_str);
4730   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4731     {
4732       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4733       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4734       vec_free (dscp_str);
4735     }
4736   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4737   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4738     {
4739       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4740       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4741       vec_free (dscp_str);
4742     }
4743   vat_json_object_add_string_copy (node, "violate_action",
4744                                    violate_action_str);
4745   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4746     {
4747       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4748       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4749       vec_free (dscp_str);
4750     }
4751
4752   vec_free (rate_type_str);
4753   vec_free (round_type_str);
4754   vec_free (type_str);
4755   vec_free (conform_action_str);
4756   vec_free (exceed_action_str);
4757   vec_free (violate_action_str);
4758 }
4759
4760 static void
4761 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4762                                            mp)
4763 {
4764   vat_main_t *vam = &vat_main;
4765   int i, count = ntohl (mp->count);
4766
4767   if (count > 0)
4768     print (vam->ofp, "classify table ids (%d) : ", count);
4769   for (i = 0; i < count; i++)
4770     {
4771       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4772       print (vam->ofp, (i < count - 1) ? "," : "");
4773     }
4774   vam->retval = ntohl (mp->retval);
4775   vam->result_ready = 1;
4776 }
4777
4778 static void
4779   vl_api_classify_table_ids_reply_t_handler_json
4780   (vl_api_classify_table_ids_reply_t * mp)
4781 {
4782   vat_main_t *vam = &vat_main;
4783   int i, count = ntohl (mp->count);
4784
4785   if (count > 0)
4786     {
4787       vat_json_node_t node;
4788
4789       vat_json_init_object (&node);
4790       for (i = 0; i < count; i++)
4791         {
4792           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4793         }
4794       vat_json_print (vam->ofp, &node);
4795       vat_json_free (&node);
4796     }
4797   vam->retval = ntohl (mp->retval);
4798   vam->result_ready = 1;
4799 }
4800
4801 static void
4802   vl_api_classify_table_by_interface_reply_t_handler
4803   (vl_api_classify_table_by_interface_reply_t * mp)
4804 {
4805   vat_main_t *vam = &vat_main;
4806   u32 table_id;
4807
4808   table_id = ntohl (mp->l2_table_id);
4809   if (table_id != ~0)
4810     print (vam->ofp, "l2 table id : %d", table_id);
4811   else
4812     print (vam->ofp, "l2 table id : No input ACL tables configured");
4813   table_id = ntohl (mp->ip4_table_id);
4814   if (table_id != ~0)
4815     print (vam->ofp, "ip4 table id : %d", table_id);
4816   else
4817     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4818   table_id = ntohl (mp->ip6_table_id);
4819   if (table_id != ~0)
4820     print (vam->ofp, "ip6 table id : %d", table_id);
4821   else
4822     print (vam->ofp, "ip6 table id : No input ACL tables configured");
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_json
4829   (vl_api_classify_table_by_interface_reply_t * mp)
4830 {
4831   vat_main_t *vam = &vat_main;
4832   vat_json_node_t node;
4833
4834   vat_json_init_object (&node);
4835
4836   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4837   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4838   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4839
4840   vat_json_print (vam->ofp, &node);
4841   vat_json_free (&node);
4842
4843   vam->retval = ntohl (mp->retval);
4844   vam->result_ready = 1;
4845 }
4846
4847 static void vl_api_policer_add_del_reply_t_handler
4848   (vl_api_policer_add_del_reply_t * mp)
4849 {
4850   vat_main_t *vam = &vat_main;
4851   i32 retval = ntohl (mp->retval);
4852   if (vam->async_mode)
4853     {
4854       vam->async_errors += (retval < 0);
4855     }
4856   else
4857     {
4858       vam->retval = retval;
4859       vam->result_ready = 1;
4860       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4861         /*
4862          * Note: this is just barely thread-safe, depends on
4863          * the main thread spinning waiting for an answer...
4864          */
4865         errmsg ("policer index %d", ntohl (mp->policer_index));
4866     }
4867 }
4868
4869 static void vl_api_policer_add_del_reply_t_handler_json
4870   (vl_api_policer_add_del_reply_t * mp)
4871 {
4872   vat_main_t *vam = &vat_main;
4873   vat_json_node_t node;
4874
4875   vat_json_init_object (&node);
4876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4877   vat_json_object_add_uint (&node, "policer_index",
4878                             ntohl (mp->policer_index));
4879
4880   vat_json_print (vam->ofp, &node);
4881   vat_json_free (&node);
4882
4883   vam->retval = ntohl (mp->retval);
4884   vam->result_ready = 1;
4885 }
4886
4887 /* Format hex dump. */
4888 u8 *
4889 format_hex_bytes (u8 * s, va_list * va)
4890 {
4891   u8 *bytes = va_arg (*va, u8 *);
4892   int n_bytes = va_arg (*va, int);
4893   uword i;
4894
4895   /* Print short or long form depending on byte count. */
4896   uword short_form = n_bytes <= 32;
4897   u32 indent = format_get_indent (s);
4898
4899   if (n_bytes == 0)
4900     return s;
4901
4902   for (i = 0; i < n_bytes; i++)
4903     {
4904       if (!short_form && (i % 32) == 0)
4905         s = format (s, "%08x: ", i);
4906       s = format (s, "%02x", bytes[i]);
4907       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4908         s = format (s, "\n%U", format_white_space, indent);
4909     }
4910
4911   return s;
4912 }
4913
4914 static void
4915 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4916                                             * mp)
4917 {
4918   vat_main_t *vam = &vat_main;
4919   i32 retval = ntohl (mp->retval);
4920   if (retval == 0)
4921     {
4922       print (vam->ofp, "classify table info :");
4923       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4924              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4925              ntohl (mp->miss_next_index));
4926       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4927              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4928              ntohl (mp->match_n_vectors));
4929       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4930              ntohl (mp->mask_length));
4931     }
4932   vam->retval = retval;
4933   vam->result_ready = 1;
4934 }
4935
4936 static void
4937   vl_api_classify_table_info_reply_t_handler_json
4938   (vl_api_classify_table_info_reply_t * mp)
4939 {
4940   vat_main_t *vam = &vat_main;
4941   vat_json_node_t node;
4942
4943   i32 retval = ntohl (mp->retval);
4944   if (retval == 0)
4945     {
4946       vat_json_init_object (&node);
4947
4948       vat_json_object_add_int (&node, "sessions",
4949                                ntohl (mp->active_sessions));
4950       vat_json_object_add_int (&node, "nexttbl",
4951                                ntohl (mp->next_table_index));
4952       vat_json_object_add_int (&node, "nextnode",
4953                                ntohl (mp->miss_next_index));
4954       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4955       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4956       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4957       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4958                       ntohl (mp->mask_length), 0);
4959       vat_json_object_add_string_copy (&node, "mask", s);
4960
4961       vat_json_print (vam->ofp, &node);
4962       vat_json_free (&node);
4963     }
4964   vam->retval = ntohl (mp->retval);
4965   vam->result_ready = 1;
4966 }
4967
4968 static void
4969 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4970                                            mp)
4971 {
4972   vat_main_t *vam = &vat_main;
4973
4974   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4975          ntohl (mp->hit_next_index), ntohl (mp->advance),
4976          ntohl (mp->opaque_index));
4977   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4978          ntohl (mp->match_length));
4979 }
4980
4981 static void
4982   vl_api_classify_session_details_t_handler_json
4983   (vl_api_classify_session_details_t * mp)
4984 {
4985   vat_main_t *vam = &vat_main;
4986   vat_json_node_t *node = NULL;
4987
4988   if (VAT_JSON_ARRAY != vam->json_tree.type)
4989     {
4990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4991       vat_json_init_array (&vam->json_tree);
4992     }
4993   node = vat_json_array_add (&vam->json_tree);
4994
4995   vat_json_init_object (node);
4996   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4997   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4998   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4999   u8 *s =
5000     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5001             0);
5002   vat_json_object_add_string_copy (node, "match", s);
5003 }
5004
5005 static void vl_api_pg_create_interface_reply_t_handler
5006   (vl_api_pg_create_interface_reply_t * mp)
5007 {
5008   vat_main_t *vam = &vat_main;
5009
5010   vam->retval = ntohl (mp->retval);
5011   vam->result_ready = 1;
5012 }
5013
5014 static void vl_api_pg_create_interface_reply_t_handler_json
5015   (vl_api_pg_create_interface_reply_t * mp)
5016 {
5017   vat_main_t *vam = &vat_main;
5018   vat_json_node_t node;
5019
5020   i32 retval = ntohl (mp->retval);
5021   if (retval == 0)
5022     {
5023       vat_json_init_object (&node);
5024
5025       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5026
5027       vat_json_print (vam->ofp, &node);
5028       vat_json_free (&node);
5029     }
5030   vam->retval = ntohl (mp->retval);
5031   vam->result_ready = 1;
5032 }
5033
5034 static void vl_api_policer_classify_details_t_handler
5035   (vl_api_policer_classify_details_t * mp)
5036 {
5037   vat_main_t *vam = &vat_main;
5038
5039   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5040          ntohl (mp->table_index));
5041 }
5042
5043 static void vl_api_policer_classify_details_t_handler_json
5044   (vl_api_policer_classify_details_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   vat_json_node_t *node;
5048
5049   if (VAT_JSON_ARRAY != vam->json_tree.type)
5050     {
5051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5052       vat_json_init_array (&vam->json_tree);
5053     }
5054   node = vat_json_array_add (&vam->json_tree);
5055
5056   vat_json_init_object (node);
5057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5058   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5059 }
5060
5061 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5062   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5063 {
5064   vat_main_t *vam = &vat_main;
5065   i32 retval = ntohl (mp->retval);
5066   if (vam->async_mode)
5067     {
5068       vam->async_errors += (retval < 0);
5069     }
5070   else
5071     {
5072       vam->retval = retval;
5073       vam->sw_if_index = ntohl (mp->sw_if_index);
5074       vam->result_ready = 1;
5075     }
5076   vam->regenerate_interface_table = 1;
5077 }
5078
5079 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5080   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5081 {
5082   vat_main_t *vam = &vat_main;
5083   vat_json_node_t node;
5084
5085   vat_json_init_object (&node);
5086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5087   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5088
5089   vat_json_print (vam->ofp, &node);
5090   vat_json_free (&node);
5091
5092   vam->retval = ntohl (mp->retval);
5093   vam->result_ready = 1;
5094 }
5095
5096 static void vl_api_flow_classify_details_t_handler
5097   (vl_api_flow_classify_details_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100
5101   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5102          ntohl (mp->table_index));
5103 }
5104
5105 static void vl_api_flow_classify_details_t_handler_json
5106   (vl_api_flow_classify_details_t * mp)
5107 {
5108   vat_main_t *vam = &vat_main;
5109   vat_json_node_t *node;
5110
5111   if (VAT_JSON_ARRAY != vam->json_tree.type)
5112     {
5113       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5114       vat_json_init_array (&vam->json_tree);
5115     }
5116   node = vat_json_array_add (&vam->json_tree);
5117
5118   vat_json_init_object (node);
5119   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5120   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5121 }
5122
5123 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5124 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5125 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5126 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5127 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5128 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5129 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5130 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5131 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5132 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5133
5134 /*
5135  * Generate boilerplate reply handlers, which
5136  * dig the return value out of the xxx_reply_t API message,
5137  * stick it into vam->retval, and set vam->result_ready
5138  *
5139  * Could also do this by pointing N message decode slots at
5140  * a single function, but that could break in subtle ways.
5141  */
5142
5143 #define foreach_standard_reply_retval_handler           \
5144 _(sw_interface_set_flags_reply)                         \
5145 _(sw_interface_add_del_address_reply)                   \
5146 _(sw_interface_set_rx_mode_reply)                       \
5147 _(sw_interface_set_rx_placement_reply)                  \
5148 _(sw_interface_set_table_reply)                         \
5149 _(sw_interface_set_mpls_enable_reply)                   \
5150 _(sw_interface_set_vpath_reply)                         \
5151 _(sw_interface_set_vxlan_bypass_reply)                  \
5152 _(sw_interface_set_geneve_bypass_reply)                 \
5153 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5154 _(sw_interface_set_l2_bridge_reply)                     \
5155 _(bridge_domain_add_del_reply)                          \
5156 _(sw_interface_set_l2_xconnect_reply)                   \
5157 _(l2fib_add_del_reply)                                  \
5158 _(l2fib_flush_int_reply)                                \
5159 _(l2fib_flush_bd_reply)                                 \
5160 _(ip_add_del_route_reply)                               \
5161 _(ip_table_add_del_reply)                               \
5162 _(ip_mroute_add_del_reply)                              \
5163 _(mpls_route_add_del_reply)                             \
5164 _(mpls_table_add_del_reply)                             \
5165 _(mpls_ip_bind_unbind_reply)                            \
5166 _(bier_route_add_del_reply)                             \
5167 _(bier_table_add_del_reply)                             \
5168 _(proxy_arp_add_del_reply)                              \
5169 _(proxy_arp_intfc_enable_disable_reply)                 \
5170 _(sw_interface_set_unnumbered_reply)                    \
5171 _(ip_neighbor_add_del_reply)                            \
5172 _(oam_add_del_reply)                                    \
5173 _(reset_fib_reply)                                      \
5174 _(dhcp_proxy_config_reply)                              \
5175 _(dhcp_proxy_set_vss_reply)                             \
5176 _(dhcp_client_config_reply)                             \
5177 _(set_ip_flow_hash_reply)                               \
5178 _(sw_interface_ip6_enable_disable_reply)                \
5179 _(ip6nd_proxy_add_del_reply)                            \
5180 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5181 _(sw_interface_ip6nd_ra_config_reply)                   \
5182 _(set_arp_neighbor_limit_reply)                         \
5183 _(l2_patch_add_del_reply)                               \
5184 _(sr_mpls_policy_add_reply)                             \
5185 _(sr_mpls_policy_mod_reply)                             \
5186 _(sr_mpls_policy_del_reply)                             \
5187 _(sr_policy_add_reply)                                  \
5188 _(sr_policy_mod_reply)                                  \
5189 _(sr_policy_del_reply)                                  \
5190 _(sr_localsid_add_del_reply)                            \
5191 _(sr_steering_add_del_reply)                            \
5192 _(classify_add_del_session_reply)                       \
5193 _(classify_set_interface_ip_table_reply)                \
5194 _(classify_set_interface_l2_tables_reply)               \
5195 _(l2tpv3_set_tunnel_cookies_reply)                      \
5196 _(l2tpv3_interface_enable_disable_reply)                \
5197 _(l2tpv3_set_lookup_key_reply)                          \
5198 _(l2_fib_clear_table_reply)                             \
5199 _(l2_interface_efp_filter_reply)                        \
5200 _(l2_interface_vlan_tag_rewrite_reply)                  \
5201 _(modify_vhost_user_if_reply)                           \
5202 _(delete_vhost_user_if_reply)                           \
5203 _(ip_probe_neighbor_reply)                              \
5204 _(ip_scan_neighbor_enable_disable_reply)                \
5205 _(want_ip4_arp_events_reply)                            \
5206 _(want_ip6_nd_events_reply)                             \
5207 _(want_l2_macs_events_reply)                            \
5208 _(input_acl_set_interface_reply)                        \
5209 _(ipsec_spd_add_del_reply)                              \
5210 _(ipsec_interface_add_del_spd_reply)                    \
5211 _(ipsec_spd_add_del_entry_reply)                        \
5212 _(ipsec_sad_add_del_entry_reply)                        \
5213 _(ipsec_sa_set_key_reply)                               \
5214 _(ipsec_tunnel_if_add_del_reply)                        \
5215 _(ipsec_tunnel_if_set_key_reply)                        \
5216 _(ipsec_tunnel_if_set_sa_reply)                         \
5217 _(ikev2_profile_add_del_reply)                          \
5218 _(ikev2_profile_set_auth_reply)                         \
5219 _(ikev2_profile_set_id_reply)                           \
5220 _(ikev2_profile_set_ts_reply)                           \
5221 _(ikev2_set_local_key_reply)                            \
5222 _(ikev2_set_responder_reply)                            \
5223 _(ikev2_set_ike_transforms_reply)                       \
5224 _(ikev2_set_esp_transforms_reply)                       \
5225 _(ikev2_set_sa_lifetime_reply)                          \
5226 _(ikev2_initiate_sa_init_reply)                         \
5227 _(ikev2_initiate_del_ike_sa_reply)                      \
5228 _(ikev2_initiate_del_child_sa_reply)                    \
5229 _(ikev2_initiate_rekey_child_sa_reply)                  \
5230 _(delete_loopback_reply)                                \
5231 _(bd_ip_mac_add_del_reply)                              \
5232 _(bd_ip_mac_flush_reply)                                \
5233 _(want_interface_events_reply)                          \
5234 _(cop_interface_enable_disable_reply)                   \
5235 _(cop_whitelist_enable_disable_reply)                   \
5236 _(sw_interface_clear_stats_reply)                       \
5237 _(ioam_enable_reply)                                    \
5238 _(ioam_disable_reply)                                   \
5239 _(one_add_del_locator_reply)                            \
5240 _(one_add_del_local_eid_reply)                          \
5241 _(one_add_del_remote_mapping_reply)                     \
5242 _(one_add_del_adjacency_reply)                          \
5243 _(one_add_del_map_resolver_reply)                       \
5244 _(one_add_del_map_server_reply)                         \
5245 _(one_enable_disable_reply)                             \
5246 _(one_rloc_probe_enable_disable_reply)                  \
5247 _(one_map_register_enable_disable_reply)                \
5248 _(one_map_register_set_ttl_reply)                       \
5249 _(one_set_transport_protocol_reply)                     \
5250 _(one_map_register_fallback_threshold_reply)            \
5251 _(one_pitr_set_locator_set_reply)                       \
5252 _(one_map_request_mode_reply)                           \
5253 _(one_add_del_map_request_itr_rlocs_reply)              \
5254 _(one_eid_table_add_del_map_reply)                      \
5255 _(one_use_petr_reply)                                   \
5256 _(one_stats_enable_disable_reply)                       \
5257 _(one_add_del_l2_arp_entry_reply)                       \
5258 _(one_add_del_ndp_entry_reply)                          \
5259 _(one_stats_flush_reply)                                \
5260 _(one_enable_disable_xtr_mode_reply)                    \
5261 _(one_enable_disable_pitr_mode_reply)                   \
5262 _(one_enable_disable_petr_mode_reply)                   \
5263 _(gpe_enable_disable_reply)                             \
5264 _(gpe_set_encap_mode_reply)                             \
5265 _(gpe_add_del_iface_reply)                              \
5266 _(gpe_add_del_native_fwd_rpath_reply)                   \
5267 _(af_packet_delete_reply)                               \
5268 _(policer_classify_set_interface_reply)                 \
5269 _(netmap_create_reply)                                  \
5270 _(netmap_delete_reply)                                  \
5271 _(set_ipfix_exporter_reply)                             \
5272 _(set_ipfix_classify_stream_reply)                      \
5273 _(ipfix_classify_table_add_del_reply)                   \
5274 _(flow_classify_set_interface_reply)                    \
5275 _(sw_interface_span_enable_disable_reply)               \
5276 _(pg_capture_reply)                                     \
5277 _(pg_enable_disable_reply)                              \
5278 _(ip_source_and_port_range_check_add_del_reply)         \
5279 _(ip_source_and_port_range_check_interface_add_del_reply)\
5280 _(delete_subif_reply)                                   \
5281 _(l2_interface_pbb_tag_rewrite_reply)                   \
5282 _(set_punt_reply)                                       \
5283 _(feature_enable_disable_reply)                         \
5284 _(sw_interface_tag_add_del_reply)                       \
5285 _(hw_interface_set_mtu_reply)                           \
5286 _(p2p_ethernet_add_reply)                               \
5287 _(p2p_ethernet_del_reply)                               \
5288 _(lldp_config_reply)                                    \
5289 _(sw_interface_set_lldp_reply)                          \
5290 _(tcp_configure_src_addresses_reply)                    \
5291 _(dns_enable_disable_reply)                             \
5292 _(dns_name_server_add_del_reply)                        \
5293 _(session_rule_add_del_reply)                           \
5294 _(ip_container_proxy_add_del_reply)                     \
5295 _(output_acl_set_interface_reply)                       \
5296 _(qos_record_enable_disable_reply)
5297
5298 #define _(n)                                    \
5299     static void vl_api_##n##_t_handler          \
5300     (vl_api_##n##_t * mp)                       \
5301     {                                           \
5302         vat_main_t * vam = &vat_main;           \
5303         i32 retval = ntohl(mp->retval);         \
5304         if (vam->async_mode) {                  \
5305             vam->async_errors += (retval < 0);  \
5306         } else {                                \
5307             vam->retval = retval;               \
5308             vam->result_ready = 1;              \
5309         }                                       \
5310     }
5311 foreach_standard_reply_retval_handler;
5312 #undef _
5313
5314 #define _(n)                                    \
5315     static void vl_api_##n##_t_handler_json     \
5316     (vl_api_##n##_t * mp)                       \
5317     {                                           \
5318         vat_main_t * vam = &vat_main;           \
5319         vat_json_node_t node;                   \
5320         vat_json_init_object(&node);            \
5321         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5322         vat_json_print(vam->ofp, &node);        \
5323         vam->retval = ntohl(mp->retval);        \
5324         vam->result_ready = 1;                  \
5325     }
5326 foreach_standard_reply_retval_handler;
5327 #undef _
5328
5329 /*
5330  * Table of message reply handlers, must include boilerplate handlers
5331  * we just generated
5332  */
5333
5334 #define foreach_vpe_api_reply_msg                                       \
5335 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5336 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5337 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5338 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5339 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5340 _(CLI_REPLY, cli_reply)                                                 \
5341 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5342 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5343   sw_interface_add_del_address_reply)                                   \
5344 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5345 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5346 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5347 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5348 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5349 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5350 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5351 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5352 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5353 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5354   sw_interface_set_l2_xconnect_reply)                                   \
5355 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5356   sw_interface_set_l2_bridge_reply)                                     \
5357 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5358 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5359 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5360 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5361 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5362 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5363 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5364 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5365 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5366 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5367 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5368 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5369 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5370 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5371 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5372 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5373 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5374 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5375 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5376 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5377 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5378 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5379 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5380 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5381 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5382 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5383 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5384 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5385 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5386 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5387   proxy_arp_intfc_enable_disable_reply)                                 \
5388 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5389 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5390   sw_interface_set_unnumbered_reply)                                    \
5391 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5392 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5393 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5394 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5395 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5396 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5397 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5398 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5399 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5400 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5401 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5402   sw_interface_ip6_enable_disable_reply)                                \
5403 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5404 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5405 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5406   sw_interface_ip6nd_ra_prefix_reply)                                   \
5407 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5408   sw_interface_ip6nd_ra_config_reply)                                   \
5409 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5410 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5411 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5412 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5413 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5414 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5415 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5416 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5417 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5418 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5419 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5420 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5421 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5422 classify_set_interface_ip_table_reply)                                  \
5423 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5424   classify_set_interface_l2_tables_reply)                               \
5425 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5426 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5427 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5428 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5429 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5430   l2tpv3_interface_enable_disable_reply)                                \
5431 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5432 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5433 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5434 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5435 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5436 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5437 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5438 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5439 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5440 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5441 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5442 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5443 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5444 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5445 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5446 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5447 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5448 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5449 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5450 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5451 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5452 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5453 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5454 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5455 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5456 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5457 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5458 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5459 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5460 _(L2_MACS_EVENT, l2_macs_event)                                         \
5461 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5462 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5463 _(IP_DETAILS, ip_details)                                               \
5464 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5465 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5466 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5467 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5468 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5469 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5470 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5471 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5472 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5473 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5474 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5475 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5476 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5477 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5478 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5479 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5480 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5481 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5482 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5483 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5484 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5485 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5486 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5487 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5488 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5489 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5490 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5491 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5492 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5493 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5494 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5495 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5496 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5497 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5498 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5499 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5500 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5501 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5502 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5503 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5504 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5505 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5506 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5507 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5508   one_map_register_enable_disable_reply)                                \
5509 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5510 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5511 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5512 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5513   one_map_register_fallback_threshold_reply)                            \
5514 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5515   one_rloc_probe_enable_disable_reply)                                  \
5516 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5517 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5518 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5519 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5520 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5521 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5522 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5523 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5524 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5525 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5526 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5527 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5528 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5529 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5530 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5531 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5532   show_one_stats_enable_disable_reply)                                  \
5533 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5534 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5535 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5536 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5537 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5538 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5539 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5540 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5541   one_enable_disable_pitr_mode_reply)                                   \
5542 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5543   one_enable_disable_petr_mode_reply)                                   \
5544 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5545 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5546 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5547 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5548 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5549 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5550 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5551 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5552 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5553 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5554 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5555 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5556   gpe_add_del_native_fwd_rpath_reply)                                   \
5557 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5558   gpe_fwd_entry_path_details)                                           \
5559 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5560 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5561   one_add_del_map_request_itr_rlocs_reply)                              \
5562 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5563   one_get_map_request_itr_rlocs_reply)                                  \
5564 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5565 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5566 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5567 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5568 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5569 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5570   show_one_map_register_state_reply)                                    \
5571 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5572 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5573   show_one_map_register_fallback_threshold_reply)                       \
5574 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5575 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5576 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5577 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5578 _(POLICER_DETAILS, policer_details)                                     \
5579 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5580 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5581 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5582 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5583 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5584 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5585 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5586 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5587 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5588 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5589 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5590 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5591 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5592 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5593 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5594 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5595 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5596 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5597 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5598 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5599 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5600 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5601 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5602 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5603 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5604  ip_source_and_port_range_check_add_del_reply)                          \
5605 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5606  ip_source_and_port_range_check_interface_add_del_reply)                \
5607 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5608 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5609 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5610 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5611 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5612 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5613 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5614 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5615 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5616 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5617 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5618 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5619 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5620 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5621 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5622 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5623 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5624 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5625 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5626 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5627 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5628 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5629 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5630 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5631 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5632 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5633 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5634 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5635
5636 #define foreach_standalone_reply_msg                                    \
5637 _(SW_INTERFACE_EVENT, sw_interface_event)
5638
5639 typedef struct
5640 {
5641   u8 *name;
5642   u32 value;
5643 } name_sort_t;
5644
5645 #define STR_VTR_OP_CASE(op)     \
5646     case L2_VTR_ ## op:         \
5647         return "" # op;
5648
5649 static const char *
5650 str_vtr_op (u32 vtr_op)
5651 {
5652   switch (vtr_op)
5653     {
5654       STR_VTR_OP_CASE (DISABLED);
5655       STR_VTR_OP_CASE (PUSH_1);
5656       STR_VTR_OP_CASE (PUSH_2);
5657       STR_VTR_OP_CASE (POP_1);
5658       STR_VTR_OP_CASE (POP_2);
5659       STR_VTR_OP_CASE (TRANSLATE_1_1);
5660       STR_VTR_OP_CASE (TRANSLATE_1_2);
5661       STR_VTR_OP_CASE (TRANSLATE_2_1);
5662       STR_VTR_OP_CASE (TRANSLATE_2_2);
5663     }
5664
5665   return "UNKNOWN";
5666 }
5667
5668 static int
5669 dump_sub_interface_table (vat_main_t * vam)
5670 {
5671   const sw_interface_subif_t *sub = NULL;
5672
5673   if (vam->json_output)
5674     {
5675       clib_warning
5676         ("JSON output supported only for VPE API calls and dump_stats_table");
5677       return -99;
5678     }
5679
5680   print (vam->ofp,
5681          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5682          "Interface", "sw_if_index",
5683          "sub id", "dot1ad", "tags", "outer id",
5684          "inner id", "exact", "default", "outer any", "inner any");
5685
5686   vec_foreach (sub, vam->sw_if_subif_table)
5687   {
5688     print (vam->ofp,
5689            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5690            sub->interface_name,
5691            sub->sw_if_index,
5692            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5693            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5694            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5695            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5696     if (sub->vtr_op != L2_VTR_DISABLED)
5697       {
5698         print (vam->ofp,
5699                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5700                "tag1: %d tag2: %d ]",
5701                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5702                sub->vtr_tag1, sub->vtr_tag2);
5703       }
5704   }
5705
5706   return 0;
5707 }
5708
5709 static int
5710 name_sort_cmp (void *a1, void *a2)
5711 {
5712   name_sort_t *n1 = a1;
5713   name_sort_t *n2 = a2;
5714
5715   return strcmp ((char *) n1->name, (char *) n2->name);
5716 }
5717
5718 static int
5719 dump_interface_table (vat_main_t * vam)
5720 {
5721   hash_pair_t *p;
5722   name_sort_t *nses = 0, *ns;
5723
5724   if (vam->json_output)
5725     {
5726       clib_warning
5727         ("JSON output supported only for VPE API calls and dump_stats_table");
5728       return -99;
5729     }
5730
5731   /* *INDENT-OFF* */
5732   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5733   ({
5734     vec_add2 (nses, ns, 1);
5735     ns->name = (u8 *)(p->key);
5736     ns->value = (u32) p->value[0];
5737   }));
5738   /* *INDENT-ON* */
5739
5740   vec_sort_with_function (nses, name_sort_cmp);
5741
5742   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5743   vec_foreach (ns, nses)
5744   {
5745     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5746   }
5747   vec_free (nses);
5748   return 0;
5749 }
5750
5751 static int
5752 dump_ip_table (vat_main_t * vam, int is_ipv6)
5753 {
5754   const ip_details_t *det = NULL;
5755   const ip_address_details_t *address = NULL;
5756   u32 i = ~0;
5757
5758   print (vam->ofp, "%-12s", "sw_if_index");
5759
5760   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5761   {
5762     i++;
5763     if (!det->present)
5764       {
5765         continue;
5766       }
5767     print (vam->ofp, "%-12d", i);
5768     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5769     if (!det->addr)
5770       {
5771         continue;
5772       }
5773     vec_foreach (address, det->addr)
5774     {
5775       print (vam->ofp,
5776              "            %-30U%-13d",
5777              is_ipv6 ? format_ip6_address : format_ip4_address,
5778              address->ip, address->prefix_length);
5779     }
5780   }
5781
5782   return 0;
5783 }
5784
5785 static int
5786 dump_ipv4_table (vat_main_t * vam)
5787 {
5788   if (vam->json_output)
5789     {
5790       clib_warning
5791         ("JSON output supported only for VPE API calls and dump_stats_table");
5792       return -99;
5793     }
5794
5795   return dump_ip_table (vam, 0);
5796 }
5797
5798 static int
5799 dump_ipv6_table (vat_main_t * vam)
5800 {
5801   if (vam->json_output)
5802     {
5803       clib_warning
5804         ("JSON output supported only for VPE API calls and dump_stats_table");
5805       return -99;
5806     }
5807
5808   return dump_ip_table (vam, 1);
5809 }
5810
5811 /*
5812  * Pass CLI buffers directly in the CLI_INBAND API message,
5813  * instead of an additional shared memory area.
5814  */
5815 static int
5816 exec_inband (vat_main_t * vam)
5817 {
5818   vl_api_cli_inband_t *mp;
5819   unformat_input_t *i = vam->input;
5820   int ret;
5821
5822   if (vec_len (i->buffer) == 0)
5823     return -1;
5824
5825   if (vam->exec_mode == 0 && unformat (i, "mode"))
5826     {
5827       vam->exec_mode = 1;
5828       return 0;
5829     }
5830   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5831     {
5832       vam->exec_mode = 0;
5833       return 0;
5834     }
5835
5836   /*
5837    * In order for the CLI command to work, it
5838    * must be a vector ending in \n, not a C-string ending
5839    * in \n\0.
5840    */
5841   u32 len = vec_len (vam->input->buffer);
5842   M2 (CLI_INBAND, mp, len);
5843   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5844
5845   S (mp);
5846   W (ret);
5847   /* json responses may or may not include a useful reply... */
5848   if (vec_len (vam->cmd_reply))
5849     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5850   return ret;
5851 }
5852
5853 int
5854 exec (vat_main_t * vam)
5855 {
5856   return exec_inband (vam);
5857 }
5858
5859 static int
5860 api_create_loopback (vat_main_t * vam)
5861 {
5862   unformat_input_t *i = vam->input;
5863   vl_api_create_loopback_t *mp;
5864   vl_api_create_loopback_instance_t *mp_lbi;
5865   u8 mac_address[6];
5866   u8 mac_set = 0;
5867   u8 is_specified = 0;
5868   u32 user_instance = 0;
5869   int ret;
5870
5871   clib_memset (mac_address, 0, sizeof (mac_address));
5872
5873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5874     {
5875       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5876         mac_set = 1;
5877       if (unformat (i, "instance %d", &user_instance))
5878         is_specified = 1;
5879       else
5880         break;
5881     }
5882
5883   if (is_specified)
5884     {
5885       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5886       mp_lbi->is_specified = is_specified;
5887       if (is_specified)
5888         mp_lbi->user_instance = htonl (user_instance);
5889       if (mac_set)
5890         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5891       S (mp_lbi);
5892     }
5893   else
5894     {
5895       /* Construct the API message */
5896       M (CREATE_LOOPBACK, mp);
5897       if (mac_set)
5898         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5899       S (mp);
5900     }
5901
5902   W (ret);
5903   return ret;
5904 }
5905
5906 static int
5907 api_delete_loopback (vat_main_t * vam)
5908 {
5909   unformat_input_t *i = vam->input;
5910   vl_api_delete_loopback_t *mp;
5911   u32 sw_if_index = ~0;
5912   int ret;
5913
5914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5915     {
5916       if (unformat (i, "sw_if_index %d", &sw_if_index))
5917         ;
5918       else
5919         break;
5920     }
5921
5922   if (sw_if_index == ~0)
5923     {
5924       errmsg ("missing sw_if_index");
5925       return -99;
5926     }
5927
5928   /* Construct the API message */
5929   M (DELETE_LOOPBACK, mp);
5930   mp->sw_if_index = ntohl (sw_if_index);
5931
5932   S (mp);
5933   W (ret);
5934   return ret;
5935 }
5936
5937 static int
5938 api_want_interface_events (vat_main_t * vam)
5939 {
5940   unformat_input_t *i = vam->input;
5941   vl_api_want_interface_events_t *mp;
5942   int enable = -1;
5943   int ret;
5944
5945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5946     {
5947       if (unformat (i, "enable"))
5948         enable = 1;
5949       else if (unformat (i, "disable"))
5950         enable = 0;
5951       else
5952         break;
5953     }
5954
5955   if (enable == -1)
5956     {
5957       errmsg ("missing enable|disable");
5958       return -99;
5959     }
5960
5961   M (WANT_INTERFACE_EVENTS, mp);
5962   mp->enable_disable = enable;
5963
5964   vam->interface_event_display = enable;
5965
5966   S (mp);
5967   W (ret);
5968   return ret;
5969 }
5970
5971
5972 /* Note: non-static, called once to set up the initial intfc table */
5973 int
5974 api_sw_interface_dump (vat_main_t * vam)
5975 {
5976   vl_api_sw_interface_dump_t *mp;
5977   vl_api_control_ping_t *mp_ping;
5978   hash_pair_t *p;
5979   name_sort_t *nses = 0, *ns;
5980   sw_interface_subif_t *sub = NULL;
5981   int ret;
5982
5983   /* Toss the old name table */
5984   /* *INDENT-OFF* */
5985   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5986   ({
5987     vec_add2 (nses, ns, 1);
5988     ns->name = (u8 *)(p->key);
5989     ns->value = (u32) p->value[0];
5990   }));
5991   /* *INDENT-ON* */
5992
5993   hash_free (vam->sw_if_index_by_interface_name);
5994
5995   vec_foreach (ns, nses) vec_free (ns->name);
5996
5997   vec_free (nses);
5998
5999   vec_foreach (sub, vam->sw_if_subif_table)
6000   {
6001     vec_free (sub->interface_name);
6002   }
6003   vec_free (vam->sw_if_subif_table);
6004
6005   /* recreate the interface name hash table */
6006   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6007
6008   /*
6009    * Ask for all interface names. Otherwise, the epic catalog of
6010    * name filters becomes ridiculously long, and vat ends up needing
6011    * to be taught about new interface types.
6012    */
6013   M (SW_INTERFACE_DUMP, mp);
6014   S (mp);
6015
6016   /* Use a control ping for synchronization */
6017   MPING (CONTROL_PING, mp_ping);
6018   S (mp_ping);
6019
6020   W (ret);
6021   return ret;
6022 }
6023
6024 static int
6025 api_sw_interface_set_flags (vat_main_t * vam)
6026 {
6027   unformat_input_t *i = vam->input;
6028   vl_api_sw_interface_set_flags_t *mp;
6029   u32 sw_if_index;
6030   u8 sw_if_index_set = 0;
6031   u8 admin_up = 0;
6032   int ret;
6033
6034   /* Parse args required to build the message */
6035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6036     {
6037       if (unformat (i, "admin-up"))
6038         admin_up = 1;
6039       else if (unformat (i, "admin-down"))
6040         admin_up = 0;
6041       else
6042         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6043         sw_if_index_set = 1;
6044       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6045         sw_if_index_set = 1;
6046       else
6047         break;
6048     }
6049
6050   if (sw_if_index_set == 0)
6051     {
6052       errmsg ("missing interface name or sw_if_index");
6053       return -99;
6054     }
6055
6056   /* Construct the API message */
6057   M (SW_INTERFACE_SET_FLAGS, mp);
6058   mp->sw_if_index = ntohl (sw_if_index);
6059   mp->admin_up_down = admin_up;
6060
6061   /* send it... */
6062   S (mp);
6063
6064   /* Wait for a reply, return the good/bad news... */
6065   W (ret);
6066   return ret;
6067 }
6068
6069 static int
6070 api_sw_interface_set_rx_mode (vat_main_t * vam)
6071 {
6072   unformat_input_t *i = vam->input;
6073   vl_api_sw_interface_set_rx_mode_t *mp;
6074   u32 sw_if_index;
6075   u8 sw_if_index_set = 0;
6076   int ret;
6077   u8 queue_id_valid = 0;
6078   u32 queue_id;
6079   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6080
6081   /* Parse args required to build the message */
6082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6083     {
6084       if (unformat (i, "queue %d", &queue_id))
6085         queue_id_valid = 1;
6086       else if (unformat (i, "polling"))
6087         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6088       else if (unformat (i, "interrupt"))
6089         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6090       else if (unformat (i, "adaptive"))
6091         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6092       else
6093         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6094         sw_if_index_set = 1;
6095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6096         sw_if_index_set = 1;
6097       else
6098         break;
6099     }
6100
6101   if (sw_if_index_set == 0)
6102     {
6103       errmsg ("missing interface name or sw_if_index");
6104       return -99;
6105     }
6106   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6107     {
6108       errmsg ("missing rx-mode");
6109       return -99;
6110     }
6111
6112   /* Construct the API message */
6113   M (SW_INTERFACE_SET_RX_MODE, mp);
6114   mp->sw_if_index = ntohl (sw_if_index);
6115   mp->mode = mode;
6116   mp->queue_id_valid = queue_id_valid;
6117   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6118
6119   /* send it... */
6120   S (mp);
6121
6122   /* Wait for a reply, return the good/bad news... */
6123   W (ret);
6124   return ret;
6125 }
6126
6127 static int
6128 api_sw_interface_set_rx_placement (vat_main_t * vam)
6129 {
6130   unformat_input_t *i = vam->input;
6131   vl_api_sw_interface_set_rx_placement_t *mp;
6132   u32 sw_if_index;
6133   u8 sw_if_index_set = 0;
6134   int ret;
6135   u8 is_main = 0;
6136   u32 queue_id, thread_index;
6137
6138   /* Parse args required to build the message */
6139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6140     {
6141       if (unformat (i, "queue %d", &queue_id))
6142         ;
6143       else if (unformat (i, "main"))
6144         is_main = 1;
6145       else if (unformat (i, "worker %d", &thread_index))
6146         ;
6147       else
6148         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6149         sw_if_index_set = 1;
6150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6151         sw_if_index_set = 1;
6152       else
6153         break;
6154     }
6155
6156   if (sw_if_index_set == 0)
6157     {
6158       errmsg ("missing interface name or sw_if_index");
6159       return -99;
6160     }
6161
6162   if (is_main)
6163     thread_index = 0;
6164   /* Construct the API message */
6165   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6166   mp->sw_if_index = ntohl (sw_if_index);
6167   mp->worker_id = ntohl (thread_index);
6168   mp->queue_id = ntohl (queue_id);
6169   mp->is_main = is_main;
6170
6171   /* send it... */
6172   S (mp);
6173   /* Wait for a reply, return the good/bad news... */
6174   W (ret);
6175   return ret;
6176 }
6177
6178 static void vl_api_sw_interface_rx_placement_details_t_handler
6179   (vl_api_sw_interface_rx_placement_details_t * mp)
6180 {
6181   vat_main_t *vam = &vat_main;
6182   u32 worker_id = ntohl (mp->worker_id);
6183
6184   print (vam->ofp,
6185          "\n%-11d %-11s %-6d %-5d %-9s",
6186          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6187          worker_id, ntohl (mp->queue_id),
6188          (mp->mode ==
6189           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6190 }
6191
6192 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6193   (vl_api_sw_interface_rx_placement_details_t * mp)
6194 {
6195   vat_main_t *vam = &vat_main;
6196   vat_json_node_t *node = NULL;
6197
6198   if (VAT_JSON_ARRAY != vam->json_tree.type)
6199     {
6200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6201       vat_json_init_array (&vam->json_tree);
6202     }
6203   node = vat_json_array_add (&vam->json_tree);
6204
6205   vat_json_init_object (node);
6206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6207   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6208   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6209   vat_json_object_add_uint (node, "mode", mp->mode);
6210 }
6211
6212 static int
6213 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6214 {
6215   unformat_input_t *i = vam->input;
6216   vl_api_sw_interface_rx_placement_dump_t *mp;
6217   vl_api_control_ping_t *mp_ping;
6218   int ret;
6219   u32 sw_if_index;
6220   u8 sw_if_index_set = 0;
6221
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++;
6226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6227         sw_if_index_set++;
6228       else
6229         break;
6230     }
6231
6232   print (vam->ofp,
6233          "\n%-11s %-11s %-6s %-5s %-4s",
6234          "sw_if_index", "main/worker", "thread", "queue", "mode");
6235
6236   /* Dump Interface rx placement */
6237   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6238
6239   if (sw_if_index_set)
6240     mp->sw_if_index = htonl (sw_if_index);
6241   else
6242     mp->sw_if_index = ~0;
6243
6244   S (mp);
6245
6246   /* Use a control ping for synchronization */
6247   MPING (CONTROL_PING, mp_ping);
6248   S (mp_ping);
6249
6250   W (ret);
6251   return ret;
6252 }
6253
6254 static int
6255 api_sw_interface_clear_stats (vat_main_t * vam)
6256 {
6257   unformat_input_t *i = vam->input;
6258   vl_api_sw_interface_clear_stats_t *mp;
6259   u32 sw_if_index;
6260   u8 sw_if_index_set = 0;
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, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6267         sw_if_index_set = 1;
6268       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6269         sw_if_index_set = 1;
6270       else
6271         break;
6272     }
6273
6274   /* Construct the API message */
6275   M (SW_INTERFACE_CLEAR_STATS, mp);
6276
6277   if (sw_if_index_set == 1)
6278     mp->sw_if_index = ntohl (sw_if_index);
6279   else
6280     mp->sw_if_index = ~0;
6281
6282   /* send it... */
6283   S (mp);
6284
6285   /* Wait for a reply, return the good/bad news... */
6286   W (ret);
6287   return ret;
6288 }
6289
6290 static int
6291 api_sw_interface_add_del_address (vat_main_t * vam)
6292 {
6293   unformat_input_t *i = vam->input;
6294   vl_api_sw_interface_add_del_address_t *mp;
6295   u32 sw_if_index;
6296   u8 sw_if_index_set = 0;
6297   u8 is_add = 1, del_all = 0;
6298   u32 address_length = 0;
6299   u8 v4_address_set = 0;
6300   u8 v6_address_set = 0;
6301   ip4_address_t v4address;
6302   ip6_address_t v6address;
6303   int ret;
6304
6305   /* Parse args required to build the message */
6306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6307     {
6308       if (unformat (i, "del-all"))
6309         del_all = 1;
6310       else if (unformat (i, "del"))
6311         is_add = 0;
6312       else
6313         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6314         sw_if_index_set = 1;
6315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6316         sw_if_index_set = 1;
6317       else if (unformat (i, "%U/%d",
6318                          unformat_ip4_address, &v4address, &address_length))
6319         v4_address_set = 1;
6320       else if (unformat (i, "%U/%d",
6321                          unformat_ip6_address, &v6address, &address_length))
6322         v6_address_set = 1;
6323       else
6324         break;
6325     }
6326
6327   if (sw_if_index_set == 0)
6328     {
6329       errmsg ("missing interface name or sw_if_index");
6330       return -99;
6331     }
6332   if (v4_address_set && v6_address_set)
6333     {
6334       errmsg ("both v4 and v6 addresses set");
6335       return -99;
6336     }
6337   if (!v4_address_set && !v6_address_set && !del_all)
6338     {
6339       errmsg ("no addresses set");
6340       return -99;
6341     }
6342
6343   /* Construct the API message */
6344   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6345
6346   mp->sw_if_index = ntohl (sw_if_index);
6347   mp->is_add = is_add;
6348   mp->del_all = del_all;
6349   if (v6_address_set)
6350     {
6351       mp->is_ipv6 = 1;
6352       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6353     }
6354   else
6355     {
6356       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6357     }
6358   mp->address_length = address_length;
6359
6360   /* send it... */
6361   S (mp);
6362
6363   /* Wait for a reply, return good/bad news  */
6364   W (ret);
6365   return ret;
6366 }
6367
6368 static int
6369 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6370 {
6371   unformat_input_t *i = vam->input;
6372   vl_api_sw_interface_set_mpls_enable_t *mp;
6373   u32 sw_if_index;
6374   u8 sw_if_index_set = 0;
6375   u8 enable = 1;
6376   int ret;
6377
6378   /* Parse args required to build the message */
6379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6380     {
6381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6382         sw_if_index_set = 1;
6383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6384         sw_if_index_set = 1;
6385       else if (unformat (i, "disable"))
6386         enable = 0;
6387       else if (unformat (i, "dis"))
6388         enable = 0;
6389       else
6390         break;
6391     }
6392
6393   if (sw_if_index_set == 0)
6394     {
6395       errmsg ("missing interface name or sw_if_index");
6396       return -99;
6397     }
6398
6399   /* Construct the API message */
6400   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6401
6402   mp->sw_if_index = ntohl (sw_if_index);
6403   mp->enable = enable;
6404
6405   /* send it... */
6406   S (mp);
6407
6408   /* Wait for a reply... */
6409   W (ret);
6410   return ret;
6411 }
6412
6413 static int
6414 api_sw_interface_set_table (vat_main_t * vam)
6415 {
6416   unformat_input_t *i = vam->input;
6417   vl_api_sw_interface_set_table_t *mp;
6418   u32 sw_if_index, vrf_id = 0;
6419   u8 sw_if_index_set = 0;
6420   u8 is_ipv6 = 0;
6421   int ret;
6422
6423   /* Parse args required to build the message */
6424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6425     {
6426       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6427         sw_if_index_set = 1;
6428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6429         sw_if_index_set = 1;
6430       else if (unformat (i, "vrf %d", &vrf_id))
6431         ;
6432       else if (unformat (i, "ipv6"))
6433         is_ipv6 = 1;
6434       else
6435         break;
6436     }
6437
6438   if (sw_if_index_set == 0)
6439     {
6440       errmsg ("missing interface name or sw_if_index");
6441       return -99;
6442     }
6443
6444   /* Construct the API message */
6445   M (SW_INTERFACE_SET_TABLE, mp);
6446
6447   mp->sw_if_index = ntohl (sw_if_index);
6448   mp->is_ipv6 = is_ipv6;
6449   mp->vrf_id = ntohl (vrf_id);
6450
6451   /* send it... */
6452   S (mp);
6453
6454   /* Wait for a reply... */
6455   W (ret);
6456   return ret;
6457 }
6458
6459 static void vl_api_sw_interface_get_table_reply_t_handler
6460   (vl_api_sw_interface_get_table_reply_t * mp)
6461 {
6462   vat_main_t *vam = &vat_main;
6463
6464   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6465
6466   vam->retval = ntohl (mp->retval);
6467   vam->result_ready = 1;
6468
6469 }
6470
6471 static void vl_api_sw_interface_get_table_reply_t_handler_json
6472   (vl_api_sw_interface_get_table_reply_t * mp)
6473 {
6474   vat_main_t *vam = &vat_main;
6475   vat_json_node_t node;
6476
6477   vat_json_init_object (&node);
6478   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6479   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6480
6481   vat_json_print (vam->ofp, &node);
6482   vat_json_free (&node);
6483
6484   vam->retval = ntohl (mp->retval);
6485   vam->result_ready = 1;
6486 }
6487
6488 static int
6489 api_sw_interface_get_table (vat_main_t * vam)
6490 {
6491   unformat_input_t *i = vam->input;
6492   vl_api_sw_interface_get_table_t *mp;
6493   u32 sw_if_index;
6494   u8 sw_if_index_set = 0;
6495   u8 is_ipv6 = 0;
6496   int ret;
6497
6498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499     {
6500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6501         sw_if_index_set = 1;
6502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6503         sw_if_index_set = 1;
6504       else if (unformat (i, "ipv6"))
6505         is_ipv6 = 1;
6506       else
6507         break;
6508     }
6509
6510   if (sw_if_index_set == 0)
6511     {
6512       errmsg ("missing interface name or sw_if_index");
6513       return -99;
6514     }
6515
6516   M (SW_INTERFACE_GET_TABLE, mp);
6517   mp->sw_if_index = htonl (sw_if_index);
6518   mp->is_ipv6 = is_ipv6;
6519
6520   S (mp);
6521   W (ret);
6522   return ret;
6523 }
6524
6525 static int
6526 api_sw_interface_set_vpath (vat_main_t * vam)
6527 {
6528   unformat_input_t *i = vam->input;
6529   vl_api_sw_interface_set_vpath_t *mp;
6530   u32 sw_if_index = 0;
6531   u8 sw_if_index_set = 0;
6532   u8 is_enable = 0;
6533   int ret;
6534
6535   /* Parse args required to build the message */
6536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6537     {
6538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6539         sw_if_index_set = 1;
6540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6541         sw_if_index_set = 1;
6542       else if (unformat (i, "enable"))
6543         is_enable = 1;
6544       else if (unformat (i, "disable"))
6545         is_enable = 0;
6546       else
6547         break;
6548     }
6549
6550   if (sw_if_index_set == 0)
6551     {
6552       errmsg ("missing interface name or sw_if_index");
6553       return -99;
6554     }
6555
6556   /* Construct the API message */
6557   M (SW_INTERFACE_SET_VPATH, mp);
6558
6559   mp->sw_if_index = ntohl (sw_if_index);
6560   mp->enable = is_enable;
6561
6562   /* send it... */
6563   S (mp);
6564
6565   /* Wait for a reply... */
6566   W (ret);
6567   return ret;
6568 }
6569
6570 static int
6571 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6575   u32 sw_if_index = 0;
6576   u8 sw_if_index_set = 0;
6577   u8 is_enable = 1;
6578   u8 is_ipv6 = 0;
6579   int ret;
6580
6581   /* Parse args required to build the message */
6582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6583     {
6584       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6585         sw_if_index_set = 1;
6586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6587         sw_if_index_set = 1;
6588       else if (unformat (i, "enable"))
6589         is_enable = 1;
6590       else if (unformat (i, "disable"))
6591         is_enable = 0;
6592       else if (unformat (i, "ip4"))
6593         is_ipv6 = 0;
6594       else if (unformat (i, "ip6"))
6595         is_ipv6 = 1;
6596       else
6597         break;
6598     }
6599
6600   if (sw_if_index_set == 0)
6601     {
6602       errmsg ("missing interface name or sw_if_index");
6603       return -99;
6604     }
6605
6606   /* Construct the API message */
6607   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6608
6609   mp->sw_if_index = ntohl (sw_if_index);
6610   mp->enable = is_enable;
6611   mp->is_ipv6 = is_ipv6;
6612
6613   /* send it... */
6614   S (mp);
6615
6616   /* Wait for a reply... */
6617   W (ret);
6618   return ret;
6619 }
6620
6621 static int
6622 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6623 {
6624   unformat_input_t *i = vam->input;
6625   vl_api_sw_interface_set_geneve_bypass_t *mp;
6626   u32 sw_if_index = 0;
6627   u8 sw_if_index_set = 0;
6628   u8 is_enable = 1;
6629   u8 is_ipv6 = 0;
6630   int ret;
6631
6632   /* Parse args required to build the message */
6633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6634     {
6635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6636         sw_if_index_set = 1;
6637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6638         sw_if_index_set = 1;
6639       else if (unformat (i, "enable"))
6640         is_enable = 1;
6641       else if (unformat (i, "disable"))
6642         is_enable = 0;
6643       else if (unformat (i, "ip4"))
6644         is_ipv6 = 0;
6645       else if (unformat (i, "ip6"))
6646         is_ipv6 = 1;
6647       else
6648         break;
6649     }
6650
6651   if (sw_if_index_set == 0)
6652     {
6653       errmsg ("missing interface name or sw_if_index");
6654       return -99;
6655     }
6656
6657   /* Construct the API message */
6658   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6659
6660   mp->sw_if_index = ntohl (sw_if_index);
6661   mp->enable = is_enable;
6662   mp->is_ipv6 = is_ipv6;
6663
6664   /* send it... */
6665   S (mp);
6666
6667   /* Wait for a reply... */
6668   W (ret);
6669   return ret;
6670 }
6671
6672 static int
6673 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6674 {
6675   unformat_input_t *i = vam->input;
6676   vl_api_sw_interface_set_l2_xconnect_t *mp;
6677   u32 rx_sw_if_index;
6678   u8 rx_sw_if_index_set = 0;
6679   u32 tx_sw_if_index;
6680   u8 tx_sw_if_index_set = 0;
6681   u8 enable = 1;
6682   int ret;
6683
6684   /* Parse args required to build the message */
6685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6686     {
6687       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6688         rx_sw_if_index_set = 1;
6689       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6690         tx_sw_if_index_set = 1;
6691       else if (unformat (i, "rx"))
6692         {
6693           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6694             {
6695               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6696                             &rx_sw_if_index))
6697                 rx_sw_if_index_set = 1;
6698             }
6699           else
6700             break;
6701         }
6702       else if (unformat (i, "tx"))
6703         {
6704           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6705             {
6706               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6707                             &tx_sw_if_index))
6708                 tx_sw_if_index_set = 1;
6709             }
6710           else
6711             break;
6712         }
6713       else if (unformat (i, "enable"))
6714         enable = 1;
6715       else if (unformat (i, "disable"))
6716         enable = 0;
6717       else
6718         break;
6719     }
6720
6721   if (rx_sw_if_index_set == 0)
6722     {
6723       errmsg ("missing rx interface name or rx_sw_if_index");
6724       return -99;
6725     }
6726
6727   if (enable && (tx_sw_if_index_set == 0))
6728     {
6729       errmsg ("missing tx interface name or tx_sw_if_index");
6730       return -99;
6731     }
6732
6733   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6734
6735   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6736   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6737   mp->enable = enable;
6738
6739   S (mp);
6740   W (ret);
6741   return ret;
6742 }
6743
6744 static int
6745 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_sw_interface_set_l2_bridge_t *mp;
6749   vl_api_l2_port_type_t port_type;
6750   u32 rx_sw_if_index;
6751   u8 rx_sw_if_index_set = 0;
6752   u32 bd_id;
6753   u8 bd_id_set = 0;
6754   u32 shg = 0;
6755   u8 enable = 1;
6756   int ret;
6757
6758   port_type = L2_API_PORT_TYPE_NORMAL;
6759
6760   /* Parse args required to build the message */
6761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6762     {
6763       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6764         rx_sw_if_index_set = 1;
6765       else if (unformat (i, "bd_id %d", &bd_id))
6766         bd_id_set = 1;
6767       else
6768         if (unformat
6769             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6770         rx_sw_if_index_set = 1;
6771       else if (unformat (i, "shg %d", &shg))
6772         ;
6773       else if (unformat (i, "bvi"))
6774         port_type = L2_API_PORT_TYPE_BVI;
6775       else if (unformat (i, "uu-fwd"))
6776         port_type = L2_API_PORT_TYPE_UU_FWD;
6777       else if (unformat (i, "enable"))
6778         enable = 1;
6779       else if (unformat (i, "disable"))
6780         enable = 0;
6781       else
6782         break;
6783     }
6784
6785   if (rx_sw_if_index_set == 0)
6786     {
6787       errmsg ("missing rx interface name or sw_if_index");
6788       return -99;
6789     }
6790
6791   if (enable && (bd_id_set == 0))
6792     {
6793       errmsg ("missing bridge domain");
6794       return -99;
6795     }
6796
6797   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6798
6799   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6800   mp->bd_id = ntohl (bd_id);
6801   mp->shg = (u8) shg;
6802   mp->port_type = ntohl (port_type);
6803   mp->enable = enable;
6804
6805   S (mp);
6806   W (ret);
6807   return ret;
6808 }
6809
6810 static int
6811 api_bridge_domain_dump (vat_main_t * vam)
6812 {
6813   unformat_input_t *i = vam->input;
6814   vl_api_bridge_domain_dump_t *mp;
6815   vl_api_control_ping_t *mp_ping;
6816   u32 bd_id = ~0;
6817   int ret;
6818
6819   /* Parse args required to build the message */
6820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6821     {
6822       if (unformat (i, "bd_id %d", &bd_id))
6823         ;
6824       else
6825         break;
6826     }
6827
6828   M (BRIDGE_DOMAIN_DUMP, mp);
6829   mp->bd_id = ntohl (bd_id);
6830   S (mp);
6831
6832   /* Use a control ping for synchronization */
6833   MPING (CONTROL_PING, mp_ping);
6834   S (mp_ping);
6835
6836   W (ret);
6837   return ret;
6838 }
6839
6840 static int
6841 api_bridge_domain_add_del (vat_main_t * vam)
6842 {
6843   unformat_input_t *i = vam->input;
6844   vl_api_bridge_domain_add_del_t *mp;
6845   u32 bd_id = ~0;
6846   u8 is_add = 1;
6847   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6848   u8 *bd_tag = NULL;
6849   u32 mac_age = 0;
6850   int ret;
6851
6852   /* Parse args required to build the message */
6853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6854     {
6855       if (unformat (i, "bd_id %d", &bd_id))
6856         ;
6857       else if (unformat (i, "flood %d", &flood))
6858         ;
6859       else if (unformat (i, "uu-flood %d", &uu_flood))
6860         ;
6861       else if (unformat (i, "forward %d", &forward))
6862         ;
6863       else if (unformat (i, "learn %d", &learn))
6864         ;
6865       else if (unformat (i, "arp-term %d", &arp_term))
6866         ;
6867       else if (unformat (i, "mac-age %d", &mac_age))
6868         ;
6869       else if (unformat (i, "bd-tag %s", &bd_tag))
6870         ;
6871       else if (unformat (i, "del"))
6872         {
6873           is_add = 0;
6874           flood = uu_flood = forward = learn = 0;
6875         }
6876       else
6877         break;
6878     }
6879
6880   if (bd_id == ~0)
6881     {
6882       errmsg ("missing bridge domain");
6883       ret = -99;
6884       goto done;
6885     }
6886
6887   if (mac_age > 255)
6888     {
6889       errmsg ("mac age must be less than 256 ");
6890       ret = -99;
6891       goto done;
6892     }
6893
6894   if ((bd_tag) && (vec_len (bd_tag) > 63))
6895     {
6896       errmsg ("bd-tag cannot be longer than 63");
6897       ret = -99;
6898       goto done;
6899     }
6900
6901   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6902
6903   mp->bd_id = ntohl (bd_id);
6904   mp->flood = flood;
6905   mp->uu_flood = uu_flood;
6906   mp->forward = forward;
6907   mp->learn = learn;
6908   mp->arp_term = arp_term;
6909   mp->is_add = is_add;
6910   mp->mac_age = (u8) mac_age;
6911   if (bd_tag)
6912     {
6913       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6914       mp->bd_tag[vec_len (bd_tag)] = 0;
6915     }
6916   S (mp);
6917   W (ret);
6918
6919 done:
6920   vec_free (bd_tag);
6921   return ret;
6922 }
6923
6924 static int
6925 api_l2fib_flush_bd (vat_main_t * vam)
6926 {
6927   unformat_input_t *i = vam->input;
6928   vl_api_l2fib_flush_bd_t *mp;
6929   u32 bd_id = ~0;
6930   int ret;
6931
6932   /* Parse args required to build the message */
6933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6934     {
6935       if (unformat (i, "bd_id %d", &bd_id));
6936       else
6937         break;
6938     }
6939
6940   if (bd_id == ~0)
6941     {
6942       errmsg ("missing bridge domain");
6943       return -99;
6944     }
6945
6946   M (L2FIB_FLUSH_BD, mp);
6947
6948   mp->bd_id = htonl (bd_id);
6949
6950   S (mp);
6951   W (ret);
6952   return ret;
6953 }
6954
6955 static int
6956 api_l2fib_flush_int (vat_main_t * vam)
6957 {
6958   unformat_input_t *i = vam->input;
6959   vl_api_l2fib_flush_int_t *mp;
6960   u32 sw_if_index = ~0;
6961   int ret;
6962
6963   /* Parse args required to build the message */
6964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6965     {
6966       if (unformat (i, "sw_if_index %d", &sw_if_index));
6967       else
6968         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6969       else
6970         break;
6971     }
6972
6973   if (sw_if_index == ~0)
6974     {
6975       errmsg ("missing interface name or sw_if_index");
6976       return -99;
6977     }
6978
6979   M (L2FIB_FLUSH_INT, mp);
6980
6981   mp->sw_if_index = ntohl (sw_if_index);
6982
6983   S (mp);
6984   W (ret);
6985   return ret;
6986 }
6987
6988 static int
6989 api_l2fib_add_del (vat_main_t * vam)
6990 {
6991   unformat_input_t *i = vam->input;
6992   vl_api_l2fib_add_del_t *mp;
6993   f64 timeout;
6994   u8 mac[6] = { 0 };
6995   u8 mac_set = 0;
6996   u32 bd_id;
6997   u8 bd_id_set = 0;
6998   u32 sw_if_index = 0;
6999   u8 sw_if_index_set = 0;
7000   u8 is_add = 1;
7001   u8 static_mac = 0;
7002   u8 filter_mac = 0;
7003   u8 bvi_mac = 0;
7004   int count = 1;
7005   f64 before = 0;
7006   int j;
7007
7008   /* Parse args required to build the message */
7009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7010     {
7011       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7012         mac_set = 1;
7013       else if (unformat (i, "bd_id %d", &bd_id))
7014         bd_id_set = 1;
7015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7016         sw_if_index_set = 1;
7017       else if (unformat (i, "sw_if"))
7018         {
7019           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020             {
7021               if (unformat
7022                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7023                 sw_if_index_set = 1;
7024             }
7025           else
7026             break;
7027         }
7028       else if (unformat (i, "static"))
7029         static_mac = 1;
7030       else if (unformat (i, "filter"))
7031         {
7032           filter_mac = 1;
7033           static_mac = 1;
7034         }
7035       else if (unformat (i, "bvi"))
7036         {
7037           bvi_mac = 1;
7038           static_mac = 1;
7039         }
7040       else if (unformat (i, "del"))
7041         is_add = 0;
7042       else if (unformat (i, "count %d", &count))
7043         ;
7044       else
7045         break;
7046     }
7047
7048   if (mac_set == 0)
7049     {
7050       errmsg ("missing mac address");
7051       return -99;
7052     }
7053
7054   if (bd_id_set == 0)
7055     {
7056       errmsg ("missing bridge domain");
7057       return -99;
7058     }
7059
7060   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7061     {
7062       errmsg ("missing interface name or sw_if_index");
7063       return -99;
7064     }
7065
7066   if (count > 1)
7067     {
7068       /* Turn on async mode */
7069       vam->async_mode = 1;
7070       vam->async_errors = 0;
7071       before = vat_time_now (vam);
7072     }
7073
7074   for (j = 0; j < count; j++)
7075     {
7076       M (L2FIB_ADD_DEL, mp);
7077
7078       clib_memcpy (mp->mac, mac, 6);
7079       mp->bd_id = ntohl (bd_id);
7080       mp->is_add = is_add;
7081       mp->sw_if_index = ntohl (sw_if_index);
7082
7083       if (is_add)
7084         {
7085           mp->static_mac = static_mac;
7086           mp->filter_mac = filter_mac;
7087           mp->bvi_mac = bvi_mac;
7088         }
7089       increment_mac_address (mac);
7090       /* send it... */
7091       S (mp);
7092     }
7093
7094   if (count > 1)
7095     {
7096       vl_api_control_ping_t *mp_ping;
7097       f64 after;
7098
7099       /* Shut off async mode */
7100       vam->async_mode = 0;
7101
7102       MPING (CONTROL_PING, mp_ping);
7103       S (mp_ping);
7104
7105       timeout = vat_time_now (vam) + 1.0;
7106       while (vat_time_now (vam) < timeout)
7107         if (vam->result_ready == 1)
7108           goto out;
7109       vam->retval = -99;
7110
7111     out:
7112       if (vam->retval == -99)
7113         errmsg ("timeout");
7114
7115       if (vam->async_errors > 0)
7116         {
7117           errmsg ("%d asynchronous errors", vam->async_errors);
7118           vam->retval = -98;
7119         }
7120       vam->async_errors = 0;
7121       after = vat_time_now (vam);
7122
7123       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7124              count, after - before, count / (after - before));
7125     }
7126   else
7127     {
7128       int ret;
7129
7130       /* Wait for a reply... */
7131       W (ret);
7132       return ret;
7133     }
7134   /* Return the good/bad news */
7135   return (vam->retval);
7136 }
7137
7138 static int
7139 api_bridge_domain_set_mac_age (vat_main_t * vam)
7140 {
7141   unformat_input_t *i = vam->input;
7142   vl_api_bridge_domain_set_mac_age_t *mp;
7143   u32 bd_id = ~0;
7144   u32 mac_age = 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, "bd_id %d", &bd_id));
7151       else if (unformat (i, "mac-age %d", &mac_age));
7152       else
7153         break;
7154     }
7155
7156   if (bd_id == ~0)
7157     {
7158       errmsg ("missing bridge domain");
7159       return -99;
7160     }
7161
7162   if (mac_age > 255)
7163     {
7164       errmsg ("mac age must be less than 256 ");
7165       return -99;
7166     }
7167
7168   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7169
7170   mp->bd_id = htonl (bd_id);
7171   mp->mac_age = (u8) mac_age;
7172
7173   S (mp);
7174   W (ret);
7175   return ret;
7176 }
7177
7178 static int
7179 api_l2_flags (vat_main_t * vam)
7180 {
7181   unformat_input_t *i = vam->input;
7182   vl_api_l2_flags_t *mp;
7183   u32 sw_if_index;
7184   u32 flags = 0;
7185   u8 sw_if_index_set = 0;
7186   u8 is_set = 0;
7187   int ret;
7188
7189   /* Parse args required to build the message */
7190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7191     {
7192       if (unformat (i, "sw_if_index %d", &sw_if_index))
7193         sw_if_index_set = 1;
7194       else if (unformat (i, "sw_if"))
7195         {
7196           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7197             {
7198               if (unformat
7199                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7200                 sw_if_index_set = 1;
7201             }
7202           else
7203             break;
7204         }
7205       else if (unformat (i, "learn"))
7206         flags |= L2_LEARN;
7207       else if (unformat (i, "forward"))
7208         flags |= L2_FWD;
7209       else if (unformat (i, "flood"))
7210         flags |= L2_FLOOD;
7211       else if (unformat (i, "uu-flood"))
7212         flags |= L2_UU_FLOOD;
7213       else if (unformat (i, "arp-term"))
7214         flags |= L2_ARP_TERM;
7215       else if (unformat (i, "off"))
7216         is_set = 0;
7217       else if (unformat (i, "disable"))
7218         is_set = 0;
7219       else
7220         break;
7221     }
7222
7223   if (sw_if_index_set == 0)
7224     {
7225       errmsg ("missing interface name or sw_if_index");
7226       return -99;
7227     }
7228
7229   M (L2_FLAGS, mp);
7230
7231   mp->sw_if_index = ntohl (sw_if_index);
7232   mp->feature_bitmap = ntohl (flags);
7233   mp->is_set = is_set;
7234
7235   S (mp);
7236   W (ret);
7237   return ret;
7238 }
7239
7240 static int
7241 api_bridge_flags (vat_main_t * vam)
7242 {
7243   unformat_input_t *i = vam->input;
7244   vl_api_bridge_flags_t *mp;
7245   u32 bd_id;
7246   u8 bd_id_set = 0;
7247   u8 is_set = 1;
7248   bd_flags_t flags = 0;
7249   int ret;
7250
7251   /* Parse args required to build the message */
7252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7253     {
7254       if (unformat (i, "bd_id %d", &bd_id))
7255         bd_id_set = 1;
7256       else if (unformat (i, "learn"))
7257         flags |= BRIDGE_API_FLAG_LEARN;
7258       else if (unformat (i, "forward"))
7259         flags |= BRIDGE_API_FLAG_FWD;
7260       else if (unformat (i, "flood"))
7261         flags |= BRIDGE_API_FLAG_FLOOD;
7262       else if (unformat (i, "uu-flood"))
7263         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7264       else if (unformat (i, "arp-term"))
7265         flags |= BRIDGE_API_FLAG_ARP_TERM;
7266       else if (unformat (i, "off"))
7267         is_set = 0;
7268       else if (unformat (i, "disable"))
7269         is_set = 0;
7270       else
7271         break;
7272     }
7273
7274   if (bd_id_set == 0)
7275     {
7276       errmsg ("missing bridge domain");
7277       return -99;
7278     }
7279
7280   M (BRIDGE_FLAGS, mp);
7281
7282   mp->bd_id = ntohl (bd_id);
7283   mp->flags = ntohl (flags);
7284   mp->is_set = is_set;
7285
7286   S (mp);
7287   W (ret);
7288   return ret;
7289 }
7290
7291 static int
7292 api_bd_ip_mac_add_del (vat_main_t * vam)
7293 {
7294   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7295   vl_api_mac_address_t mac = { 0 };
7296   unformat_input_t *i = vam->input;
7297   vl_api_bd_ip_mac_add_del_t *mp;
7298   ip46_type_t type;
7299   u32 bd_id;
7300   u8 is_ipv6 = 0;
7301   u8 is_add = 1;
7302   u8 bd_id_set = 0;
7303   u8 ip_set = 0;
7304   u8 mac_set = 0;
7305   u8 macaddr[6];
7306   int ret;
7307
7308
7309   /* Parse args required to build the message */
7310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7311     {
7312       if (unformat (i, "bd_id %d", &bd_id))
7313         {
7314           bd_id_set++;
7315         }
7316       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7317         {
7318           ip_set++;
7319         }
7320       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7321         {
7322           mac_set++;
7323         }
7324       else if (unformat (i, "del"))
7325         is_add = 0;
7326       else
7327         break;
7328     }
7329
7330   if (bd_id_set == 0)
7331     {
7332       errmsg ("missing bridge domain");
7333       return -99;
7334     }
7335   else if (ip_set == 0)
7336     {
7337       errmsg ("missing IP address");
7338       return -99;
7339     }
7340   else if (mac_set == 0)
7341     {
7342       errmsg ("missing MAC address");
7343       return -99;
7344     }
7345
7346   M (BD_IP_MAC_ADD_DEL, mp);
7347
7348   mp->bd_id = ntohl (bd_id);
7349   mp->is_add = is_add;
7350
7351   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7352   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7353
7354   S (mp);
7355   W (ret);
7356   return ret;
7357 }
7358
7359 static int
7360 api_bd_ip_mac_flush (vat_main_t * vam)
7361 {
7362   unformat_input_t *i = vam->input;
7363   vl_api_bd_ip_mac_flush_t *mp;
7364   u32 bd_id;
7365   u8 bd_id_set = 0;
7366   int ret;
7367
7368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7369     {
7370       if (unformat (i, "bd_id %d", &bd_id))
7371         {
7372           bd_id_set++;
7373         }
7374       else
7375         break;
7376     }
7377
7378   if (bd_id_set == 0)
7379     {
7380       errmsg ("missing bridge domain");
7381       return -99;
7382     }
7383
7384   M (BD_IP_MAC_FLUSH, mp);
7385
7386   mp->bd_id = ntohl (bd_id);
7387
7388   S (mp);
7389   W (ret);
7390   return ret;
7391 }
7392
7393 static void vl_api_bd_ip_mac_details_t_handler
7394   (vl_api_bd_ip_mac_details_t * mp)
7395 {
7396   vat_main_t *vam = &vat_main;
7397   u8 *ip = 0;
7398
7399   if (!mp->is_ipv6)
7400     ip =
7401       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7402   else
7403     ip =
7404       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7405
7406   print (vam->ofp,
7407          "\n%-5d %-7s %-20U %-30s",
7408          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7409          format_ethernet_address, mp->mac_address, ip);
7410
7411   vec_free (ip);
7412 }
7413
7414 static void vl_api_bd_ip_mac_details_t_handler_json
7415   (vl_api_bd_ip_mac_details_t * mp)
7416 {
7417   vat_main_t *vam = &vat_main;
7418   vat_json_node_t *node = NULL;
7419
7420   if (VAT_JSON_ARRAY != vam->json_tree.type)
7421     {
7422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7423       vat_json_init_array (&vam->json_tree);
7424     }
7425   node = vat_json_array_add (&vam->json_tree);
7426
7427   vat_json_init_object (node);
7428   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7429   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7430   vat_json_object_add_string_copy (node, "mac_address",
7431                                    format (0, "%U", format_ethernet_address,
7432                                            &mp->mac_address));
7433   u8 *ip = 0;
7434
7435   if (!mp->is_ipv6)
7436     ip =
7437       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7438   else
7439     ip =
7440       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7441   vat_json_object_add_string_copy (node, "ip_address", ip);
7442   vec_free (ip);
7443 }
7444
7445 static int
7446 api_bd_ip_mac_dump (vat_main_t * vam)
7447 {
7448   unformat_input_t *i = vam->input;
7449   vl_api_bd_ip_mac_dump_t *mp;
7450   vl_api_control_ping_t *mp_ping;
7451   int ret;
7452   u32 bd_id;
7453   u8 bd_id_set = 0;
7454
7455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7456     {
7457       if (unformat (i, "bd_id %d", &bd_id))
7458         {
7459           bd_id_set++;
7460         }
7461       else
7462         break;
7463     }
7464
7465   print (vam->ofp,
7466          "\n%-5s %-7s %-20s %-30s",
7467          "bd_id", "is_ipv6", "mac_address", "ip_address");
7468
7469   /* Dump Bridge Domain Ip to Mac entries */
7470   M (BD_IP_MAC_DUMP, mp);
7471
7472   if (bd_id_set)
7473     mp->bd_id = htonl (bd_id);
7474   else
7475     mp->bd_id = ~0;
7476
7477   S (mp);
7478
7479   /* Use a control ping for synchronization */
7480   MPING (CONTROL_PING, mp_ping);
7481   S (mp_ping);
7482
7483   W (ret);
7484   return ret;
7485 }
7486
7487 static int
7488 api_tap_create_v2 (vat_main_t * vam)
7489 {
7490   unformat_input_t *i = vam->input;
7491   vl_api_tap_create_v2_t *mp;
7492   u8 mac_address[6];
7493   u8 random_mac = 1;
7494   u32 id = ~0;
7495   u8 *host_if_name = 0;
7496   u8 *host_ns = 0;
7497   u8 host_mac_addr[6];
7498   u8 host_mac_addr_set = 0;
7499   u8 *host_bridge = 0;
7500   ip4_address_t host_ip4_addr;
7501   ip4_address_t host_ip4_gw;
7502   u8 host_ip4_gw_set = 0;
7503   u32 host_ip4_prefix_len = 0;
7504   ip6_address_t host_ip6_addr;
7505   ip6_address_t host_ip6_gw;
7506   u8 host_ip6_gw_set = 0;
7507   u32 host_ip6_prefix_len = 0;
7508   int ret;
7509   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7510
7511   clib_memset (mac_address, 0, sizeof (mac_address));
7512
7513   /* Parse args required to build the message */
7514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7515     {
7516       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7517         {
7518           random_mac = 0;
7519         }
7520       else if (unformat (i, "id %u", &id))
7521         ;
7522       else if (unformat (i, "host-if-name %s", &host_if_name))
7523         ;
7524       else if (unformat (i, "host-ns %s", &host_ns))
7525         ;
7526       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7527                          host_mac_addr))
7528         host_mac_addr_set = 1;
7529       else if (unformat (i, "host-bridge %s", &host_bridge))
7530         ;
7531       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7532                          &host_ip4_addr, &host_ip4_prefix_len))
7533         ;
7534       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7535                          &host_ip6_addr, &host_ip6_prefix_len))
7536         ;
7537       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7538                          &host_ip4_gw))
7539         host_ip4_gw_set = 1;
7540       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7541                          &host_ip6_gw))
7542         host_ip6_gw_set = 1;
7543       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7544         ;
7545       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7546         ;
7547       else
7548         break;
7549     }
7550
7551   if (vec_len (host_if_name) > 63)
7552     {
7553       errmsg ("tap name too long. ");
7554       return -99;
7555     }
7556   if (vec_len (host_ns) > 63)
7557     {
7558       errmsg ("host name space too long. ");
7559       return -99;
7560     }
7561   if (vec_len (host_bridge) > 63)
7562     {
7563       errmsg ("host bridge name too long. ");
7564       return -99;
7565     }
7566   if (host_ip4_prefix_len > 32)
7567     {
7568       errmsg ("host ip4 prefix length not valid. ");
7569       return -99;
7570     }
7571   if (host_ip6_prefix_len > 128)
7572     {
7573       errmsg ("host ip6 prefix length not valid. ");
7574       return -99;
7575     }
7576   if (!is_pow2 (rx_ring_sz))
7577     {
7578       errmsg ("rx ring size must be power of 2. ");
7579       return -99;
7580     }
7581   if (rx_ring_sz > 32768)
7582     {
7583       errmsg ("rx ring size must be 32768 or lower. ");
7584       return -99;
7585     }
7586   if (!is_pow2 (tx_ring_sz))
7587     {
7588       errmsg ("tx ring size must be power of 2. ");
7589       return -99;
7590     }
7591   if (tx_ring_sz > 32768)
7592     {
7593       errmsg ("tx ring size must be 32768 or lower. ");
7594       return -99;
7595     }
7596
7597   /* Construct the API message */
7598   M (TAP_CREATE_V2, mp);
7599
7600   mp->use_random_mac = random_mac;
7601
7602   mp->id = ntohl (id);
7603   mp->host_namespace_set = host_ns != 0;
7604   mp->host_bridge_set = host_bridge != 0;
7605   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7606   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7607   mp->rx_ring_sz = ntohs (rx_ring_sz);
7608   mp->tx_ring_sz = ntohs (tx_ring_sz);
7609
7610   if (random_mac == 0)
7611     clib_memcpy (mp->mac_address, mac_address, 6);
7612   if (host_mac_addr_set)
7613     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7614   if (host_if_name)
7615     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7616   if (host_ns)
7617     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7618   if (host_bridge)
7619     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7620   if (host_ip4_prefix_len)
7621     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7622   if (host_ip6_prefix_len)
7623     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7624   if (host_ip4_gw_set)
7625     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7626   if (host_ip6_gw_set)
7627     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7628
7629   vec_free (host_ns);
7630   vec_free (host_if_name);
7631   vec_free (host_bridge);
7632
7633   /* send it... */
7634   S (mp);
7635
7636   /* Wait for a reply... */
7637   W (ret);
7638   return ret;
7639 }
7640
7641 static int
7642 api_tap_delete_v2 (vat_main_t * vam)
7643 {
7644   unformat_input_t *i = vam->input;
7645   vl_api_tap_delete_v2_t *mp;
7646   u32 sw_if_index = ~0;
7647   u8 sw_if_index_set = 0;
7648   int ret;
7649
7650   /* Parse args required to build the message */
7651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7652     {
7653       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7654         sw_if_index_set = 1;
7655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7656         sw_if_index_set = 1;
7657       else
7658         break;
7659     }
7660
7661   if (sw_if_index_set == 0)
7662     {
7663       errmsg ("missing vpp interface name. ");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (TAP_DELETE_V2, mp);
7669
7670   mp->sw_if_index = ntohl (sw_if_index);
7671
7672   /* send it... */
7673   S (mp);
7674
7675   /* Wait for a reply... */
7676   W (ret);
7677   return ret;
7678 }
7679
7680 uword
7681 unformat_pci_addr (unformat_input_t * input, va_list * args)
7682 {
7683   struct pci_addr_t
7684   {
7685     u16 domain;
7686     u8 bus;
7687     u8 slot:5;
7688     u8 function:3;
7689   } *addr;
7690   addr = va_arg (*args, struct pci_addr_t *);
7691   u32 x[4];
7692
7693   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7694     return 0;
7695
7696   addr->domain = x[0];
7697   addr->bus = x[1];
7698   addr->slot = x[2];
7699   addr->function = x[3];
7700
7701   return 1;
7702 }
7703
7704 static int
7705 api_virtio_pci_create (vat_main_t * vam)
7706 {
7707   unformat_input_t *i = vam->input;
7708   vl_api_virtio_pci_create_t *mp;
7709   u8 mac_address[6];
7710   u8 random_mac = 1;
7711   u32 pci_addr = 0;
7712   u64 features = (u64) ~ (0ULL);
7713   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7714   int ret;
7715
7716   clib_memset (mac_address, 0, sizeof (mac_address));
7717
7718   /* Parse args required to build the message */
7719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7720     {
7721       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7722         {
7723           random_mac = 0;
7724         }
7725       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7726         ;
7727       else if (unformat (i, "features 0x%llx", &features))
7728         ;
7729       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7730         ;
7731       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7732         ;
7733       else
7734         break;
7735     }
7736
7737   if (pci_addr == 0)
7738     {
7739       errmsg ("pci address must be non zero. ");
7740       return -99;
7741     }
7742   if (!is_pow2 (rx_ring_sz))
7743     {
7744       errmsg ("rx ring size must be power of 2. ");
7745       return -99;
7746     }
7747   if (rx_ring_sz > 32768)
7748     {
7749       errmsg ("rx ring size must be 32768 or lower. ");
7750       return -99;
7751     }
7752   if (!is_pow2 (tx_ring_sz))
7753     {
7754       errmsg ("tx ring size must be power of 2. ");
7755       return -99;
7756     }
7757   if (tx_ring_sz > 32768)
7758     {
7759       errmsg ("tx ring size must be 32768 or lower. ");
7760       return -99;
7761     }
7762
7763   /* Construct the API message */
7764   M (VIRTIO_PCI_CREATE, mp);
7765
7766   mp->use_random_mac = random_mac;
7767
7768   mp->pci_addr = htonl (pci_addr);
7769   mp->features = clib_host_to_net_u64 (features);
7770   mp->rx_ring_sz = htons (rx_ring_sz);
7771   mp->tx_ring_sz = htons (tx_ring_sz);
7772
7773   if (random_mac == 0)
7774     clib_memcpy (mp->mac_address, mac_address, 6);
7775
7776   /* send it... */
7777   S (mp);
7778
7779   /* Wait for a reply... */
7780   W (ret);
7781   return ret;
7782 }
7783
7784 static int
7785 api_virtio_pci_delete (vat_main_t * vam)
7786 {
7787   unformat_input_t *i = vam->input;
7788   vl_api_virtio_pci_delete_t *mp;
7789   u32 sw_if_index = ~0;
7790   u8 sw_if_index_set = 0;
7791   int ret;
7792
7793   /* Parse args required to build the message */
7794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7795     {
7796       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7797         sw_if_index_set = 1;
7798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7799         sw_if_index_set = 1;
7800       else
7801         break;
7802     }
7803
7804   if (sw_if_index_set == 0)
7805     {
7806       errmsg ("missing vpp interface name. ");
7807       return -99;
7808     }
7809
7810   /* Construct the API message */
7811   M (VIRTIO_PCI_DELETE, mp);
7812
7813   mp->sw_if_index = htonl (sw_if_index);
7814
7815   /* send it... */
7816   S (mp);
7817
7818   /* Wait for a reply... */
7819   W (ret);
7820   return ret;
7821 }
7822
7823 static int
7824 api_bond_create (vat_main_t * vam)
7825 {
7826   unformat_input_t *i = vam->input;
7827   vl_api_bond_create_t *mp;
7828   u8 mac_address[6];
7829   u8 custom_mac = 0;
7830   int ret;
7831   u8 mode;
7832   u8 lb;
7833   u8 mode_is_set = 0;
7834   u32 id = ~0;
7835
7836   clib_memset (mac_address, 0, sizeof (mac_address));
7837   lb = BOND_LB_L2;
7838
7839   /* Parse args required to build the message */
7840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7841     {
7842       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7843         mode_is_set = 1;
7844       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7845                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7846         ;
7847       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7848                          mac_address))
7849         custom_mac = 1;
7850       else if (unformat (i, "id %u", &id))
7851         ;
7852       else
7853         break;
7854     }
7855
7856   if (mode_is_set == 0)
7857     {
7858       errmsg ("Missing bond mode. ");
7859       return -99;
7860     }
7861
7862   /* Construct the API message */
7863   M (BOND_CREATE, mp);
7864
7865   mp->use_custom_mac = custom_mac;
7866
7867   mp->mode = mode;
7868   mp->lb = lb;
7869   mp->id = htonl (id);
7870
7871   if (custom_mac)
7872     clib_memcpy (mp->mac_address, mac_address, 6);
7873
7874   /* send it... */
7875   S (mp);
7876
7877   /* Wait for a reply... */
7878   W (ret);
7879   return ret;
7880 }
7881
7882 static int
7883 api_bond_delete (vat_main_t * vam)
7884 {
7885   unformat_input_t *i = vam->input;
7886   vl_api_bond_delete_t *mp;
7887   u32 sw_if_index = ~0;
7888   u8 sw_if_index_set = 0;
7889   int ret;
7890
7891   /* Parse args required to build the message */
7892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7893     {
7894       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7895         sw_if_index_set = 1;
7896       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7897         sw_if_index_set = 1;
7898       else
7899         break;
7900     }
7901
7902   if (sw_if_index_set == 0)
7903     {
7904       errmsg ("missing vpp interface name. ");
7905       return -99;
7906     }
7907
7908   /* Construct the API message */
7909   M (BOND_DELETE, mp);
7910
7911   mp->sw_if_index = ntohl (sw_if_index);
7912
7913   /* send it... */
7914   S (mp);
7915
7916   /* Wait for a reply... */
7917   W (ret);
7918   return ret;
7919 }
7920
7921 static int
7922 api_bond_enslave (vat_main_t * vam)
7923 {
7924   unformat_input_t *i = vam->input;
7925   vl_api_bond_enslave_t *mp;
7926   u32 bond_sw_if_index;
7927   int ret;
7928   u8 is_passive;
7929   u8 is_long_timeout;
7930   u32 bond_sw_if_index_is_set = 0;
7931   u32 sw_if_index;
7932   u8 sw_if_index_is_set = 0;
7933
7934   /* Parse args required to build the message */
7935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7936     {
7937       if (unformat (i, "sw_if_index %d", &sw_if_index))
7938         sw_if_index_is_set = 1;
7939       else if (unformat (i, "bond %u", &bond_sw_if_index))
7940         bond_sw_if_index_is_set = 1;
7941       else if (unformat (i, "passive %d", &is_passive))
7942         ;
7943       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7944         ;
7945       else
7946         break;
7947     }
7948
7949   if (bond_sw_if_index_is_set == 0)
7950     {
7951       errmsg ("Missing bond sw_if_index. ");
7952       return -99;
7953     }
7954   if (sw_if_index_is_set == 0)
7955     {
7956       errmsg ("Missing slave sw_if_index. ");
7957       return -99;
7958     }
7959
7960   /* Construct the API message */
7961   M (BOND_ENSLAVE, mp);
7962
7963   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7964   mp->sw_if_index = ntohl (sw_if_index);
7965   mp->is_long_timeout = is_long_timeout;
7966   mp->is_passive = is_passive;
7967
7968   /* send it... */
7969   S (mp);
7970
7971   /* Wait for a reply... */
7972   W (ret);
7973   return ret;
7974 }
7975
7976 static int
7977 api_bond_detach_slave (vat_main_t * vam)
7978 {
7979   unformat_input_t *i = vam->input;
7980   vl_api_bond_detach_slave_t *mp;
7981   u32 sw_if_index = ~0;
7982   u8 sw_if_index_set = 0;
7983   int ret;
7984
7985   /* Parse args required to build the message */
7986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7987     {
7988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7989         sw_if_index_set = 1;
7990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7991         sw_if_index_set = 1;
7992       else
7993         break;
7994     }
7995
7996   if (sw_if_index_set == 0)
7997     {
7998       errmsg ("missing vpp interface name. ");
7999       return -99;
8000     }
8001
8002   /* Construct the API message */
8003   M (BOND_DETACH_SLAVE, mp);
8004
8005   mp->sw_if_index = ntohl (sw_if_index);
8006
8007   /* send it... */
8008   S (mp);
8009
8010   /* Wait for a reply... */
8011   W (ret);
8012   return ret;
8013 }
8014
8015 static int
8016 api_ip_table_add_del (vat_main_t * vam)
8017 {
8018   unformat_input_t *i = vam->input;
8019   vl_api_ip_table_add_del_t *mp;
8020   u32 table_id = ~0;
8021   u8 is_ipv6 = 0;
8022   u8 is_add = 1;
8023   int ret = 0;
8024
8025   /* Parse args required to build the message */
8026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8027     {
8028       if (unformat (i, "ipv6"))
8029         is_ipv6 = 1;
8030       else if (unformat (i, "del"))
8031         is_add = 0;
8032       else if (unformat (i, "add"))
8033         is_add = 1;
8034       else if (unformat (i, "table %d", &table_id))
8035         ;
8036       else
8037         {
8038           clib_warning ("parse error '%U'", format_unformat_error, i);
8039           return -99;
8040         }
8041     }
8042
8043   if (~0 == table_id)
8044     {
8045       errmsg ("missing table-ID");
8046       return -99;
8047     }
8048
8049   /* Construct the API message */
8050   M (IP_TABLE_ADD_DEL, mp);
8051
8052   mp->table_id = ntohl (table_id);
8053   mp->is_ipv6 = is_ipv6;
8054   mp->is_add = is_add;
8055
8056   /* send it... */
8057   S (mp);
8058
8059   /* Wait for a reply... */
8060   W (ret);
8061
8062   return ret;
8063 }
8064
8065 static int
8066 api_ip_add_del_route (vat_main_t * vam)
8067 {
8068   unformat_input_t *i = vam->input;
8069   vl_api_ip_add_del_route_t *mp;
8070   u32 sw_if_index = ~0, vrf_id = 0;
8071   u8 is_ipv6 = 0;
8072   u8 is_local = 0, is_drop = 0;
8073   u8 is_unreach = 0, is_prohibit = 0;
8074   u8 is_add = 1;
8075   u32 next_hop_weight = 1;
8076   u8 is_multipath = 0;
8077   u8 address_set = 0;
8078   u8 address_length_set = 0;
8079   u32 next_hop_table_id = 0;
8080   u32 resolve_attempts = 0;
8081   u32 dst_address_length = 0;
8082   u8 next_hop_set = 0;
8083   ip4_address_t v4_dst_address, v4_next_hop_address;
8084   ip6_address_t v6_dst_address, v6_next_hop_address;
8085   int count = 1;
8086   int j;
8087   f64 before = 0;
8088   u32 random_add_del = 0;
8089   u32 *random_vector = 0;
8090   uword *random_hash;
8091   u32 random_seed = 0xdeaddabe;
8092   u32 classify_table_index = ~0;
8093   u8 is_classify = 0;
8094   u8 resolve_host = 0, resolve_attached = 0;
8095   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8096   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8097   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8098
8099   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8100   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8101   /* Parse args required to build the message */
8102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8103     {
8104       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8105         ;
8106       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8107         ;
8108       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8109         {
8110           address_set = 1;
8111           is_ipv6 = 0;
8112         }
8113       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8114         {
8115           address_set = 1;
8116           is_ipv6 = 1;
8117         }
8118       else if (unformat (i, "/%d", &dst_address_length))
8119         {
8120           address_length_set = 1;
8121         }
8122
8123       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8124                                          &v4_next_hop_address))
8125         {
8126           next_hop_set = 1;
8127         }
8128       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8129                                          &v6_next_hop_address))
8130         {
8131           next_hop_set = 1;
8132         }
8133       else
8134         if (unformat
8135             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8136         {
8137           next_hop_set = 1;
8138         }
8139       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8140         {
8141           next_hop_set = 1;
8142         }
8143       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8144         ;
8145       else if (unformat (i, "weight %d", &next_hop_weight))
8146         ;
8147       else if (unformat (i, "drop"))
8148         {
8149           is_drop = 1;
8150         }
8151       else if (unformat (i, "null-send-unreach"))
8152         {
8153           is_unreach = 1;
8154         }
8155       else if (unformat (i, "null-send-prohibit"))
8156         {
8157           is_prohibit = 1;
8158         }
8159       else if (unformat (i, "local"))
8160         {
8161           is_local = 1;
8162         }
8163       else if (unformat (i, "classify %d", &classify_table_index))
8164         {
8165           is_classify = 1;
8166         }
8167       else if (unformat (i, "del"))
8168         is_add = 0;
8169       else if (unformat (i, "add"))
8170         is_add = 1;
8171       else if (unformat (i, "resolve-via-host"))
8172         resolve_host = 1;
8173       else if (unformat (i, "resolve-via-attached"))
8174         resolve_attached = 1;
8175       else if (unformat (i, "multipath"))
8176         is_multipath = 1;
8177       else if (unformat (i, "vrf %d", &vrf_id))
8178         ;
8179       else if (unformat (i, "count %d", &count))
8180         ;
8181       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8182         ;
8183       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8184         ;
8185       else if (unformat (i, "out-label %d", &next_hop_out_label))
8186         {
8187           vl_api_fib_mpls_label_t fib_label = {
8188             .label = ntohl (next_hop_out_label),
8189             .ttl = 64,
8190             .exp = 0,
8191           };
8192           vec_add1 (next_hop_out_label_stack, fib_label);
8193         }
8194       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8195         ;
8196       else if (unformat (i, "random"))
8197         random_add_del = 1;
8198       else if (unformat (i, "seed %d", &random_seed))
8199         ;
8200       else
8201         {
8202           clib_warning ("parse error '%U'", format_unformat_error, i);
8203           return -99;
8204         }
8205     }
8206
8207   if (!next_hop_set && !is_drop && !is_local &&
8208       !is_classify && !is_unreach && !is_prohibit &&
8209       MPLS_LABEL_INVALID == next_hop_via_label)
8210     {
8211       errmsg
8212         ("next hop / local / drop / unreach / prohibit / classify not set");
8213       return -99;
8214     }
8215
8216   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8217     {
8218       errmsg ("next hop and next-hop via label set");
8219       return -99;
8220     }
8221   if (address_set == 0)
8222     {
8223       errmsg ("missing addresses");
8224       return -99;
8225     }
8226
8227   if (address_length_set == 0)
8228     {
8229       errmsg ("missing address length");
8230       return -99;
8231     }
8232
8233   /* Generate a pile of unique, random routes */
8234   if (random_add_del)
8235     {
8236       u32 this_random_address;
8237       random_hash = hash_create (count, sizeof (uword));
8238
8239       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8240       for (j = 0; j <= count; j++)
8241         {
8242           do
8243             {
8244               this_random_address = random_u32 (&random_seed);
8245               this_random_address =
8246                 clib_host_to_net_u32 (this_random_address);
8247             }
8248           while (hash_get (random_hash, this_random_address));
8249           vec_add1 (random_vector, this_random_address);
8250           hash_set (random_hash, this_random_address, 1);
8251         }
8252       hash_free (random_hash);
8253       v4_dst_address.as_u32 = random_vector[0];
8254     }
8255
8256   if (count > 1)
8257     {
8258       /* Turn on async mode */
8259       vam->async_mode = 1;
8260       vam->async_errors = 0;
8261       before = vat_time_now (vam);
8262     }
8263
8264   for (j = 0; j < count; j++)
8265     {
8266       /* Construct the API message */
8267       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8268           vec_len (next_hop_out_label_stack));
8269
8270       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8271       mp->table_id = ntohl (vrf_id);
8272
8273       mp->is_add = is_add;
8274       mp->is_drop = is_drop;
8275       mp->is_unreach = is_unreach;
8276       mp->is_prohibit = is_prohibit;
8277       mp->is_ipv6 = is_ipv6;
8278       mp->is_local = is_local;
8279       mp->is_classify = is_classify;
8280       mp->is_multipath = is_multipath;
8281       mp->is_resolve_host = resolve_host;
8282       mp->is_resolve_attached = resolve_attached;
8283       mp->next_hop_weight = next_hop_weight;
8284       mp->next_hop_preference = 0;
8285       mp->dst_address_length = dst_address_length;
8286       mp->next_hop_table_id = ntohl (next_hop_table_id);
8287       mp->classify_table_index = ntohl (classify_table_index);
8288       mp->next_hop_via_label = ntohl (next_hop_via_label);
8289       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8290       if (0 != mp->next_hop_n_out_labels)
8291         {
8292           memcpy (mp->next_hop_out_label_stack,
8293                   next_hop_out_label_stack,
8294                   (vec_len (next_hop_out_label_stack) *
8295                    sizeof (vl_api_fib_mpls_label_t)));
8296           vec_free (next_hop_out_label_stack);
8297         }
8298
8299       if (is_ipv6)
8300         {
8301           clib_memcpy (mp->dst_address, &v6_dst_address,
8302                        sizeof (v6_dst_address));
8303           if (next_hop_set)
8304             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8305                          sizeof (v6_next_hop_address));
8306           increment_v6_address (&v6_dst_address);
8307         }
8308       else
8309         {
8310           clib_memcpy (mp->dst_address, &v4_dst_address,
8311                        sizeof (v4_dst_address));
8312           if (next_hop_set)
8313             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8314                          sizeof (v4_next_hop_address));
8315           if (random_add_del)
8316             v4_dst_address.as_u32 = random_vector[j + 1];
8317           else
8318             increment_v4_address (&v4_dst_address);
8319         }
8320       /* send it... */
8321       S (mp);
8322       /* If we receive SIGTERM, stop now... */
8323       if (vam->do_exit)
8324         break;
8325     }
8326
8327   /* When testing multiple add/del ops, use a control-ping to sync */
8328   if (count > 1)
8329     {
8330       vl_api_control_ping_t *mp_ping;
8331       f64 after;
8332       f64 timeout;
8333
8334       /* Shut off async mode */
8335       vam->async_mode = 0;
8336
8337       MPING (CONTROL_PING, mp_ping);
8338       S (mp_ping);
8339
8340       timeout = vat_time_now (vam) + 1.0;
8341       while (vat_time_now (vam) < timeout)
8342         if (vam->result_ready == 1)
8343           goto out;
8344       vam->retval = -99;
8345
8346     out:
8347       if (vam->retval == -99)
8348         errmsg ("timeout");
8349
8350       if (vam->async_errors > 0)
8351         {
8352           errmsg ("%d asynchronous errors", vam->async_errors);
8353           vam->retval = -98;
8354         }
8355       vam->async_errors = 0;
8356       after = vat_time_now (vam);
8357
8358       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8359       if (j > 0)
8360         count = j;
8361
8362       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8363              count, after - before, count / (after - before));
8364     }
8365   else
8366     {
8367       int ret;
8368
8369       /* Wait for a reply... */
8370       W (ret);
8371       return ret;
8372     }
8373
8374   /* Return the good/bad news */
8375   return (vam->retval);
8376 }
8377
8378 static int
8379 api_ip_mroute_add_del (vat_main_t * vam)
8380 {
8381   unformat_input_t *i = vam->input;
8382   vl_api_ip_mroute_add_del_t *mp;
8383   u32 sw_if_index = ~0, vrf_id = 0;
8384   u8 is_ipv6 = 0;
8385   u8 is_local = 0;
8386   u8 is_add = 1;
8387   u8 address_set = 0;
8388   u32 grp_address_length = 0;
8389   ip4_address_t v4_grp_address, v4_src_address;
8390   ip6_address_t v6_grp_address, v6_src_address;
8391   mfib_itf_flags_t iflags = 0;
8392   mfib_entry_flags_t eflags = 0;
8393   int ret;
8394
8395   /* Parse args required to build the message */
8396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8397     {
8398       if (unformat (i, "sw_if_index %d", &sw_if_index))
8399         ;
8400       else if (unformat (i, "%U %U",
8401                          unformat_ip4_address, &v4_src_address,
8402                          unformat_ip4_address, &v4_grp_address))
8403         {
8404           grp_address_length = 64;
8405           address_set = 1;
8406           is_ipv6 = 0;
8407         }
8408       else if (unformat (i, "%U %U",
8409                          unformat_ip6_address, &v6_src_address,
8410                          unformat_ip6_address, &v6_grp_address))
8411         {
8412           grp_address_length = 256;
8413           address_set = 1;
8414           is_ipv6 = 1;
8415         }
8416       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8417         {
8418           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8419           grp_address_length = 32;
8420           address_set = 1;
8421           is_ipv6 = 0;
8422         }
8423       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8424         {
8425           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8426           grp_address_length = 128;
8427           address_set = 1;
8428           is_ipv6 = 1;
8429         }
8430       else if (unformat (i, "/%d", &grp_address_length))
8431         ;
8432       else if (unformat (i, "local"))
8433         {
8434           is_local = 1;
8435         }
8436       else if (unformat (i, "del"))
8437         is_add = 0;
8438       else if (unformat (i, "add"))
8439         is_add = 1;
8440       else if (unformat (i, "vrf %d", &vrf_id))
8441         ;
8442       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8443         ;
8444       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8445         ;
8446       else
8447         {
8448           clib_warning ("parse error '%U'", format_unformat_error, i);
8449           return -99;
8450         }
8451     }
8452
8453   if (address_set == 0)
8454     {
8455       errmsg ("missing addresses\n");
8456       return -99;
8457     }
8458
8459   /* Construct the API message */
8460   M (IP_MROUTE_ADD_DEL, mp);
8461
8462   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8463   mp->table_id = ntohl (vrf_id);
8464
8465   mp->is_add = is_add;
8466   mp->is_ipv6 = is_ipv6;
8467   mp->is_local = is_local;
8468   mp->itf_flags = ntohl (iflags);
8469   mp->entry_flags = ntohl (eflags);
8470   mp->grp_address_length = grp_address_length;
8471   mp->grp_address_length = ntohs (mp->grp_address_length);
8472
8473   if (is_ipv6)
8474     {
8475       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8476       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8477     }
8478   else
8479     {
8480       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8481       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8482
8483     }
8484
8485   /* send it... */
8486   S (mp);
8487   /* Wait for a reply... */
8488   W (ret);
8489   return ret;
8490 }
8491
8492 static int
8493 api_mpls_table_add_del (vat_main_t * vam)
8494 {
8495   unformat_input_t *i = vam->input;
8496   vl_api_mpls_table_add_del_t *mp;
8497   u32 table_id = ~0;
8498   u8 is_add = 1;
8499   int ret = 0;
8500
8501   /* Parse args required to build the message */
8502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8503     {
8504       if (unformat (i, "table %d", &table_id))
8505         ;
8506       else if (unformat (i, "del"))
8507         is_add = 0;
8508       else if (unformat (i, "add"))
8509         is_add = 1;
8510       else
8511         {
8512           clib_warning ("parse error '%U'", format_unformat_error, i);
8513           return -99;
8514         }
8515     }
8516
8517   if (~0 == table_id)
8518     {
8519       errmsg ("missing table-ID");
8520       return -99;
8521     }
8522
8523   /* Construct the API message */
8524   M (MPLS_TABLE_ADD_DEL, mp);
8525
8526   mp->mt_table_id = ntohl (table_id);
8527   mp->mt_is_add = is_add;
8528
8529   /* send it... */
8530   S (mp);
8531
8532   /* Wait for a reply... */
8533   W (ret);
8534
8535   return ret;
8536 }
8537
8538 static int
8539 api_mpls_route_add_del (vat_main_t * vam)
8540 {
8541   unformat_input_t *i = vam->input;
8542   vl_api_mpls_route_add_del_t *mp;
8543   u32 sw_if_index = ~0, table_id = 0;
8544   u8 is_add = 1;
8545   u32 next_hop_weight = 1;
8546   u8 is_multipath = 0;
8547   u32 next_hop_table_id = 0;
8548   u8 next_hop_set = 0;
8549   ip4_address_t v4_next_hop_address = {
8550     .as_u32 = 0,
8551   };
8552   ip6_address_t v6_next_hop_address = { {0} };
8553   int count = 1;
8554   int j;
8555   f64 before = 0;
8556   u32 classify_table_index = ~0;
8557   u8 is_classify = 0;
8558   u8 resolve_host = 0, resolve_attached = 0;
8559   u8 is_interface_rx = 0;
8560   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8561   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8562   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8563   mpls_label_t local_label = MPLS_LABEL_INVALID;
8564   u8 is_eos = 0;
8565   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8566
8567   /* Parse args required to build the message */
8568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8569     {
8570       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8571         ;
8572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8573         ;
8574       else if (unformat (i, "%d", &local_label))
8575         ;
8576       else if (unformat (i, "eos"))
8577         is_eos = 1;
8578       else if (unformat (i, "non-eos"))
8579         is_eos = 0;
8580       else if (unformat (i, "via %U", unformat_ip4_address,
8581                          &v4_next_hop_address))
8582         {
8583           next_hop_set = 1;
8584           next_hop_proto = DPO_PROTO_IP4;
8585         }
8586       else if (unformat (i, "via %U", unformat_ip6_address,
8587                          &v6_next_hop_address))
8588         {
8589           next_hop_set = 1;
8590           next_hop_proto = DPO_PROTO_IP6;
8591         }
8592       else if (unformat (i, "weight %d", &next_hop_weight))
8593         ;
8594       else if (unformat (i, "classify %d", &classify_table_index))
8595         {
8596           is_classify = 1;
8597         }
8598       else if (unformat (i, "del"))
8599         is_add = 0;
8600       else if (unformat (i, "add"))
8601         is_add = 1;
8602       else if (unformat (i, "resolve-via-host"))
8603         resolve_host = 1;
8604       else if (unformat (i, "resolve-via-attached"))
8605         resolve_attached = 1;
8606       else if (unformat (i, "multipath"))
8607         is_multipath = 1;
8608       else if (unformat (i, "count %d", &count))
8609         ;
8610       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8611         {
8612           next_hop_set = 1;
8613           next_hop_proto = DPO_PROTO_IP4;
8614         }
8615       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8616         {
8617           next_hop_set = 1;
8618           next_hop_proto = DPO_PROTO_IP6;
8619         }
8620       else
8621         if (unformat
8622             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8623              &sw_if_index))
8624         {
8625           next_hop_set = 1;
8626           next_hop_proto = DPO_PROTO_ETHERNET;
8627           is_interface_rx = 1;
8628         }
8629       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8630         {
8631           next_hop_set = 1;
8632           next_hop_proto = DPO_PROTO_ETHERNET;
8633           is_interface_rx = 1;
8634         }
8635       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8636         next_hop_set = 1;
8637       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8638         next_hop_set = 1;
8639       else if (unformat (i, "out-label %d", &next_hop_out_label))
8640         {
8641           vl_api_fib_mpls_label_t fib_label = {
8642             .label = ntohl (next_hop_out_label),
8643             .ttl = 64,
8644             .exp = 0,
8645           };
8646           vec_add1 (next_hop_out_label_stack, fib_label);
8647         }
8648       else
8649         {
8650           clib_warning ("parse error '%U'", format_unformat_error, i);
8651           return -99;
8652         }
8653     }
8654
8655   if (!next_hop_set && !is_classify)
8656     {
8657       errmsg ("next hop / classify not set");
8658       return -99;
8659     }
8660
8661   if (MPLS_LABEL_INVALID == local_label)
8662     {
8663       errmsg ("missing label");
8664       return -99;
8665     }
8666
8667   if (count > 1)
8668     {
8669       /* Turn on async mode */
8670       vam->async_mode = 1;
8671       vam->async_errors = 0;
8672       before = vat_time_now (vam);
8673     }
8674
8675   for (j = 0; j < count; j++)
8676     {
8677       /* Construct the API message */
8678       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8679           vec_len (next_hop_out_label_stack));
8680
8681       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8682       mp->mr_table_id = ntohl (table_id);
8683
8684       mp->mr_is_add = is_add;
8685       mp->mr_next_hop_proto = next_hop_proto;
8686       mp->mr_is_classify = is_classify;
8687       mp->mr_is_multipath = is_multipath;
8688       mp->mr_is_resolve_host = resolve_host;
8689       mp->mr_is_resolve_attached = resolve_attached;
8690       mp->mr_is_interface_rx = is_interface_rx;
8691       mp->mr_next_hop_weight = next_hop_weight;
8692       mp->mr_next_hop_preference = 0;
8693       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8694       mp->mr_classify_table_index = ntohl (classify_table_index);
8695       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8696       mp->mr_label = ntohl (local_label);
8697       mp->mr_eos = is_eos;
8698
8699       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8700       if (0 != mp->mr_next_hop_n_out_labels)
8701         {
8702           memcpy (mp->mr_next_hop_out_label_stack,
8703                   next_hop_out_label_stack,
8704                   vec_len (next_hop_out_label_stack) *
8705                   sizeof (vl_api_fib_mpls_label_t));
8706           vec_free (next_hop_out_label_stack);
8707         }
8708
8709       if (next_hop_set)
8710         {
8711           if (DPO_PROTO_IP4 == next_hop_proto)
8712             {
8713               clib_memcpy (mp->mr_next_hop,
8714                            &v4_next_hop_address,
8715                            sizeof (v4_next_hop_address));
8716             }
8717           else if (DPO_PROTO_IP6 == next_hop_proto)
8718
8719             {
8720               clib_memcpy (mp->mr_next_hop,
8721                            &v6_next_hop_address,
8722                            sizeof (v6_next_hop_address));
8723             }
8724         }
8725       local_label++;
8726
8727       /* send it... */
8728       S (mp);
8729       /* If we receive SIGTERM, stop now... */
8730       if (vam->do_exit)
8731         break;
8732     }
8733
8734   /* When testing multiple add/del ops, use a control-ping to sync */
8735   if (count > 1)
8736     {
8737       vl_api_control_ping_t *mp_ping;
8738       f64 after;
8739       f64 timeout;
8740
8741       /* Shut off async mode */
8742       vam->async_mode = 0;
8743
8744       MPING (CONTROL_PING, mp_ping);
8745       S (mp_ping);
8746
8747       timeout = vat_time_now (vam) + 1.0;
8748       while (vat_time_now (vam) < timeout)
8749         if (vam->result_ready == 1)
8750           goto out;
8751       vam->retval = -99;
8752
8753     out:
8754       if (vam->retval == -99)
8755         errmsg ("timeout");
8756
8757       if (vam->async_errors > 0)
8758         {
8759           errmsg ("%d asynchronous errors", vam->async_errors);
8760           vam->retval = -98;
8761         }
8762       vam->async_errors = 0;
8763       after = vat_time_now (vam);
8764
8765       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8766       if (j > 0)
8767         count = j;
8768
8769       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8770              count, after - before, count / (after - before));
8771     }
8772   else
8773     {
8774       int ret;
8775
8776       /* Wait for a reply... */
8777       W (ret);
8778       return ret;
8779     }
8780
8781   /* Return the good/bad news */
8782   return (vam->retval);
8783 }
8784
8785 static int
8786 api_mpls_ip_bind_unbind (vat_main_t * vam)
8787 {
8788   unformat_input_t *i = vam->input;
8789   vl_api_mpls_ip_bind_unbind_t *mp;
8790   u32 ip_table_id = 0;
8791   u8 is_bind = 1;
8792   u8 is_ip4 = 1;
8793   ip4_address_t v4_address;
8794   ip6_address_t v6_address;
8795   u32 address_length;
8796   u8 address_set = 0;
8797   mpls_label_t local_label = MPLS_LABEL_INVALID;
8798   int ret;
8799
8800   /* Parse args required to build the message */
8801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8802     {
8803       if (unformat (i, "%U/%d", unformat_ip4_address,
8804                     &v4_address, &address_length))
8805         {
8806           is_ip4 = 1;
8807           address_set = 1;
8808         }
8809       else if (unformat (i, "%U/%d", unformat_ip6_address,
8810                          &v6_address, &address_length))
8811         {
8812           is_ip4 = 0;
8813           address_set = 1;
8814         }
8815       else if (unformat (i, "%d", &local_label))
8816         ;
8817       else if (unformat (i, "table-id %d", &ip_table_id))
8818         ;
8819       else if (unformat (i, "unbind"))
8820         is_bind = 0;
8821       else if (unformat (i, "bind"))
8822         is_bind = 1;
8823       else
8824         {
8825           clib_warning ("parse error '%U'", format_unformat_error, i);
8826           return -99;
8827         }
8828     }
8829
8830   if (!address_set)
8831     {
8832       errmsg ("IP address not set");
8833       return -99;
8834     }
8835
8836   if (MPLS_LABEL_INVALID == local_label)
8837     {
8838       errmsg ("missing label");
8839       return -99;
8840     }
8841
8842   /* Construct the API message */
8843   M (MPLS_IP_BIND_UNBIND, mp);
8844
8845   mp->mb_is_bind = is_bind;
8846   mp->mb_is_ip4 = is_ip4;
8847   mp->mb_ip_table_id = ntohl (ip_table_id);
8848   mp->mb_mpls_table_id = 0;
8849   mp->mb_label = ntohl (local_label);
8850   mp->mb_address_length = address_length;
8851
8852   if (is_ip4)
8853     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8854   else
8855     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8856
8857   /* send it... */
8858   S (mp);
8859
8860   /* Wait for a reply... */
8861   W (ret);
8862   return ret;
8863 }
8864
8865 static int
8866 api_sr_mpls_policy_add (vat_main_t * vam)
8867 {
8868   unformat_input_t *i = vam->input;
8869   vl_api_sr_mpls_policy_add_t *mp;
8870   u32 bsid = 0;
8871   u32 weight = 1;
8872   u8 type = 0;
8873   u8 n_segments = 0;
8874   u32 sid;
8875   u32 *segments = NULL;
8876   int ret;
8877
8878   /* Parse args required to build the message */
8879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8880     {
8881       if (unformat (i, "bsid %d", &bsid))
8882         ;
8883       else if (unformat (i, "weight %d", &weight))
8884         ;
8885       else if (unformat (i, "spray"))
8886         type = 1;
8887       else if (unformat (i, "next %d", &sid))
8888         {
8889           n_segments += 1;
8890           vec_add1 (segments, htonl (sid));
8891         }
8892       else
8893         {
8894           clib_warning ("parse error '%U'", format_unformat_error, i);
8895           return -99;
8896         }
8897     }
8898
8899   if (bsid == 0)
8900     {
8901       errmsg ("bsid not set");
8902       return -99;
8903     }
8904
8905   if (n_segments == 0)
8906     {
8907       errmsg ("no sid in segment stack");
8908       return -99;
8909     }
8910
8911   /* Construct the API message */
8912   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8913
8914   mp->bsid = htonl (bsid);
8915   mp->weight = htonl (weight);
8916   mp->type = type;
8917   mp->n_segments = n_segments;
8918   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8919   vec_free (segments);
8920
8921   /* send it... */
8922   S (mp);
8923
8924   /* Wait for a reply... */
8925   W (ret);
8926   return ret;
8927 }
8928
8929 static int
8930 api_sr_mpls_policy_del (vat_main_t * vam)
8931 {
8932   unformat_input_t *i = vam->input;
8933   vl_api_sr_mpls_policy_del_t *mp;
8934   u32 bsid = 0;
8935   int ret;
8936
8937   /* Parse args required to build the message */
8938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (i, "bsid %d", &bsid))
8941         ;
8942       else
8943         {
8944           clib_warning ("parse error '%U'", format_unformat_error, i);
8945           return -99;
8946         }
8947     }
8948
8949   if (bsid == 0)
8950     {
8951       errmsg ("bsid not set");
8952       return -99;
8953     }
8954
8955   /* Construct the API message */
8956   M (SR_MPLS_POLICY_DEL, mp);
8957
8958   mp->bsid = htonl (bsid);
8959
8960   /* send it... */
8961   S (mp);
8962
8963   /* Wait for a reply... */
8964   W (ret);
8965   return ret;
8966 }
8967
8968 static int
8969 api_bier_table_add_del (vat_main_t * vam)
8970 {
8971   unformat_input_t *i = vam->input;
8972   vl_api_bier_table_add_del_t *mp;
8973   u8 is_add = 1;
8974   u32 set = 0, sub_domain = 0, hdr_len = 3;
8975   mpls_label_t local_label = MPLS_LABEL_INVALID;
8976   int ret;
8977
8978   /* Parse args required to build the message */
8979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8980     {
8981       if (unformat (i, "sub-domain %d", &sub_domain))
8982         ;
8983       else if (unformat (i, "set %d", &set))
8984         ;
8985       else if (unformat (i, "label %d", &local_label))
8986         ;
8987       else if (unformat (i, "hdr-len %d", &hdr_len))
8988         ;
8989       else if (unformat (i, "add"))
8990         is_add = 1;
8991       else if (unformat (i, "del"))
8992         is_add = 0;
8993       else
8994         {
8995           clib_warning ("parse error '%U'", format_unformat_error, i);
8996           return -99;
8997         }
8998     }
8999
9000   if (MPLS_LABEL_INVALID == local_label)
9001     {
9002       errmsg ("missing label\n");
9003       return -99;
9004     }
9005
9006   /* Construct the API message */
9007   M (BIER_TABLE_ADD_DEL, mp);
9008
9009   mp->bt_is_add = is_add;
9010   mp->bt_label = ntohl (local_label);
9011   mp->bt_tbl_id.bt_set = set;
9012   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9013   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9014
9015   /* send it... */
9016   S (mp);
9017
9018   /* Wait for a reply... */
9019   W (ret);
9020
9021   return (ret);
9022 }
9023
9024 static int
9025 api_bier_route_add_del (vat_main_t * vam)
9026 {
9027   unformat_input_t *i = vam->input;
9028   vl_api_bier_route_add_del_t *mp;
9029   u8 is_add = 1;
9030   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9031   ip4_address_t v4_next_hop_address;
9032   ip6_address_t v6_next_hop_address;
9033   u8 next_hop_set = 0;
9034   u8 next_hop_proto_is_ip4 = 1;
9035   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9036   int ret;
9037
9038   /* Parse args required to build the message */
9039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9040     {
9041       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9042         {
9043           next_hop_proto_is_ip4 = 1;
9044           next_hop_set = 1;
9045         }
9046       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9047         {
9048           next_hop_proto_is_ip4 = 0;
9049           next_hop_set = 1;
9050         }
9051       if (unformat (i, "sub-domain %d", &sub_domain))
9052         ;
9053       else if (unformat (i, "set %d", &set))
9054         ;
9055       else if (unformat (i, "hdr-len %d", &hdr_len))
9056         ;
9057       else if (unformat (i, "bp %d", &bp))
9058         ;
9059       else if (unformat (i, "add"))
9060         is_add = 1;
9061       else if (unformat (i, "del"))
9062         is_add = 0;
9063       else if (unformat (i, "out-label %d", &next_hop_out_label))
9064         ;
9065       else
9066         {
9067           clib_warning ("parse error '%U'", format_unformat_error, i);
9068           return -99;
9069         }
9070     }
9071
9072   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9073     {
9074       errmsg ("next hop / label set\n");
9075       return -99;
9076     }
9077   if (0 == bp)
9078     {
9079       errmsg ("bit=position not set\n");
9080       return -99;
9081     }
9082
9083   /* Construct the API message */
9084   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9085
9086   mp->br_is_add = is_add;
9087   mp->br_tbl_id.bt_set = set;
9088   mp->br_tbl_id.bt_sub_domain = sub_domain;
9089   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9090   mp->br_bp = ntohs (bp);
9091   mp->br_n_paths = 1;
9092   mp->br_paths[0].n_labels = 1;
9093   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9094   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9095
9096   if (next_hop_proto_is_ip4)
9097     {
9098       clib_memcpy (mp->br_paths[0].next_hop,
9099                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9100     }
9101   else
9102     {
9103       clib_memcpy (mp->br_paths[0].next_hop,
9104                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9105     }
9106
9107   /* send it... */
9108   S (mp);
9109
9110   /* Wait for a reply... */
9111   W (ret);
9112
9113   return (ret);
9114 }
9115
9116 static int
9117 api_proxy_arp_add_del (vat_main_t * vam)
9118 {
9119   unformat_input_t *i = vam->input;
9120   vl_api_proxy_arp_add_del_t *mp;
9121   u32 vrf_id = 0;
9122   u8 is_add = 1;
9123   vl_api_ip4_address_t lo, hi;
9124   u8 range_set = 0;
9125   int ret;
9126
9127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9128     {
9129       if (unformat (i, "vrf %d", &vrf_id))
9130         ;
9131       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9132                          unformat_vl_api_ip4_address, &hi))
9133         range_set = 1;
9134       else if (unformat (i, "del"))
9135         is_add = 0;
9136       else
9137         {
9138           clib_warning ("parse error '%U'", format_unformat_error, i);
9139           return -99;
9140         }
9141     }
9142
9143   if (range_set == 0)
9144     {
9145       errmsg ("address range not set");
9146       return -99;
9147     }
9148
9149   M (PROXY_ARP_ADD_DEL, mp);
9150
9151   mp->proxy.table_id = ntohl (vrf_id);
9152   mp->is_add = is_add;
9153   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9154   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9155
9156   S (mp);
9157   W (ret);
9158   return ret;
9159 }
9160
9161 static int
9162 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9163 {
9164   unformat_input_t *i = vam->input;
9165   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9166   u32 sw_if_index;
9167   u8 enable = 1;
9168   u8 sw_if_index_set = 0;
9169   int ret;
9170
9171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9172     {
9173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9174         sw_if_index_set = 1;
9175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9176         sw_if_index_set = 1;
9177       else if (unformat (i, "enable"))
9178         enable = 1;
9179       else if (unformat (i, "disable"))
9180         enable = 0;
9181       else
9182         {
9183           clib_warning ("parse error '%U'", format_unformat_error, i);
9184           return -99;
9185         }
9186     }
9187
9188   if (sw_if_index_set == 0)
9189     {
9190       errmsg ("missing interface name or sw_if_index");
9191       return -99;
9192     }
9193
9194   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9195
9196   mp->sw_if_index = ntohl (sw_if_index);
9197   mp->enable_disable = enable;
9198
9199   S (mp);
9200   W (ret);
9201   return ret;
9202 }
9203
9204 static int
9205 api_mpls_tunnel_add_del (vat_main_t * vam)
9206 {
9207   unformat_input_t *i = vam->input;
9208   vl_api_mpls_tunnel_add_del_t *mp;
9209
9210   u8 is_add = 1;
9211   u8 l2_only = 0;
9212   u32 sw_if_index = ~0;
9213   u32 next_hop_sw_if_index = ~0;
9214   u32 next_hop_proto_is_ip4 = 1;
9215
9216   u32 next_hop_table_id = 0;
9217   ip4_address_t v4_next_hop_address = {
9218     .as_u32 = 0,
9219   };
9220   ip6_address_t v6_next_hop_address = { {0} };
9221   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9222   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9223   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9224   int ret;
9225
9226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9227     {
9228       if (unformat (i, "add"))
9229         is_add = 1;
9230       else
9231         if (unformat
9232             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9233         is_add = 0;
9234       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9235         is_add = 0;
9236       else if (unformat (i, "via %U",
9237                          unformat_ip4_address, &v4_next_hop_address))
9238         {
9239           next_hop_proto_is_ip4 = 1;
9240         }
9241       else if (unformat (i, "via %U",
9242                          unformat_ip6_address, &v6_next_hop_address))
9243         {
9244           next_hop_proto_is_ip4 = 0;
9245         }
9246       else if (unformat (i, "via-label %d", &next_hop_via_label))
9247         ;
9248       else
9249         if (unformat
9250             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9251         ;
9252       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9253         ;
9254       else if (unformat (i, "l2-only"))
9255         l2_only = 1;
9256       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9257         ;
9258       else if (unformat (i, "out-label %d", &next_hop_out_label))
9259         {
9260           vl_api_fib_mpls_label_t fib_label = {
9261             .label = ntohl (next_hop_out_label),
9262             .ttl = 64,
9263             .exp = 0,
9264           };
9265           vec_add1 (next_hop_out_label_stack, fib_label);
9266         }
9267       else
9268         {
9269           clib_warning ("parse error '%U'", format_unformat_error, i);
9270           return -99;
9271         }
9272     }
9273
9274   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9275       vec_len (next_hop_out_label_stack));
9276
9277   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9278   mp->mt_sw_if_index = ntohl (sw_if_index);
9279   mp->mt_is_add = is_add;
9280   mp->mt_l2_only = l2_only;
9281   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9282   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9283   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9284   mp->mt_next_hop_weight = 1;
9285   mp->mt_next_hop_preference = 0;
9286
9287   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9288
9289   if (0 != mp->mt_next_hop_n_out_labels)
9290     {
9291       clib_memcpy (mp->mt_next_hop_out_label_stack,
9292                    next_hop_out_label_stack,
9293                    (vec_len (next_hop_out_label_stack) *
9294                     sizeof (vl_api_fib_mpls_label_t)));
9295       vec_free (next_hop_out_label_stack);
9296     }
9297
9298   if (next_hop_proto_is_ip4)
9299     {
9300       clib_memcpy (mp->mt_next_hop,
9301                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9302     }
9303   else
9304     {
9305       clib_memcpy (mp->mt_next_hop,
9306                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9307     }
9308
9309   S (mp);
9310   W (ret);
9311   return ret;
9312 }
9313
9314 static int
9315 api_sw_interface_set_unnumbered (vat_main_t * vam)
9316 {
9317   unformat_input_t *i = vam->input;
9318   vl_api_sw_interface_set_unnumbered_t *mp;
9319   u32 sw_if_index;
9320   u32 unnum_sw_index = ~0;
9321   u8 is_add = 1;
9322   u8 sw_if_index_set = 0;
9323   int ret;
9324
9325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9326     {
9327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9328         sw_if_index_set = 1;
9329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9330         sw_if_index_set = 1;
9331       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9332         ;
9333       else if (unformat (i, "del"))
9334         is_add = 0;
9335       else
9336         {
9337           clib_warning ("parse error '%U'", format_unformat_error, i);
9338           return -99;
9339         }
9340     }
9341
9342   if (sw_if_index_set == 0)
9343     {
9344       errmsg ("missing interface name or sw_if_index");
9345       return -99;
9346     }
9347
9348   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9349
9350   mp->sw_if_index = ntohl (sw_if_index);
9351   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9352   mp->is_add = is_add;
9353
9354   S (mp);
9355   W (ret);
9356   return ret;
9357 }
9358
9359 static int
9360 api_ip_neighbor_add_del (vat_main_t * vam)
9361 {
9362   vl_api_mac_address_t mac_address;
9363   unformat_input_t *i = vam->input;
9364   vl_api_ip_neighbor_add_del_t *mp;
9365   vl_api_address_t ip_address;
9366   u32 sw_if_index;
9367   u8 sw_if_index_set = 0;
9368   u8 is_add = 1;
9369   u8 mac_set = 0;
9370   u8 address_set = 0;
9371   int ret;
9372   ip_neighbor_flags_t flags;
9373
9374   flags = IP_NEIGHBOR_FLAG_NONE;
9375   clib_memset (&ip_address, 0, sizeof (ip_address));
9376   clib_memset (&mac_address, 0, sizeof (mac_address));
9377   /* Parse args required to build the message */
9378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9379     {
9380       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9381         {
9382           mac_set = 1;
9383         }
9384       else if (unformat (i, "del"))
9385         is_add = 0;
9386       else
9387         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9388         sw_if_index_set = 1;
9389       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9390         sw_if_index_set = 1;
9391       else if (unformat (i, "static"))
9392         flags |= IP_NEIGHBOR_FLAG_STATIC;
9393       else if (unformat (i, "no-fib-entry"))
9394         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9395       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9396         address_set = 1;
9397       else
9398         {
9399           clib_warning ("parse error '%U'", format_unformat_error, i);
9400           return -99;
9401         }
9402     }
9403
9404   if (sw_if_index_set == 0)
9405     {
9406       errmsg ("missing interface name or sw_if_index");
9407       return -99;
9408     }
9409   if (!address_set)
9410     {
9411       errmsg ("no address set");
9412       return -99;
9413     }
9414
9415   /* Construct the API message */
9416   M (IP_NEIGHBOR_ADD_DEL, mp);
9417
9418   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9419   mp->is_add = is_add;
9420   mp->neighbor.flags = htonl (flags);
9421   if (mac_set)
9422     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9423                  sizeof (mac_address));
9424   if (address_set)
9425     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9426
9427   /* send it... */
9428   S (mp);
9429
9430   /* Wait for a reply, return good/bad news  */
9431   W (ret);
9432   return ret;
9433 }
9434
9435 static int
9436 api_create_vlan_subif (vat_main_t * vam)
9437 {
9438   unformat_input_t *i = vam->input;
9439   vl_api_create_vlan_subif_t *mp;
9440   u32 sw_if_index;
9441   u8 sw_if_index_set = 0;
9442   u32 vlan_id;
9443   u8 vlan_id_set = 0;
9444   int ret;
9445
9446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9447     {
9448       if (unformat (i, "sw_if_index %d", &sw_if_index))
9449         sw_if_index_set = 1;
9450       else
9451         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9452         sw_if_index_set = 1;
9453       else if (unformat (i, "vlan %d", &vlan_id))
9454         vlan_id_set = 1;
9455       else
9456         {
9457           clib_warning ("parse error '%U'", format_unformat_error, i);
9458           return -99;
9459         }
9460     }
9461
9462   if (sw_if_index_set == 0)
9463     {
9464       errmsg ("missing interface name or sw_if_index");
9465       return -99;
9466     }
9467
9468   if (vlan_id_set == 0)
9469     {
9470       errmsg ("missing vlan_id");
9471       return -99;
9472     }
9473   M (CREATE_VLAN_SUBIF, mp);
9474
9475   mp->sw_if_index = ntohl (sw_if_index);
9476   mp->vlan_id = ntohl (vlan_id);
9477
9478   S (mp);
9479   W (ret);
9480   return ret;
9481 }
9482
9483 #define foreach_create_subif_bit                \
9484 _(no_tags)                                      \
9485 _(one_tag)                                      \
9486 _(two_tags)                                     \
9487 _(dot1ad)                                       \
9488 _(exact_match)                                  \
9489 _(default_sub)                                  \
9490 _(outer_vlan_id_any)                            \
9491 _(inner_vlan_id_any)
9492
9493 static int
9494 api_create_subif (vat_main_t * vam)
9495 {
9496   unformat_input_t *i = vam->input;
9497   vl_api_create_subif_t *mp;
9498   u32 sw_if_index;
9499   u8 sw_if_index_set = 0;
9500   u32 sub_id;
9501   u8 sub_id_set = 0;
9502   u32 no_tags = 0;
9503   u32 one_tag = 0;
9504   u32 two_tags = 0;
9505   u32 dot1ad = 0;
9506   u32 exact_match = 0;
9507   u32 default_sub = 0;
9508   u32 outer_vlan_id_any = 0;
9509   u32 inner_vlan_id_any = 0;
9510   u32 tmp;
9511   u16 outer_vlan_id = 0;
9512   u16 inner_vlan_id = 0;
9513   int ret;
9514
9515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9516     {
9517       if (unformat (i, "sw_if_index %d", &sw_if_index))
9518         sw_if_index_set = 1;
9519       else
9520         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9521         sw_if_index_set = 1;
9522       else if (unformat (i, "sub_id %d", &sub_id))
9523         sub_id_set = 1;
9524       else if (unformat (i, "outer_vlan_id %d", &tmp))
9525         outer_vlan_id = tmp;
9526       else if (unformat (i, "inner_vlan_id %d", &tmp))
9527         inner_vlan_id = tmp;
9528
9529 #define _(a) else if (unformat (i, #a)) a = 1 ;
9530       foreach_create_subif_bit
9531 #undef _
9532         else
9533         {
9534           clib_warning ("parse error '%U'", format_unformat_error, i);
9535           return -99;
9536         }
9537     }
9538
9539   if (sw_if_index_set == 0)
9540     {
9541       errmsg ("missing interface name or sw_if_index");
9542       return -99;
9543     }
9544
9545   if (sub_id_set == 0)
9546     {
9547       errmsg ("missing sub_id");
9548       return -99;
9549     }
9550   M (CREATE_SUBIF, mp);
9551
9552   mp->sw_if_index = ntohl (sw_if_index);
9553   mp->sub_id = ntohl (sub_id);
9554
9555 #define _(a) mp->a = a;
9556   foreach_create_subif_bit;
9557 #undef _
9558
9559   mp->outer_vlan_id = ntohs (outer_vlan_id);
9560   mp->inner_vlan_id = ntohs (inner_vlan_id);
9561
9562   S (mp);
9563   W (ret);
9564   return ret;
9565 }
9566
9567 static int
9568 api_oam_add_del (vat_main_t * vam)
9569 {
9570   unformat_input_t *i = vam->input;
9571   vl_api_oam_add_del_t *mp;
9572   u32 vrf_id = 0;
9573   u8 is_add = 1;
9574   ip4_address_t src, dst;
9575   u8 src_set = 0;
9576   u8 dst_set = 0;
9577   int ret;
9578
9579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9580     {
9581       if (unformat (i, "vrf %d", &vrf_id))
9582         ;
9583       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9584         src_set = 1;
9585       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9586         dst_set = 1;
9587       else if (unformat (i, "del"))
9588         is_add = 0;
9589       else
9590         {
9591           clib_warning ("parse error '%U'", format_unformat_error, i);
9592           return -99;
9593         }
9594     }
9595
9596   if (src_set == 0)
9597     {
9598       errmsg ("missing src addr");
9599       return -99;
9600     }
9601
9602   if (dst_set == 0)
9603     {
9604       errmsg ("missing dst addr");
9605       return -99;
9606     }
9607
9608   M (OAM_ADD_DEL, mp);
9609
9610   mp->vrf_id = ntohl (vrf_id);
9611   mp->is_add = is_add;
9612   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9613   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9614
9615   S (mp);
9616   W (ret);
9617   return ret;
9618 }
9619
9620 static int
9621 api_reset_fib (vat_main_t * vam)
9622 {
9623   unformat_input_t *i = vam->input;
9624   vl_api_reset_fib_t *mp;
9625   u32 vrf_id = 0;
9626   u8 is_ipv6 = 0;
9627   u8 vrf_id_set = 0;
9628
9629   int ret;
9630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9631     {
9632       if (unformat (i, "vrf %d", &vrf_id))
9633         vrf_id_set = 1;
9634       else if (unformat (i, "ipv6"))
9635         is_ipv6 = 1;
9636       else
9637         {
9638           clib_warning ("parse error '%U'", format_unformat_error, i);
9639           return -99;
9640         }
9641     }
9642
9643   if (vrf_id_set == 0)
9644     {
9645       errmsg ("missing vrf id");
9646       return -99;
9647     }
9648
9649   M (RESET_FIB, mp);
9650
9651   mp->vrf_id = ntohl (vrf_id);
9652   mp->is_ipv6 = is_ipv6;
9653
9654   S (mp);
9655   W (ret);
9656   return ret;
9657 }
9658
9659 static int
9660 api_dhcp_proxy_config (vat_main_t * vam)
9661 {
9662   unformat_input_t *i = vam->input;
9663   vl_api_dhcp_proxy_config_t *mp;
9664   u32 rx_vrf_id = 0;
9665   u32 server_vrf_id = 0;
9666   u8 is_add = 1;
9667   u8 v4_address_set = 0;
9668   u8 v6_address_set = 0;
9669   ip4_address_t v4address;
9670   ip6_address_t v6address;
9671   u8 v4_src_address_set = 0;
9672   u8 v6_src_address_set = 0;
9673   ip4_address_t v4srcaddress;
9674   ip6_address_t v6srcaddress;
9675   int ret;
9676
9677   /* Parse args required to build the message */
9678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9679     {
9680       if (unformat (i, "del"))
9681         is_add = 0;
9682       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9683         ;
9684       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9685         ;
9686       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9687         v4_address_set = 1;
9688       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9689         v6_address_set = 1;
9690       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9691         v4_src_address_set = 1;
9692       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9693         v6_src_address_set = 1;
9694       else
9695         break;
9696     }
9697
9698   if (v4_address_set && v6_address_set)
9699     {
9700       errmsg ("both v4 and v6 server addresses set");
9701       return -99;
9702     }
9703   if (!v4_address_set && !v6_address_set)
9704     {
9705       errmsg ("no server addresses set");
9706       return -99;
9707     }
9708
9709   if (v4_src_address_set && v6_src_address_set)
9710     {
9711       errmsg ("both v4 and v6  src addresses set");
9712       return -99;
9713     }
9714   if (!v4_src_address_set && !v6_src_address_set)
9715     {
9716       errmsg ("no src addresses set");
9717       return -99;
9718     }
9719
9720   if (!(v4_src_address_set && v4_address_set) &&
9721       !(v6_src_address_set && v6_address_set))
9722     {
9723       errmsg ("no matching server and src addresses set");
9724       return -99;
9725     }
9726
9727   /* Construct the API message */
9728   M (DHCP_PROXY_CONFIG, mp);
9729
9730   mp->is_add = is_add;
9731   mp->rx_vrf_id = ntohl (rx_vrf_id);
9732   mp->server_vrf_id = ntohl (server_vrf_id);
9733   if (v6_address_set)
9734     {
9735       mp->is_ipv6 = 1;
9736       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9737       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9738     }
9739   else
9740     {
9741       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9742       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9743     }
9744
9745   /* send it... */
9746   S (mp);
9747
9748   /* Wait for a reply, return good/bad news  */
9749   W (ret);
9750   return ret;
9751 }
9752
9753 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9754 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9755
9756 static void
9757 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9758 {
9759   vat_main_t *vam = &vat_main;
9760   u32 i, count = mp->count;
9761   vl_api_dhcp_server_t *s;
9762
9763   if (mp->is_ipv6)
9764     print (vam->ofp,
9765            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9766            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9767            ntohl (mp->rx_vrf_id),
9768            format_ip6_address, mp->dhcp_src_address,
9769            mp->vss_type, mp->vss_vpn_ascii_id,
9770            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9771   else
9772     print (vam->ofp,
9773            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9774            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9775            ntohl (mp->rx_vrf_id),
9776            format_ip4_address, mp->dhcp_src_address,
9777            mp->vss_type, mp->vss_vpn_ascii_id,
9778            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9779
9780   for (i = 0; i < count; i++)
9781     {
9782       s = &mp->servers[i];
9783
9784       if (mp->is_ipv6)
9785         print (vam->ofp,
9786                " Server Table-ID %d, Server Address %U",
9787                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9788       else
9789         print (vam->ofp,
9790                " Server Table-ID %d, Server Address %U",
9791                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9792     }
9793 }
9794
9795 static void vl_api_dhcp_proxy_details_t_handler_json
9796   (vl_api_dhcp_proxy_details_t * mp)
9797 {
9798   vat_main_t *vam = &vat_main;
9799   vat_json_node_t *node = NULL;
9800   u32 i, count = mp->count;
9801   struct in_addr ip4;
9802   struct in6_addr ip6;
9803   vl_api_dhcp_server_t *s;
9804
9805   if (VAT_JSON_ARRAY != vam->json_tree.type)
9806     {
9807       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9808       vat_json_init_array (&vam->json_tree);
9809     }
9810   node = vat_json_array_add (&vam->json_tree);
9811
9812   vat_json_init_object (node);
9813   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9814   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9815                              sizeof (mp->vss_type));
9816   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9817                                    mp->vss_vpn_ascii_id);
9818   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9819   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9820
9821   if (mp->is_ipv6)
9822     {
9823       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9824       vat_json_object_add_ip6 (node, "src_address", ip6);
9825     }
9826   else
9827     {
9828       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9829       vat_json_object_add_ip4 (node, "src_address", ip4);
9830     }
9831
9832   for (i = 0; i < count; i++)
9833     {
9834       s = &mp->servers[i];
9835
9836       vat_json_object_add_uint (node, "server-table-id",
9837                                 ntohl (s->server_vrf_id));
9838
9839       if (mp->is_ipv6)
9840         {
9841           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9842           vat_json_object_add_ip4 (node, "src_address", ip4);
9843         }
9844       else
9845         {
9846           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9847           vat_json_object_add_ip6 (node, "server_address", ip6);
9848         }
9849     }
9850 }
9851
9852 static int
9853 api_dhcp_proxy_dump (vat_main_t * vam)
9854 {
9855   unformat_input_t *i = vam->input;
9856   vl_api_control_ping_t *mp_ping;
9857   vl_api_dhcp_proxy_dump_t *mp;
9858   u8 is_ipv6 = 0;
9859   int ret;
9860
9861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9862     {
9863       if (unformat (i, "ipv6"))
9864         is_ipv6 = 1;
9865       else
9866         {
9867           clib_warning ("parse error '%U'", format_unformat_error, i);
9868           return -99;
9869         }
9870     }
9871
9872   M (DHCP_PROXY_DUMP, mp);
9873
9874   mp->is_ip6 = is_ipv6;
9875   S (mp);
9876
9877   /* Use a control ping for synchronization */
9878   MPING (CONTROL_PING, mp_ping);
9879   S (mp_ping);
9880
9881   W (ret);
9882   return ret;
9883 }
9884
9885 static int
9886 api_dhcp_proxy_set_vss (vat_main_t * vam)
9887 {
9888   unformat_input_t *i = vam->input;
9889   vl_api_dhcp_proxy_set_vss_t *mp;
9890   u8 is_ipv6 = 0;
9891   u8 is_add = 1;
9892   u32 tbl_id = ~0;
9893   u8 vss_type = VSS_TYPE_DEFAULT;
9894   u8 *vpn_ascii_id = 0;
9895   u32 oui = 0;
9896   u32 fib_id = 0;
9897   int ret;
9898
9899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9900     {
9901       if (unformat (i, "tbl_id %d", &tbl_id))
9902         ;
9903       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9904         vss_type = VSS_TYPE_ASCII;
9905       else if (unformat (i, "fib_id %d", &fib_id))
9906         vss_type = VSS_TYPE_VPN_ID;
9907       else if (unformat (i, "oui %d", &oui))
9908         vss_type = VSS_TYPE_VPN_ID;
9909       else if (unformat (i, "ipv6"))
9910         is_ipv6 = 1;
9911       else if (unformat (i, "del"))
9912         is_add = 0;
9913       else
9914         break;
9915     }
9916
9917   if (tbl_id == ~0)
9918     {
9919       errmsg ("missing tbl_id ");
9920       vec_free (vpn_ascii_id);
9921       return -99;
9922     }
9923
9924   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9925     {
9926       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9927       vec_free (vpn_ascii_id);
9928       return -99;
9929     }
9930
9931   M (DHCP_PROXY_SET_VSS, mp);
9932   mp->tbl_id = ntohl (tbl_id);
9933   mp->vss_type = vss_type;
9934   if (vpn_ascii_id)
9935     {
9936       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9937       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9938     }
9939   mp->vpn_index = ntohl (fib_id);
9940   mp->oui = ntohl (oui);
9941   mp->is_ipv6 = is_ipv6;
9942   mp->is_add = is_add;
9943
9944   S (mp);
9945   W (ret);
9946
9947   vec_free (vpn_ascii_id);
9948   return ret;
9949 }
9950
9951 static int
9952 api_dhcp_client_config (vat_main_t * vam)
9953 {
9954   unformat_input_t *i = vam->input;
9955   vl_api_dhcp_client_config_t *mp;
9956   u32 sw_if_index;
9957   u8 sw_if_index_set = 0;
9958   u8 is_add = 1;
9959   u8 *hostname = 0;
9960   u8 disable_event = 0;
9961   int ret;
9962
9963   /* Parse args required to build the message */
9964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9965     {
9966       if (unformat (i, "del"))
9967         is_add = 0;
9968       else
9969         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9970         sw_if_index_set = 1;
9971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9972         sw_if_index_set = 1;
9973       else if (unformat (i, "hostname %s", &hostname))
9974         ;
9975       else if (unformat (i, "disable_event"))
9976         disable_event = 1;
9977       else
9978         break;
9979     }
9980
9981   if (sw_if_index_set == 0)
9982     {
9983       errmsg ("missing interface name or sw_if_index");
9984       return -99;
9985     }
9986
9987   if (vec_len (hostname) > 63)
9988     {
9989       errmsg ("hostname too long");
9990     }
9991   vec_add1 (hostname, 0);
9992
9993   /* Construct the API message */
9994   M (DHCP_CLIENT_CONFIG, mp);
9995
9996   mp->is_add = is_add;
9997   mp->client.sw_if_index = htonl (sw_if_index);
9998   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9999   vec_free (hostname);
10000   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10001   mp->client.pid = htonl (getpid ());
10002
10003   /* send it... */
10004   S (mp);
10005
10006   /* Wait for a reply, return good/bad news  */
10007   W (ret);
10008   return ret;
10009 }
10010
10011 static int
10012 api_set_ip_flow_hash (vat_main_t * vam)
10013 {
10014   unformat_input_t *i = vam->input;
10015   vl_api_set_ip_flow_hash_t *mp;
10016   u32 vrf_id = 0;
10017   u8 is_ipv6 = 0;
10018   u8 vrf_id_set = 0;
10019   u8 src = 0;
10020   u8 dst = 0;
10021   u8 sport = 0;
10022   u8 dport = 0;
10023   u8 proto = 0;
10024   u8 reverse = 0;
10025   int ret;
10026
10027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10028     {
10029       if (unformat (i, "vrf %d", &vrf_id))
10030         vrf_id_set = 1;
10031       else if (unformat (i, "ipv6"))
10032         is_ipv6 = 1;
10033       else if (unformat (i, "src"))
10034         src = 1;
10035       else if (unformat (i, "dst"))
10036         dst = 1;
10037       else if (unformat (i, "sport"))
10038         sport = 1;
10039       else if (unformat (i, "dport"))
10040         dport = 1;
10041       else if (unformat (i, "proto"))
10042         proto = 1;
10043       else if (unformat (i, "reverse"))
10044         reverse = 1;
10045
10046       else
10047         {
10048           clib_warning ("parse error '%U'", format_unformat_error, i);
10049           return -99;
10050         }
10051     }
10052
10053   if (vrf_id_set == 0)
10054     {
10055       errmsg ("missing vrf id");
10056       return -99;
10057     }
10058
10059   M (SET_IP_FLOW_HASH, mp);
10060   mp->src = src;
10061   mp->dst = dst;
10062   mp->sport = sport;
10063   mp->dport = dport;
10064   mp->proto = proto;
10065   mp->reverse = reverse;
10066   mp->vrf_id = ntohl (vrf_id);
10067   mp->is_ipv6 = is_ipv6;
10068
10069   S (mp);
10070   W (ret);
10071   return ret;
10072 }
10073
10074 static int
10075 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10076 {
10077   unformat_input_t *i = vam->input;
10078   vl_api_sw_interface_ip6_enable_disable_t *mp;
10079   u32 sw_if_index;
10080   u8 sw_if_index_set = 0;
10081   u8 enable = 0;
10082   int ret;
10083
10084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10085     {
10086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10087         sw_if_index_set = 1;
10088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10089         sw_if_index_set = 1;
10090       else if (unformat (i, "enable"))
10091         enable = 1;
10092       else if (unformat (i, "disable"))
10093         enable = 0;
10094       else
10095         {
10096           clib_warning ("parse error '%U'", format_unformat_error, i);
10097           return -99;
10098         }
10099     }
10100
10101   if (sw_if_index_set == 0)
10102     {
10103       errmsg ("missing interface name or sw_if_index");
10104       return -99;
10105     }
10106
10107   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10108
10109   mp->sw_if_index = ntohl (sw_if_index);
10110   mp->enable = enable;
10111
10112   S (mp);
10113   W (ret);
10114   return ret;
10115 }
10116
10117 static int
10118 api_ip6nd_proxy_add_del (vat_main_t * vam)
10119 {
10120   unformat_input_t *i = vam->input;
10121   vl_api_ip6nd_proxy_add_del_t *mp;
10122   u32 sw_if_index = ~0;
10123   u8 v6_address_set = 0;
10124   vl_api_ip6_address_t v6address;
10125   u8 is_del = 0;
10126   int ret;
10127
10128   /* Parse args required to build the message */
10129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10130     {
10131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10132         ;
10133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10134         ;
10135       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10136         v6_address_set = 1;
10137       if (unformat (i, "del"))
10138         is_del = 1;
10139       else
10140         {
10141           clib_warning ("parse error '%U'", format_unformat_error, i);
10142           return -99;
10143         }
10144     }
10145
10146   if (sw_if_index == ~0)
10147     {
10148       errmsg ("missing interface name or sw_if_index");
10149       return -99;
10150     }
10151   if (!v6_address_set)
10152     {
10153       errmsg ("no address set");
10154       return -99;
10155     }
10156
10157   /* Construct the API message */
10158   M (IP6ND_PROXY_ADD_DEL, mp);
10159
10160   mp->is_del = is_del;
10161   mp->sw_if_index = ntohl (sw_if_index);
10162   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10163
10164   /* send it... */
10165   S (mp);
10166
10167   /* Wait for a reply, return good/bad news  */
10168   W (ret);
10169   return ret;
10170 }
10171
10172 static int
10173 api_ip6nd_proxy_dump (vat_main_t * vam)
10174 {
10175   vl_api_ip6nd_proxy_dump_t *mp;
10176   vl_api_control_ping_t *mp_ping;
10177   int ret;
10178
10179   M (IP6ND_PROXY_DUMP, mp);
10180
10181   S (mp);
10182
10183   /* Use a control ping for synchronization */
10184   MPING (CONTROL_PING, mp_ping);
10185   S (mp_ping);
10186
10187   W (ret);
10188   return ret;
10189 }
10190
10191 static void vl_api_ip6nd_proxy_details_t_handler
10192   (vl_api_ip6nd_proxy_details_t * mp)
10193 {
10194   vat_main_t *vam = &vat_main;
10195
10196   print (vam->ofp, "host %U sw_if_index %d",
10197          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10198 }
10199
10200 static void vl_api_ip6nd_proxy_details_t_handler_json
10201   (vl_api_ip6nd_proxy_details_t * mp)
10202 {
10203   vat_main_t *vam = &vat_main;
10204   struct in6_addr ip6;
10205   vat_json_node_t *node = NULL;
10206
10207   if (VAT_JSON_ARRAY != vam->json_tree.type)
10208     {
10209       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10210       vat_json_init_array (&vam->json_tree);
10211     }
10212   node = vat_json_array_add (&vam->json_tree);
10213
10214   vat_json_init_object (node);
10215   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10216
10217   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10218   vat_json_object_add_ip6 (node, "host", ip6);
10219 }
10220
10221 static int
10222 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10223 {
10224   unformat_input_t *i = vam->input;
10225   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10226   u32 sw_if_index;
10227   u8 sw_if_index_set = 0;
10228   u32 address_length = 0;
10229   u8 v6_address_set = 0;
10230   vl_api_prefix_t pfx;
10231   u8 use_default = 0;
10232   u8 no_advertise = 0;
10233   u8 off_link = 0;
10234   u8 no_autoconfig = 0;
10235   u8 no_onlink = 0;
10236   u8 is_no = 0;
10237   u32 val_lifetime = 0;
10238   u32 pref_lifetime = 0;
10239   int ret;
10240
10241   /* Parse args required to build the message */
10242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10243     {
10244       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10245         sw_if_index_set = 1;
10246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10247         sw_if_index_set = 1;
10248       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10249         v6_address_set = 1;
10250       else if (unformat (i, "val_life %d", &val_lifetime))
10251         ;
10252       else if (unformat (i, "pref_life %d", &pref_lifetime))
10253         ;
10254       else if (unformat (i, "def"))
10255         use_default = 1;
10256       else if (unformat (i, "noadv"))
10257         no_advertise = 1;
10258       else if (unformat (i, "offl"))
10259         off_link = 1;
10260       else if (unformat (i, "noauto"))
10261         no_autoconfig = 1;
10262       else if (unformat (i, "nolink"))
10263         no_onlink = 1;
10264       else if (unformat (i, "isno"))
10265         is_no = 1;
10266       else
10267         {
10268           clib_warning ("parse error '%U'", format_unformat_error, i);
10269           return -99;
10270         }
10271     }
10272
10273   if (sw_if_index_set == 0)
10274     {
10275       errmsg ("missing interface name or sw_if_index");
10276       return -99;
10277     }
10278   if (!v6_address_set)
10279     {
10280       errmsg ("no address set");
10281       return -99;
10282     }
10283
10284   /* Construct the API message */
10285   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10286
10287   mp->sw_if_index = ntohl (sw_if_index);
10288   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10289   mp->use_default = use_default;
10290   mp->no_advertise = no_advertise;
10291   mp->off_link = off_link;
10292   mp->no_autoconfig = no_autoconfig;
10293   mp->no_onlink = no_onlink;
10294   mp->is_no = is_no;
10295   mp->val_lifetime = ntohl (val_lifetime);
10296   mp->pref_lifetime = ntohl (pref_lifetime);
10297
10298   /* send it... */
10299   S (mp);
10300
10301   /* Wait for a reply, return good/bad news  */
10302   W (ret);
10303   return ret;
10304 }
10305
10306 static int
10307 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10308 {
10309   unformat_input_t *i = vam->input;
10310   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10311   u32 sw_if_index;
10312   u8 sw_if_index_set = 0;
10313   u8 suppress = 0;
10314   u8 managed = 0;
10315   u8 other = 0;
10316   u8 ll_option = 0;
10317   u8 send_unicast = 0;
10318   u8 cease = 0;
10319   u8 is_no = 0;
10320   u8 default_router = 0;
10321   u32 max_interval = 0;
10322   u32 min_interval = 0;
10323   u32 lifetime = 0;
10324   u32 initial_count = 0;
10325   u32 initial_interval = 0;
10326   int ret;
10327
10328
10329   /* Parse args required to build the message */
10330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10331     {
10332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10333         sw_if_index_set = 1;
10334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10335         sw_if_index_set = 1;
10336       else if (unformat (i, "maxint %d", &max_interval))
10337         ;
10338       else if (unformat (i, "minint %d", &min_interval))
10339         ;
10340       else if (unformat (i, "life %d", &lifetime))
10341         ;
10342       else if (unformat (i, "count %d", &initial_count))
10343         ;
10344       else if (unformat (i, "interval %d", &initial_interval))
10345         ;
10346       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10347         suppress = 1;
10348       else if (unformat (i, "managed"))
10349         managed = 1;
10350       else if (unformat (i, "other"))
10351         other = 1;
10352       else if (unformat (i, "ll"))
10353         ll_option = 1;
10354       else if (unformat (i, "send"))
10355         send_unicast = 1;
10356       else if (unformat (i, "cease"))
10357         cease = 1;
10358       else if (unformat (i, "isno"))
10359         is_no = 1;
10360       else if (unformat (i, "def"))
10361         default_router = 1;
10362       else
10363         {
10364           clib_warning ("parse error '%U'", format_unformat_error, i);
10365           return -99;
10366         }
10367     }
10368
10369   if (sw_if_index_set == 0)
10370     {
10371       errmsg ("missing interface name or sw_if_index");
10372       return -99;
10373     }
10374
10375   /* Construct the API message */
10376   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10377
10378   mp->sw_if_index = ntohl (sw_if_index);
10379   mp->max_interval = ntohl (max_interval);
10380   mp->min_interval = ntohl (min_interval);
10381   mp->lifetime = ntohl (lifetime);
10382   mp->initial_count = ntohl (initial_count);
10383   mp->initial_interval = ntohl (initial_interval);
10384   mp->suppress = suppress;
10385   mp->managed = managed;
10386   mp->other = other;
10387   mp->ll_option = ll_option;
10388   mp->send_unicast = send_unicast;
10389   mp->cease = cease;
10390   mp->is_no = is_no;
10391   mp->default_router = default_router;
10392
10393   /* send it... */
10394   S (mp);
10395
10396   /* Wait for a reply, return good/bad news  */
10397   W (ret);
10398   return ret;
10399 }
10400
10401 static int
10402 api_set_arp_neighbor_limit (vat_main_t * vam)
10403 {
10404   unformat_input_t *i = vam->input;
10405   vl_api_set_arp_neighbor_limit_t *mp;
10406   u32 arp_nbr_limit;
10407   u8 limit_set = 0;
10408   u8 is_ipv6 = 0;
10409   int ret;
10410
10411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10412     {
10413       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10414         limit_set = 1;
10415       else if (unformat (i, "ipv6"))
10416         is_ipv6 = 1;
10417       else
10418         {
10419           clib_warning ("parse error '%U'", format_unformat_error, i);
10420           return -99;
10421         }
10422     }
10423
10424   if (limit_set == 0)
10425     {
10426       errmsg ("missing limit value");
10427       return -99;
10428     }
10429
10430   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10431
10432   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10433   mp->is_ipv6 = is_ipv6;
10434
10435   S (mp);
10436   W (ret);
10437   return ret;
10438 }
10439
10440 static int
10441 api_l2_patch_add_del (vat_main_t * vam)
10442 {
10443   unformat_input_t *i = vam->input;
10444   vl_api_l2_patch_add_del_t *mp;
10445   u32 rx_sw_if_index;
10446   u8 rx_sw_if_index_set = 0;
10447   u32 tx_sw_if_index;
10448   u8 tx_sw_if_index_set = 0;
10449   u8 is_add = 1;
10450   int ret;
10451
10452   /* Parse args required to build the message */
10453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10454     {
10455       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10456         rx_sw_if_index_set = 1;
10457       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10458         tx_sw_if_index_set = 1;
10459       else if (unformat (i, "rx"))
10460         {
10461           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10462             {
10463               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10464                             &rx_sw_if_index))
10465                 rx_sw_if_index_set = 1;
10466             }
10467           else
10468             break;
10469         }
10470       else if (unformat (i, "tx"))
10471         {
10472           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10473             {
10474               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10475                             &tx_sw_if_index))
10476                 tx_sw_if_index_set = 1;
10477             }
10478           else
10479             break;
10480         }
10481       else if (unformat (i, "del"))
10482         is_add = 0;
10483       else
10484         break;
10485     }
10486
10487   if (rx_sw_if_index_set == 0)
10488     {
10489       errmsg ("missing rx interface name or rx_sw_if_index");
10490       return -99;
10491     }
10492
10493   if (tx_sw_if_index_set == 0)
10494     {
10495       errmsg ("missing tx interface name or tx_sw_if_index");
10496       return -99;
10497     }
10498
10499   M (L2_PATCH_ADD_DEL, mp);
10500
10501   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10502   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10503   mp->is_add = is_add;
10504
10505   S (mp);
10506   W (ret);
10507   return ret;
10508 }
10509
10510 u8 is_del;
10511 u8 localsid_addr[16];
10512 u8 end_psp;
10513 u8 behavior;
10514 u32 sw_if_index;
10515 u32 vlan_index;
10516 u32 fib_table;
10517 u8 nh_addr[16];
10518
10519 static int
10520 api_sr_localsid_add_del (vat_main_t * vam)
10521 {
10522   unformat_input_t *i = vam->input;
10523   vl_api_sr_localsid_add_del_t *mp;
10524
10525   u8 is_del;
10526   ip6_address_t localsid;
10527   u8 end_psp = 0;
10528   u8 behavior = ~0;
10529   u32 sw_if_index;
10530   u32 fib_table = ~(u32) 0;
10531   ip6_address_t nh_addr6;
10532   ip4_address_t nh_addr4;
10533   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10534   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10535
10536   bool nexthop_set = 0;
10537
10538   int ret;
10539
10540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10541     {
10542       if (unformat (i, "del"))
10543         is_del = 1;
10544       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10545       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10546         nexthop_set = 1;
10547       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10548         nexthop_set = 1;
10549       else if (unformat (i, "behavior %u", &behavior));
10550       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10551       else if (unformat (i, "fib-table %u", &fib_table));
10552       else if (unformat (i, "end.psp %u", &behavior));
10553       else
10554         break;
10555     }
10556
10557   M (SR_LOCALSID_ADD_DEL, mp);
10558
10559   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10560   if (nexthop_set)
10561     {
10562       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10563       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10564     }
10565   mp->behavior = behavior;
10566   mp->sw_if_index = ntohl (sw_if_index);
10567   mp->fib_table = ntohl (fib_table);
10568   mp->end_psp = end_psp;
10569   mp->is_del = is_del;
10570
10571   S (mp);
10572   W (ret);
10573   return ret;
10574 }
10575
10576 static int
10577 api_ioam_enable (vat_main_t * vam)
10578 {
10579   unformat_input_t *input = vam->input;
10580   vl_api_ioam_enable_t *mp;
10581   u32 id = 0;
10582   int has_trace_option = 0;
10583   int has_pot_option = 0;
10584   int has_seqno_option = 0;
10585   int has_analyse_option = 0;
10586   int ret;
10587
10588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10589     {
10590       if (unformat (input, "trace"))
10591         has_trace_option = 1;
10592       else if (unformat (input, "pot"))
10593         has_pot_option = 1;
10594       else if (unformat (input, "seqno"))
10595         has_seqno_option = 1;
10596       else if (unformat (input, "analyse"))
10597         has_analyse_option = 1;
10598       else
10599         break;
10600     }
10601   M (IOAM_ENABLE, mp);
10602   mp->id = htons (id);
10603   mp->seqno = has_seqno_option;
10604   mp->analyse = has_analyse_option;
10605   mp->pot_enable = has_pot_option;
10606   mp->trace_enable = has_trace_option;
10607
10608   S (mp);
10609   W (ret);
10610   return ret;
10611 }
10612
10613
10614 static int
10615 api_ioam_disable (vat_main_t * vam)
10616 {
10617   vl_api_ioam_disable_t *mp;
10618   int ret;
10619
10620   M (IOAM_DISABLE, mp);
10621   S (mp);
10622   W (ret);
10623   return ret;
10624 }
10625
10626 #define foreach_tcp_proto_field                 \
10627 _(src_port)                                     \
10628 _(dst_port)
10629
10630 #define foreach_udp_proto_field                 \
10631 _(src_port)                                     \
10632 _(dst_port)
10633
10634 #define foreach_ip4_proto_field                 \
10635 _(src_address)                                  \
10636 _(dst_address)                                  \
10637 _(tos)                                          \
10638 _(length)                                       \
10639 _(fragment_id)                                  \
10640 _(ttl)                                          \
10641 _(protocol)                                     \
10642 _(checksum)
10643
10644 typedef struct
10645 {
10646   u16 src_port, dst_port;
10647 } tcpudp_header_t;
10648
10649 #if VPP_API_TEST_BUILTIN == 0
10650 uword
10651 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10652 {
10653   u8 **maskp = va_arg (*args, u8 **);
10654   u8 *mask = 0;
10655   u8 found_something = 0;
10656   tcp_header_t *tcp;
10657
10658 #define _(a) u8 a=0;
10659   foreach_tcp_proto_field;
10660 #undef _
10661
10662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10663     {
10664       if (0);
10665 #define _(a) else if (unformat (input, #a)) a=1;
10666       foreach_tcp_proto_field
10667 #undef _
10668         else
10669         break;
10670     }
10671
10672 #define _(a) found_something += a;
10673   foreach_tcp_proto_field;
10674 #undef _
10675
10676   if (found_something == 0)
10677     return 0;
10678
10679   vec_validate (mask, sizeof (*tcp) - 1);
10680
10681   tcp = (tcp_header_t *) mask;
10682
10683 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10684   foreach_tcp_proto_field;
10685 #undef _
10686
10687   *maskp = mask;
10688   return 1;
10689 }
10690
10691 uword
10692 unformat_udp_mask (unformat_input_t * input, va_list * args)
10693 {
10694   u8 **maskp = va_arg (*args, u8 **);
10695   u8 *mask = 0;
10696   u8 found_something = 0;
10697   udp_header_t *udp;
10698
10699 #define _(a) u8 a=0;
10700   foreach_udp_proto_field;
10701 #undef _
10702
10703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10704     {
10705       if (0);
10706 #define _(a) else if (unformat (input, #a)) a=1;
10707       foreach_udp_proto_field
10708 #undef _
10709         else
10710         break;
10711     }
10712
10713 #define _(a) found_something += a;
10714   foreach_udp_proto_field;
10715 #undef _
10716
10717   if (found_something == 0)
10718     return 0;
10719
10720   vec_validate (mask, sizeof (*udp) - 1);
10721
10722   udp = (udp_header_t *) mask;
10723
10724 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10725   foreach_udp_proto_field;
10726 #undef _
10727
10728   *maskp = mask;
10729   return 1;
10730 }
10731
10732 uword
10733 unformat_l4_mask (unformat_input_t * input, va_list * args)
10734 {
10735   u8 **maskp = va_arg (*args, u8 **);
10736   u16 src_port = 0, dst_port = 0;
10737   tcpudp_header_t *tcpudp;
10738
10739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10740     {
10741       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10742         return 1;
10743       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10744         return 1;
10745       else if (unformat (input, "src_port"))
10746         src_port = 0xFFFF;
10747       else if (unformat (input, "dst_port"))
10748         dst_port = 0xFFFF;
10749       else
10750         return 0;
10751     }
10752
10753   if (!src_port && !dst_port)
10754     return 0;
10755
10756   u8 *mask = 0;
10757   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10758
10759   tcpudp = (tcpudp_header_t *) mask;
10760   tcpudp->src_port = src_port;
10761   tcpudp->dst_port = dst_port;
10762
10763   *maskp = mask;
10764
10765   return 1;
10766 }
10767
10768 uword
10769 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10770 {
10771   u8 **maskp = va_arg (*args, u8 **);
10772   u8 *mask = 0;
10773   u8 found_something = 0;
10774   ip4_header_t *ip;
10775
10776 #define _(a) u8 a=0;
10777   foreach_ip4_proto_field;
10778 #undef _
10779   u8 version = 0;
10780   u8 hdr_length = 0;
10781
10782
10783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10784     {
10785       if (unformat (input, "version"))
10786         version = 1;
10787       else if (unformat (input, "hdr_length"))
10788         hdr_length = 1;
10789       else if (unformat (input, "src"))
10790         src_address = 1;
10791       else if (unformat (input, "dst"))
10792         dst_address = 1;
10793       else if (unformat (input, "proto"))
10794         protocol = 1;
10795
10796 #define _(a) else if (unformat (input, #a)) a=1;
10797       foreach_ip4_proto_field
10798 #undef _
10799         else
10800         break;
10801     }
10802
10803 #define _(a) found_something += a;
10804   foreach_ip4_proto_field;
10805 #undef _
10806
10807   if (found_something == 0)
10808     return 0;
10809
10810   vec_validate (mask, sizeof (*ip) - 1);
10811
10812   ip = (ip4_header_t *) mask;
10813
10814 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10815   foreach_ip4_proto_field;
10816 #undef _
10817
10818   ip->ip_version_and_header_length = 0;
10819
10820   if (version)
10821     ip->ip_version_and_header_length |= 0xF0;
10822
10823   if (hdr_length)
10824     ip->ip_version_and_header_length |= 0x0F;
10825
10826   *maskp = mask;
10827   return 1;
10828 }
10829
10830 #define foreach_ip6_proto_field                 \
10831 _(src_address)                                  \
10832 _(dst_address)                                  \
10833 _(payload_length)                               \
10834 _(hop_limit)                                    \
10835 _(protocol)
10836
10837 uword
10838 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10839 {
10840   u8 **maskp = va_arg (*args, u8 **);
10841   u8 *mask = 0;
10842   u8 found_something = 0;
10843   ip6_header_t *ip;
10844   u32 ip_version_traffic_class_and_flow_label;
10845
10846 #define _(a) u8 a=0;
10847   foreach_ip6_proto_field;
10848 #undef _
10849   u8 version = 0;
10850   u8 traffic_class = 0;
10851   u8 flow_label = 0;
10852
10853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10854     {
10855       if (unformat (input, "version"))
10856         version = 1;
10857       else if (unformat (input, "traffic-class"))
10858         traffic_class = 1;
10859       else if (unformat (input, "flow-label"))
10860         flow_label = 1;
10861       else if (unformat (input, "src"))
10862         src_address = 1;
10863       else if (unformat (input, "dst"))
10864         dst_address = 1;
10865       else if (unformat (input, "proto"))
10866         protocol = 1;
10867
10868 #define _(a) else if (unformat (input, #a)) a=1;
10869       foreach_ip6_proto_field
10870 #undef _
10871         else
10872         break;
10873     }
10874
10875 #define _(a) found_something += a;
10876   foreach_ip6_proto_field;
10877 #undef _
10878
10879   if (found_something == 0)
10880     return 0;
10881
10882   vec_validate (mask, sizeof (*ip) - 1);
10883
10884   ip = (ip6_header_t *) mask;
10885
10886 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10887   foreach_ip6_proto_field;
10888 #undef _
10889
10890   ip_version_traffic_class_and_flow_label = 0;
10891
10892   if (version)
10893     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10894
10895   if (traffic_class)
10896     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10897
10898   if (flow_label)
10899     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10900
10901   ip->ip_version_traffic_class_and_flow_label =
10902     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10903
10904   *maskp = mask;
10905   return 1;
10906 }
10907
10908 uword
10909 unformat_l3_mask (unformat_input_t * input, va_list * args)
10910 {
10911   u8 **maskp = va_arg (*args, u8 **);
10912
10913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10914     {
10915       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10916         return 1;
10917       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10918         return 1;
10919       else
10920         break;
10921     }
10922   return 0;
10923 }
10924
10925 uword
10926 unformat_l2_mask (unformat_input_t * input, va_list * args)
10927 {
10928   u8 **maskp = va_arg (*args, u8 **);
10929   u8 *mask = 0;
10930   u8 src = 0;
10931   u8 dst = 0;
10932   u8 proto = 0;
10933   u8 tag1 = 0;
10934   u8 tag2 = 0;
10935   u8 ignore_tag1 = 0;
10936   u8 ignore_tag2 = 0;
10937   u8 cos1 = 0;
10938   u8 cos2 = 0;
10939   u8 dot1q = 0;
10940   u8 dot1ad = 0;
10941   int len = 14;
10942
10943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10944     {
10945       if (unformat (input, "src"))
10946         src = 1;
10947       else if (unformat (input, "dst"))
10948         dst = 1;
10949       else if (unformat (input, "proto"))
10950         proto = 1;
10951       else if (unformat (input, "tag1"))
10952         tag1 = 1;
10953       else if (unformat (input, "tag2"))
10954         tag2 = 1;
10955       else if (unformat (input, "ignore-tag1"))
10956         ignore_tag1 = 1;
10957       else if (unformat (input, "ignore-tag2"))
10958         ignore_tag2 = 1;
10959       else if (unformat (input, "cos1"))
10960         cos1 = 1;
10961       else if (unformat (input, "cos2"))
10962         cos2 = 1;
10963       else if (unformat (input, "dot1q"))
10964         dot1q = 1;
10965       else if (unformat (input, "dot1ad"))
10966         dot1ad = 1;
10967       else
10968         break;
10969     }
10970   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10971        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10972     return 0;
10973
10974   if (tag1 || ignore_tag1 || cos1 || dot1q)
10975     len = 18;
10976   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10977     len = 22;
10978
10979   vec_validate (mask, len - 1);
10980
10981   if (dst)
10982     clib_memset (mask, 0xff, 6);
10983
10984   if (src)
10985     clib_memset (mask + 6, 0xff, 6);
10986
10987   if (tag2 || dot1ad)
10988     {
10989       /* inner vlan tag */
10990       if (tag2)
10991         {
10992           mask[19] = 0xff;
10993           mask[18] = 0x0f;
10994         }
10995       if (cos2)
10996         mask[18] |= 0xe0;
10997       if (proto)
10998         mask[21] = mask[20] = 0xff;
10999       if (tag1)
11000         {
11001           mask[15] = 0xff;
11002           mask[14] = 0x0f;
11003         }
11004       if (cos1)
11005         mask[14] |= 0xe0;
11006       *maskp = mask;
11007       return 1;
11008     }
11009   if (tag1 | dot1q)
11010     {
11011       if (tag1)
11012         {
11013           mask[15] = 0xff;
11014           mask[14] = 0x0f;
11015         }
11016       if (cos1)
11017         mask[14] |= 0xe0;
11018       if (proto)
11019         mask[16] = mask[17] = 0xff;
11020
11021       *maskp = mask;
11022       return 1;
11023     }
11024   if (cos2)
11025     mask[18] |= 0xe0;
11026   if (cos1)
11027     mask[14] |= 0xe0;
11028   if (proto)
11029     mask[12] = mask[13] = 0xff;
11030
11031   *maskp = mask;
11032   return 1;
11033 }
11034
11035 uword
11036 unformat_classify_mask (unformat_input_t * input, va_list * args)
11037 {
11038   u8 **maskp = va_arg (*args, u8 **);
11039   u32 *skipp = va_arg (*args, u32 *);
11040   u32 *matchp = va_arg (*args, u32 *);
11041   u32 match;
11042   u8 *mask = 0;
11043   u8 *l2 = 0;
11044   u8 *l3 = 0;
11045   u8 *l4 = 0;
11046   int i;
11047
11048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11049     {
11050       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11051         ;
11052       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11053         ;
11054       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11055         ;
11056       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11057         ;
11058       else
11059         break;
11060     }
11061
11062   if (l4 && !l3)
11063     {
11064       vec_free (mask);
11065       vec_free (l2);
11066       vec_free (l4);
11067       return 0;
11068     }
11069
11070   if (mask || l2 || l3 || l4)
11071     {
11072       if (l2 || l3 || l4)
11073         {
11074           /* "With a free Ethernet header in every package" */
11075           if (l2 == 0)
11076             vec_validate (l2, 13);
11077           mask = l2;
11078           if (vec_len (l3))
11079             {
11080               vec_append (mask, l3);
11081               vec_free (l3);
11082             }
11083           if (vec_len (l4))
11084             {
11085               vec_append (mask, l4);
11086               vec_free (l4);
11087             }
11088         }
11089
11090       /* Scan forward looking for the first significant mask octet */
11091       for (i = 0; i < vec_len (mask); i++)
11092         if (mask[i])
11093           break;
11094
11095       /* compute (skip, match) params */
11096       *skipp = i / sizeof (u32x4);
11097       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11098
11099       /* Pad mask to an even multiple of the vector size */
11100       while (vec_len (mask) % sizeof (u32x4))
11101         vec_add1 (mask, 0);
11102
11103       match = vec_len (mask) / sizeof (u32x4);
11104
11105       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11106         {
11107           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11108           if (*tmp || *(tmp + 1))
11109             break;
11110           match--;
11111         }
11112       if (match == 0)
11113         clib_warning ("BUG: match 0");
11114
11115       _vec_len (mask) = match * sizeof (u32x4);
11116
11117       *matchp = match;
11118       *maskp = mask;
11119
11120       return 1;
11121     }
11122
11123   return 0;
11124 }
11125 #endif /* VPP_API_TEST_BUILTIN */
11126
11127 #define foreach_l2_next                         \
11128 _(drop, DROP)                                   \
11129 _(ethernet, ETHERNET_INPUT)                     \
11130 _(ip4, IP4_INPUT)                               \
11131 _(ip6, IP6_INPUT)
11132
11133 uword
11134 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11135 {
11136   u32 *miss_next_indexp = va_arg (*args, u32 *);
11137   u32 next_index = 0;
11138   u32 tmp;
11139
11140 #define _(n,N) \
11141   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11142   foreach_l2_next;
11143 #undef _
11144
11145   if (unformat (input, "%d", &tmp))
11146     {
11147       next_index = tmp;
11148       goto out;
11149     }
11150
11151   return 0;
11152
11153 out:
11154   *miss_next_indexp = next_index;
11155   return 1;
11156 }
11157
11158 #define foreach_ip_next                         \
11159 _(drop, DROP)                                   \
11160 _(local, LOCAL)                                 \
11161 _(rewrite, REWRITE)
11162
11163 uword
11164 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11165 {
11166   u32 *miss_next_indexp = va_arg (*args, u32 *);
11167   u32 next_index = 0;
11168   u32 tmp;
11169
11170 #define _(n,N) \
11171   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11172   foreach_ip_next;
11173 #undef _
11174
11175   if (unformat (input, "%d", &tmp))
11176     {
11177       next_index = tmp;
11178       goto out;
11179     }
11180
11181   return 0;
11182
11183 out:
11184   *miss_next_indexp = next_index;
11185   return 1;
11186 }
11187
11188 #define foreach_acl_next                        \
11189 _(deny, DENY)
11190
11191 uword
11192 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11193 {
11194   u32 *miss_next_indexp = va_arg (*args, u32 *);
11195   u32 next_index = 0;
11196   u32 tmp;
11197
11198 #define _(n,N) \
11199   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11200   foreach_acl_next;
11201 #undef _
11202
11203   if (unformat (input, "permit"))
11204     {
11205       next_index = ~0;
11206       goto out;
11207     }
11208   else if (unformat (input, "%d", &tmp))
11209     {
11210       next_index = tmp;
11211       goto out;
11212     }
11213
11214   return 0;
11215
11216 out:
11217   *miss_next_indexp = next_index;
11218   return 1;
11219 }
11220
11221 uword
11222 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11223 {
11224   u32 *r = va_arg (*args, u32 *);
11225
11226   if (unformat (input, "conform-color"))
11227     *r = POLICE_CONFORM;
11228   else if (unformat (input, "exceed-color"))
11229     *r = POLICE_EXCEED;
11230   else
11231     return 0;
11232
11233   return 1;
11234 }
11235
11236 static int
11237 api_classify_add_del_table (vat_main_t * vam)
11238 {
11239   unformat_input_t *i = vam->input;
11240   vl_api_classify_add_del_table_t *mp;
11241
11242   u32 nbuckets = 2;
11243   u32 skip = ~0;
11244   u32 match = ~0;
11245   int is_add = 1;
11246   int del_chain = 0;
11247   u32 table_index = ~0;
11248   u32 next_table_index = ~0;
11249   u32 miss_next_index = ~0;
11250   u32 memory_size = 32 << 20;
11251   u8 *mask = 0;
11252   u32 current_data_flag = 0;
11253   int current_data_offset = 0;
11254   int ret;
11255
11256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11257     {
11258       if (unformat (i, "del"))
11259         is_add = 0;
11260       else if (unformat (i, "del-chain"))
11261         {
11262           is_add = 0;
11263           del_chain = 1;
11264         }
11265       else if (unformat (i, "buckets %d", &nbuckets))
11266         ;
11267       else if (unformat (i, "memory_size %d", &memory_size))
11268         ;
11269       else if (unformat (i, "skip %d", &skip))
11270         ;
11271       else if (unformat (i, "match %d", &match))
11272         ;
11273       else if (unformat (i, "table %d", &table_index))
11274         ;
11275       else if (unformat (i, "mask %U", unformat_classify_mask,
11276                          &mask, &skip, &match))
11277         ;
11278       else if (unformat (i, "next-table %d", &next_table_index))
11279         ;
11280       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11281                          &miss_next_index))
11282         ;
11283       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11284                          &miss_next_index))
11285         ;
11286       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11287                          &miss_next_index))
11288         ;
11289       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11290         ;
11291       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11292         ;
11293       else
11294         break;
11295     }
11296
11297   if (is_add && mask == 0)
11298     {
11299       errmsg ("Mask required");
11300       return -99;
11301     }
11302
11303   if (is_add && skip == ~0)
11304     {
11305       errmsg ("skip count required");
11306       return -99;
11307     }
11308
11309   if (is_add && match == ~0)
11310     {
11311       errmsg ("match count required");
11312       return -99;
11313     }
11314
11315   if (!is_add && table_index == ~0)
11316     {
11317       errmsg ("table index required for delete");
11318       return -99;
11319     }
11320
11321   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11322
11323   mp->is_add = is_add;
11324   mp->del_chain = del_chain;
11325   mp->table_index = ntohl (table_index);
11326   mp->nbuckets = ntohl (nbuckets);
11327   mp->memory_size = ntohl (memory_size);
11328   mp->skip_n_vectors = ntohl (skip);
11329   mp->match_n_vectors = ntohl (match);
11330   mp->next_table_index = ntohl (next_table_index);
11331   mp->miss_next_index = ntohl (miss_next_index);
11332   mp->current_data_flag = ntohl (current_data_flag);
11333   mp->current_data_offset = ntohl (current_data_offset);
11334   mp->mask_len = ntohl (vec_len (mask));
11335   clib_memcpy (mp->mask, mask, vec_len (mask));
11336
11337   vec_free (mask);
11338
11339   S (mp);
11340   W (ret);
11341   return ret;
11342 }
11343
11344 #if VPP_API_TEST_BUILTIN == 0
11345 uword
11346 unformat_l4_match (unformat_input_t * input, va_list * args)
11347 {
11348   u8 **matchp = va_arg (*args, u8 **);
11349
11350   u8 *proto_header = 0;
11351   int src_port = 0;
11352   int dst_port = 0;
11353
11354   tcpudp_header_t h;
11355
11356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11357     {
11358       if (unformat (input, "src_port %d", &src_port))
11359         ;
11360       else if (unformat (input, "dst_port %d", &dst_port))
11361         ;
11362       else
11363         return 0;
11364     }
11365
11366   h.src_port = clib_host_to_net_u16 (src_port);
11367   h.dst_port = clib_host_to_net_u16 (dst_port);
11368   vec_validate (proto_header, sizeof (h) - 1);
11369   memcpy (proto_header, &h, sizeof (h));
11370
11371   *matchp = proto_header;
11372
11373   return 1;
11374 }
11375
11376 uword
11377 unformat_ip4_match (unformat_input_t * input, va_list * args)
11378 {
11379   u8 **matchp = va_arg (*args, u8 **);
11380   u8 *match = 0;
11381   ip4_header_t *ip;
11382   int version = 0;
11383   u32 version_val;
11384   int hdr_length = 0;
11385   u32 hdr_length_val;
11386   int src = 0, dst = 0;
11387   ip4_address_t src_val, dst_val;
11388   int proto = 0;
11389   u32 proto_val;
11390   int tos = 0;
11391   u32 tos_val;
11392   int length = 0;
11393   u32 length_val;
11394   int fragment_id = 0;
11395   u32 fragment_id_val;
11396   int ttl = 0;
11397   int ttl_val;
11398   int checksum = 0;
11399   u32 checksum_val;
11400
11401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11402     {
11403       if (unformat (input, "version %d", &version_val))
11404         version = 1;
11405       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11406         hdr_length = 1;
11407       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11408         src = 1;
11409       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11410         dst = 1;
11411       else if (unformat (input, "proto %d", &proto_val))
11412         proto = 1;
11413       else if (unformat (input, "tos %d", &tos_val))
11414         tos = 1;
11415       else if (unformat (input, "length %d", &length_val))
11416         length = 1;
11417       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11418         fragment_id = 1;
11419       else if (unformat (input, "ttl %d", &ttl_val))
11420         ttl = 1;
11421       else if (unformat (input, "checksum %d", &checksum_val))
11422         checksum = 1;
11423       else
11424         break;
11425     }
11426
11427   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11428       + ttl + checksum == 0)
11429     return 0;
11430
11431   /*
11432    * Aligned because we use the real comparison functions
11433    */
11434   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11435
11436   ip = (ip4_header_t *) match;
11437
11438   /* These are realistically matched in practice */
11439   if (src)
11440     ip->src_address.as_u32 = src_val.as_u32;
11441
11442   if (dst)
11443     ip->dst_address.as_u32 = dst_val.as_u32;
11444
11445   if (proto)
11446     ip->protocol = proto_val;
11447
11448
11449   /* These are not, but they're included for completeness */
11450   if (version)
11451     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11452
11453   if (hdr_length)
11454     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11455
11456   if (tos)
11457     ip->tos = tos_val;
11458
11459   if (length)
11460     ip->length = clib_host_to_net_u16 (length_val);
11461
11462   if (ttl)
11463     ip->ttl = ttl_val;
11464
11465   if (checksum)
11466     ip->checksum = clib_host_to_net_u16 (checksum_val);
11467
11468   *matchp = match;
11469   return 1;
11470 }
11471
11472 uword
11473 unformat_ip6_match (unformat_input_t * input, va_list * args)
11474 {
11475   u8 **matchp = va_arg (*args, u8 **);
11476   u8 *match = 0;
11477   ip6_header_t *ip;
11478   int version = 0;
11479   u32 version_val;
11480   u8 traffic_class = 0;
11481   u32 traffic_class_val = 0;
11482   u8 flow_label = 0;
11483   u8 flow_label_val;
11484   int src = 0, dst = 0;
11485   ip6_address_t src_val, dst_val;
11486   int proto = 0;
11487   u32 proto_val;
11488   int payload_length = 0;
11489   u32 payload_length_val;
11490   int hop_limit = 0;
11491   int hop_limit_val;
11492   u32 ip_version_traffic_class_and_flow_label;
11493
11494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11495     {
11496       if (unformat (input, "version %d", &version_val))
11497         version = 1;
11498       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11499         traffic_class = 1;
11500       else if (unformat (input, "flow_label %d", &flow_label_val))
11501         flow_label = 1;
11502       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11503         src = 1;
11504       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11505         dst = 1;
11506       else if (unformat (input, "proto %d", &proto_val))
11507         proto = 1;
11508       else if (unformat (input, "payload_length %d", &payload_length_val))
11509         payload_length = 1;
11510       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11511         hop_limit = 1;
11512       else
11513         break;
11514     }
11515
11516   if (version + traffic_class + flow_label + src + dst + proto +
11517       payload_length + hop_limit == 0)
11518     return 0;
11519
11520   /*
11521    * Aligned because we use the real comparison functions
11522    */
11523   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11524
11525   ip = (ip6_header_t *) match;
11526
11527   if (src)
11528     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11529
11530   if (dst)
11531     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11532
11533   if (proto)
11534     ip->protocol = proto_val;
11535
11536   ip_version_traffic_class_and_flow_label = 0;
11537
11538   if (version)
11539     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11540
11541   if (traffic_class)
11542     ip_version_traffic_class_and_flow_label |=
11543       (traffic_class_val & 0xFF) << 20;
11544
11545   if (flow_label)
11546     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11547
11548   ip->ip_version_traffic_class_and_flow_label =
11549     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11550
11551   if (payload_length)
11552     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11553
11554   if (hop_limit)
11555     ip->hop_limit = hop_limit_val;
11556
11557   *matchp = match;
11558   return 1;
11559 }
11560
11561 uword
11562 unformat_l3_match (unformat_input_t * input, va_list * args)
11563 {
11564   u8 **matchp = va_arg (*args, u8 **);
11565
11566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11567     {
11568       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11569         return 1;
11570       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11571         return 1;
11572       else
11573         break;
11574     }
11575   return 0;
11576 }
11577
11578 uword
11579 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11580 {
11581   u8 *tagp = va_arg (*args, u8 *);
11582   u32 tag;
11583
11584   if (unformat (input, "%d", &tag))
11585     {
11586       tagp[0] = (tag >> 8) & 0x0F;
11587       tagp[1] = tag & 0xFF;
11588       return 1;
11589     }
11590
11591   return 0;
11592 }
11593
11594 uword
11595 unformat_l2_match (unformat_input_t * input, va_list * args)
11596 {
11597   u8 **matchp = va_arg (*args, u8 **);
11598   u8 *match = 0;
11599   u8 src = 0;
11600   u8 src_val[6];
11601   u8 dst = 0;
11602   u8 dst_val[6];
11603   u8 proto = 0;
11604   u16 proto_val;
11605   u8 tag1 = 0;
11606   u8 tag1_val[2];
11607   u8 tag2 = 0;
11608   u8 tag2_val[2];
11609   int len = 14;
11610   u8 ignore_tag1 = 0;
11611   u8 ignore_tag2 = 0;
11612   u8 cos1 = 0;
11613   u8 cos2 = 0;
11614   u32 cos1_val = 0;
11615   u32 cos2_val = 0;
11616
11617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11618     {
11619       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11620         src = 1;
11621       else
11622         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11623         dst = 1;
11624       else if (unformat (input, "proto %U",
11625                          unformat_ethernet_type_host_byte_order, &proto_val))
11626         proto = 1;
11627       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11628         tag1 = 1;
11629       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11630         tag2 = 1;
11631       else if (unformat (input, "ignore-tag1"))
11632         ignore_tag1 = 1;
11633       else if (unformat (input, "ignore-tag2"))
11634         ignore_tag2 = 1;
11635       else if (unformat (input, "cos1 %d", &cos1_val))
11636         cos1 = 1;
11637       else if (unformat (input, "cos2 %d", &cos2_val))
11638         cos2 = 1;
11639       else
11640         break;
11641     }
11642   if ((src + dst + proto + tag1 + tag2 +
11643        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11644     return 0;
11645
11646   if (tag1 || ignore_tag1 || cos1)
11647     len = 18;
11648   if (tag2 || ignore_tag2 || cos2)
11649     len = 22;
11650
11651   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11652
11653   if (dst)
11654     clib_memcpy (match, dst_val, 6);
11655
11656   if (src)
11657     clib_memcpy (match + 6, src_val, 6);
11658
11659   if (tag2)
11660     {
11661       /* inner vlan tag */
11662       match[19] = tag2_val[1];
11663       match[18] = tag2_val[0];
11664       if (cos2)
11665         match[18] |= (cos2_val & 0x7) << 5;
11666       if (proto)
11667         {
11668           match[21] = proto_val & 0xff;
11669           match[20] = proto_val >> 8;
11670         }
11671       if (tag1)
11672         {
11673           match[15] = tag1_val[1];
11674           match[14] = tag1_val[0];
11675         }
11676       if (cos1)
11677         match[14] |= (cos1_val & 0x7) << 5;
11678       *matchp = match;
11679       return 1;
11680     }
11681   if (tag1)
11682     {
11683       match[15] = tag1_val[1];
11684       match[14] = tag1_val[0];
11685       if (proto)
11686         {
11687           match[17] = proto_val & 0xff;
11688           match[16] = proto_val >> 8;
11689         }
11690       if (cos1)
11691         match[14] |= (cos1_val & 0x7) << 5;
11692
11693       *matchp = match;
11694       return 1;
11695     }
11696   if (cos2)
11697     match[18] |= (cos2_val & 0x7) << 5;
11698   if (cos1)
11699     match[14] |= (cos1_val & 0x7) << 5;
11700   if (proto)
11701     {
11702       match[13] = proto_val & 0xff;
11703       match[12] = proto_val >> 8;
11704     }
11705
11706   *matchp = match;
11707   return 1;
11708 }
11709
11710 uword
11711 unformat_qos_source (unformat_input_t * input, va_list * args)
11712 {
11713   int *qs = va_arg (*args, int *);
11714
11715   if (unformat (input, "ip"))
11716     *qs = QOS_SOURCE_IP;
11717   else if (unformat (input, "mpls"))
11718     *qs = QOS_SOURCE_MPLS;
11719   else if (unformat (input, "ext"))
11720     *qs = QOS_SOURCE_EXT;
11721   else if (unformat (input, "vlan"))
11722     *qs = QOS_SOURCE_VLAN;
11723   else
11724     return 0;
11725
11726   return 1;
11727 }
11728 #endif
11729
11730 uword
11731 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11732 {
11733   u8 **matchp = va_arg (*args, u8 **);
11734   u32 skip_n_vectors = va_arg (*args, u32);
11735   u32 match_n_vectors = va_arg (*args, u32);
11736
11737   u8 *match = 0;
11738   u8 *l2 = 0;
11739   u8 *l3 = 0;
11740   u8 *l4 = 0;
11741
11742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11743     {
11744       if (unformat (input, "hex %U", unformat_hex_string, &match))
11745         ;
11746       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11747         ;
11748       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11749         ;
11750       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11751         ;
11752       else
11753         break;
11754     }
11755
11756   if (l4 && !l3)
11757     {
11758       vec_free (match);
11759       vec_free (l2);
11760       vec_free (l4);
11761       return 0;
11762     }
11763
11764   if (match || l2 || l3 || l4)
11765     {
11766       if (l2 || l3 || l4)
11767         {
11768           /* "Win a free Ethernet header in every packet" */
11769           if (l2 == 0)
11770             vec_validate_aligned (l2, 13, sizeof (u32x4));
11771           match = l2;
11772           if (vec_len (l3))
11773             {
11774               vec_append_aligned (match, l3, sizeof (u32x4));
11775               vec_free (l3);
11776             }
11777           if (vec_len (l4))
11778             {
11779               vec_append_aligned (match, l4, sizeof (u32x4));
11780               vec_free (l4);
11781             }
11782         }
11783
11784       /* Make sure the vector is big enough even if key is all 0's */
11785       vec_validate_aligned
11786         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11787          sizeof (u32x4));
11788
11789       /* Set size, include skipped vectors */
11790       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11791
11792       *matchp = match;
11793
11794       return 1;
11795     }
11796
11797   return 0;
11798 }
11799
11800 static int
11801 api_classify_add_del_session (vat_main_t * vam)
11802 {
11803   unformat_input_t *i = vam->input;
11804   vl_api_classify_add_del_session_t *mp;
11805   int is_add = 1;
11806   u32 table_index = ~0;
11807   u32 hit_next_index = ~0;
11808   u32 opaque_index = ~0;
11809   u8 *match = 0;
11810   i32 advance = 0;
11811   u32 skip_n_vectors = 0;
11812   u32 match_n_vectors = 0;
11813   u32 action = 0;
11814   u32 metadata = 0;
11815   int ret;
11816
11817   /*
11818    * Warning: you have to supply skip_n and match_n
11819    * because the API client cant simply look at the classify
11820    * table object.
11821    */
11822
11823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11824     {
11825       if (unformat (i, "del"))
11826         is_add = 0;
11827       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11828                          &hit_next_index))
11829         ;
11830       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11831                          &hit_next_index))
11832         ;
11833       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11834                          &hit_next_index))
11835         ;
11836       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11837         ;
11838       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11839         ;
11840       else if (unformat (i, "opaque-index %d", &opaque_index))
11841         ;
11842       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11843         ;
11844       else if (unformat (i, "match_n %d", &match_n_vectors))
11845         ;
11846       else if (unformat (i, "match %U", api_unformat_classify_match,
11847                          &match, skip_n_vectors, match_n_vectors))
11848         ;
11849       else if (unformat (i, "advance %d", &advance))
11850         ;
11851       else if (unformat (i, "table-index %d", &table_index))
11852         ;
11853       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11854         action = 1;
11855       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11856         action = 2;
11857       else if (unformat (i, "action %d", &action))
11858         ;
11859       else if (unformat (i, "metadata %d", &metadata))
11860         ;
11861       else
11862         break;
11863     }
11864
11865   if (table_index == ~0)
11866     {
11867       errmsg ("Table index required");
11868       return -99;
11869     }
11870
11871   if (is_add && match == 0)
11872     {
11873       errmsg ("Match value required");
11874       return -99;
11875     }
11876
11877   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11878
11879   mp->is_add = is_add;
11880   mp->table_index = ntohl (table_index);
11881   mp->hit_next_index = ntohl (hit_next_index);
11882   mp->opaque_index = ntohl (opaque_index);
11883   mp->advance = ntohl (advance);
11884   mp->action = action;
11885   mp->metadata = ntohl (metadata);
11886   mp->match_len = ntohl (vec_len (match));
11887   clib_memcpy (mp->match, match, vec_len (match));
11888   vec_free (match);
11889
11890   S (mp);
11891   W (ret);
11892   return ret;
11893 }
11894
11895 static int
11896 api_classify_set_interface_ip_table (vat_main_t * vam)
11897 {
11898   unformat_input_t *i = vam->input;
11899   vl_api_classify_set_interface_ip_table_t *mp;
11900   u32 sw_if_index;
11901   int sw_if_index_set;
11902   u32 table_index = ~0;
11903   u8 is_ipv6 = 0;
11904   int ret;
11905
11906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11907     {
11908       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11909         sw_if_index_set = 1;
11910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11911         sw_if_index_set = 1;
11912       else if (unformat (i, "table %d", &table_index))
11913         ;
11914       else
11915         {
11916           clib_warning ("parse error '%U'", format_unformat_error, i);
11917           return -99;
11918         }
11919     }
11920
11921   if (sw_if_index_set == 0)
11922     {
11923       errmsg ("missing interface name or sw_if_index");
11924       return -99;
11925     }
11926
11927
11928   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11929
11930   mp->sw_if_index = ntohl (sw_if_index);
11931   mp->table_index = ntohl (table_index);
11932   mp->is_ipv6 = is_ipv6;
11933
11934   S (mp);
11935   W (ret);
11936   return ret;
11937 }
11938
11939 static int
11940 api_classify_set_interface_l2_tables (vat_main_t * vam)
11941 {
11942   unformat_input_t *i = vam->input;
11943   vl_api_classify_set_interface_l2_tables_t *mp;
11944   u32 sw_if_index;
11945   int sw_if_index_set;
11946   u32 ip4_table_index = ~0;
11947   u32 ip6_table_index = ~0;
11948   u32 other_table_index = ~0;
11949   u32 is_input = 1;
11950   int ret;
11951
11952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11953     {
11954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11955         sw_if_index_set = 1;
11956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11957         sw_if_index_set = 1;
11958       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11959         ;
11960       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11961         ;
11962       else if (unformat (i, "other-table %d", &other_table_index))
11963         ;
11964       else if (unformat (i, "is-input %d", &is_input))
11965         ;
11966       else
11967         {
11968           clib_warning ("parse error '%U'", format_unformat_error, i);
11969           return -99;
11970         }
11971     }
11972
11973   if (sw_if_index_set == 0)
11974     {
11975       errmsg ("missing interface name or sw_if_index");
11976       return -99;
11977     }
11978
11979
11980   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11981
11982   mp->sw_if_index = ntohl (sw_if_index);
11983   mp->ip4_table_index = ntohl (ip4_table_index);
11984   mp->ip6_table_index = ntohl (ip6_table_index);
11985   mp->other_table_index = ntohl (other_table_index);
11986   mp->is_input = (u8) is_input;
11987
11988   S (mp);
11989   W (ret);
11990   return ret;
11991 }
11992
11993 static int
11994 api_set_ipfix_exporter (vat_main_t * vam)
11995 {
11996   unformat_input_t *i = vam->input;
11997   vl_api_set_ipfix_exporter_t *mp;
11998   ip4_address_t collector_address;
11999   u8 collector_address_set = 0;
12000   u32 collector_port = ~0;
12001   ip4_address_t src_address;
12002   u8 src_address_set = 0;
12003   u32 vrf_id = ~0;
12004   u32 path_mtu = ~0;
12005   u32 template_interval = ~0;
12006   u8 udp_checksum = 0;
12007   int ret;
12008
12009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12010     {
12011       if (unformat (i, "collector_address %U", unformat_ip4_address,
12012                     &collector_address))
12013         collector_address_set = 1;
12014       else if (unformat (i, "collector_port %d", &collector_port))
12015         ;
12016       else if (unformat (i, "src_address %U", unformat_ip4_address,
12017                          &src_address))
12018         src_address_set = 1;
12019       else if (unformat (i, "vrf_id %d", &vrf_id))
12020         ;
12021       else if (unformat (i, "path_mtu %d", &path_mtu))
12022         ;
12023       else if (unformat (i, "template_interval %d", &template_interval))
12024         ;
12025       else if (unformat (i, "udp_checksum"))
12026         udp_checksum = 1;
12027       else
12028         break;
12029     }
12030
12031   if (collector_address_set == 0)
12032     {
12033       errmsg ("collector_address required");
12034       return -99;
12035     }
12036
12037   if (src_address_set == 0)
12038     {
12039       errmsg ("src_address required");
12040       return -99;
12041     }
12042
12043   M (SET_IPFIX_EXPORTER, mp);
12044
12045   memcpy (mp->collector_address, collector_address.data,
12046           sizeof (collector_address.data));
12047   mp->collector_port = htons ((u16) collector_port);
12048   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12049   mp->vrf_id = htonl (vrf_id);
12050   mp->path_mtu = htonl (path_mtu);
12051   mp->template_interval = htonl (template_interval);
12052   mp->udp_checksum = udp_checksum;
12053
12054   S (mp);
12055   W (ret);
12056   return ret;
12057 }
12058
12059 static int
12060 api_set_ipfix_classify_stream (vat_main_t * vam)
12061 {
12062   unformat_input_t *i = vam->input;
12063   vl_api_set_ipfix_classify_stream_t *mp;
12064   u32 domain_id = 0;
12065   u32 src_port = UDP_DST_PORT_ipfix;
12066   int ret;
12067
12068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12069     {
12070       if (unformat (i, "domain %d", &domain_id))
12071         ;
12072       else if (unformat (i, "src_port %d", &src_port))
12073         ;
12074       else
12075         {
12076           errmsg ("unknown input `%U'", format_unformat_error, i);
12077           return -99;
12078         }
12079     }
12080
12081   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12082
12083   mp->domain_id = htonl (domain_id);
12084   mp->src_port = htons ((u16) src_port);
12085
12086   S (mp);
12087   W (ret);
12088   return ret;
12089 }
12090
12091 static int
12092 api_ipfix_classify_table_add_del (vat_main_t * vam)
12093 {
12094   unformat_input_t *i = vam->input;
12095   vl_api_ipfix_classify_table_add_del_t *mp;
12096   int is_add = -1;
12097   u32 classify_table_index = ~0;
12098   u8 ip_version = 0;
12099   u8 transport_protocol = 255;
12100   int ret;
12101
12102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12103     {
12104       if (unformat (i, "add"))
12105         is_add = 1;
12106       else if (unformat (i, "del"))
12107         is_add = 0;
12108       else if (unformat (i, "table %d", &classify_table_index))
12109         ;
12110       else if (unformat (i, "ip4"))
12111         ip_version = 4;
12112       else if (unformat (i, "ip6"))
12113         ip_version = 6;
12114       else if (unformat (i, "tcp"))
12115         transport_protocol = 6;
12116       else if (unformat (i, "udp"))
12117         transport_protocol = 17;
12118       else
12119         {
12120           errmsg ("unknown input `%U'", format_unformat_error, i);
12121           return -99;
12122         }
12123     }
12124
12125   if (is_add == -1)
12126     {
12127       errmsg ("expecting: add|del");
12128       return -99;
12129     }
12130   if (classify_table_index == ~0)
12131     {
12132       errmsg ("classifier table not specified");
12133       return -99;
12134     }
12135   if (ip_version == 0)
12136     {
12137       errmsg ("IP version not specified");
12138       return -99;
12139     }
12140
12141   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12142
12143   mp->is_add = is_add;
12144   mp->table_id = htonl (classify_table_index);
12145   mp->ip_version = ip_version;
12146   mp->transport_protocol = transport_protocol;
12147
12148   S (mp);
12149   W (ret);
12150   return ret;
12151 }
12152
12153 static int
12154 api_get_node_index (vat_main_t * vam)
12155 {
12156   unformat_input_t *i = vam->input;
12157   vl_api_get_node_index_t *mp;
12158   u8 *name = 0;
12159   int ret;
12160
12161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12162     {
12163       if (unformat (i, "node %s", &name))
12164         ;
12165       else
12166         break;
12167     }
12168   if (name == 0)
12169     {
12170       errmsg ("node name required");
12171       return -99;
12172     }
12173   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12174     {
12175       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12176       return -99;
12177     }
12178
12179   M (GET_NODE_INDEX, mp);
12180   clib_memcpy (mp->node_name, name, vec_len (name));
12181   vec_free (name);
12182
12183   S (mp);
12184   W (ret);
12185   return ret;
12186 }
12187
12188 static int
12189 api_get_next_index (vat_main_t * vam)
12190 {
12191   unformat_input_t *i = vam->input;
12192   vl_api_get_next_index_t *mp;
12193   u8 *node_name = 0, *next_node_name = 0;
12194   int ret;
12195
12196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12197     {
12198       if (unformat (i, "node-name %s", &node_name))
12199         ;
12200       else if (unformat (i, "next-node-name %s", &next_node_name))
12201         break;
12202     }
12203
12204   if (node_name == 0)
12205     {
12206       errmsg ("node name required");
12207       return -99;
12208     }
12209   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12210     {
12211       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12212       return -99;
12213     }
12214
12215   if (next_node_name == 0)
12216     {
12217       errmsg ("next node name required");
12218       return -99;
12219     }
12220   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12221     {
12222       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12223       return -99;
12224     }
12225
12226   M (GET_NEXT_INDEX, mp);
12227   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12228   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12229   vec_free (node_name);
12230   vec_free (next_node_name);
12231
12232   S (mp);
12233   W (ret);
12234   return ret;
12235 }
12236
12237 static int
12238 api_add_node_next (vat_main_t * vam)
12239 {
12240   unformat_input_t *i = vam->input;
12241   vl_api_add_node_next_t *mp;
12242   u8 *name = 0;
12243   u8 *next = 0;
12244   int ret;
12245
12246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12247     {
12248       if (unformat (i, "node %s", &name))
12249         ;
12250       else if (unformat (i, "next %s", &next))
12251         ;
12252       else
12253         break;
12254     }
12255   if (name == 0)
12256     {
12257       errmsg ("node name required");
12258       return -99;
12259     }
12260   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12261     {
12262       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12263       return -99;
12264     }
12265   if (next == 0)
12266     {
12267       errmsg ("next node required");
12268       return -99;
12269     }
12270   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12271     {
12272       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12273       return -99;
12274     }
12275
12276   M (ADD_NODE_NEXT, mp);
12277   clib_memcpy (mp->node_name, name, vec_len (name));
12278   clib_memcpy (mp->next_name, next, vec_len (next));
12279   vec_free (name);
12280   vec_free (next);
12281
12282   S (mp);
12283   W (ret);
12284   return ret;
12285 }
12286
12287 static int
12288 api_l2tpv3_create_tunnel (vat_main_t * vam)
12289 {
12290   unformat_input_t *i = vam->input;
12291   ip6_address_t client_address, our_address;
12292   int client_address_set = 0;
12293   int our_address_set = 0;
12294   u32 local_session_id = 0;
12295   u32 remote_session_id = 0;
12296   u64 local_cookie = 0;
12297   u64 remote_cookie = 0;
12298   u8 l2_sublayer_present = 0;
12299   vl_api_l2tpv3_create_tunnel_t *mp;
12300   int ret;
12301
12302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12303     {
12304       if (unformat (i, "client_address %U", unformat_ip6_address,
12305                     &client_address))
12306         client_address_set = 1;
12307       else if (unformat (i, "our_address %U", unformat_ip6_address,
12308                          &our_address))
12309         our_address_set = 1;
12310       else if (unformat (i, "local_session_id %d", &local_session_id))
12311         ;
12312       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12313         ;
12314       else if (unformat (i, "local_cookie %lld", &local_cookie))
12315         ;
12316       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12317         ;
12318       else if (unformat (i, "l2-sublayer-present"))
12319         l2_sublayer_present = 1;
12320       else
12321         break;
12322     }
12323
12324   if (client_address_set == 0)
12325     {
12326       errmsg ("client_address required");
12327       return -99;
12328     }
12329
12330   if (our_address_set == 0)
12331     {
12332       errmsg ("our_address required");
12333       return -99;
12334     }
12335
12336   M (L2TPV3_CREATE_TUNNEL, mp);
12337
12338   clib_memcpy (mp->client_address, client_address.as_u8,
12339                sizeof (mp->client_address));
12340
12341   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12342
12343   mp->local_session_id = ntohl (local_session_id);
12344   mp->remote_session_id = ntohl (remote_session_id);
12345   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12346   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12347   mp->l2_sublayer_present = l2_sublayer_present;
12348   mp->is_ipv6 = 1;
12349
12350   S (mp);
12351   W (ret);
12352   return ret;
12353 }
12354
12355 static int
12356 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12357 {
12358   unformat_input_t *i = vam->input;
12359   u32 sw_if_index;
12360   u8 sw_if_index_set = 0;
12361   u64 new_local_cookie = 0;
12362   u64 new_remote_cookie = 0;
12363   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12364   int ret;
12365
12366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12367     {
12368       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12369         sw_if_index_set = 1;
12370       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12371         sw_if_index_set = 1;
12372       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12373         ;
12374       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12375         ;
12376       else
12377         break;
12378     }
12379
12380   if (sw_if_index_set == 0)
12381     {
12382       errmsg ("missing interface name or sw_if_index");
12383       return -99;
12384     }
12385
12386   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12387
12388   mp->sw_if_index = ntohl (sw_if_index);
12389   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12390   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12391
12392   S (mp);
12393   W (ret);
12394   return ret;
12395 }
12396
12397 static int
12398 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12399 {
12400   unformat_input_t *i = vam->input;
12401   vl_api_l2tpv3_interface_enable_disable_t *mp;
12402   u32 sw_if_index;
12403   u8 sw_if_index_set = 0;
12404   u8 enable_disable = 1;
12405   int ret;
12406
12407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12408     {
12409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12410         sw_if_index_set = 1;
12411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12412         sw_if_index_set = 1;
12413       else if (unformat (i, "enable"))
12414         enable_disable = 1;
12415       else if (unformat (i, "disable"))
12416         enable_disable = 0;
12417       else
12418         break;
12419     }
12420
12421   if (sw_if_index_set == 0)
12422     {
12423       errmsg ("missing interface name or sw_if_index");
12424       return -99;
12425     }
12426
12427   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12428
12429   mp->sw_if_index = ntohl (sw_if_index);
12430   mp->enable_disable = enable_disable;
12431
12432   S (mp);
12433   W (ret);
12434   return ret;
12435 }
12436
12437 static int
12438 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12439 {
12440   unformat_input_t *i = vam->input;
12441   vl_api_l2tpv3_set_lookup_key_t *mp;
12442   u8 key = ~0;
12443   int ret;
12444
12445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12446     {
12447       if (unformat (i, "lookup_v6_src"))
12448         key = L2T_LOOKUP_SRC_ADDRESS;
12449       else if (unformat (i, "lookup_v6_dst"))
12450         key = L2T_LOOKUP_DST_ADDRESS;
12451       else if (unformat (i, "lookup_session_id"))
12452         key = L2T_LOOKUP_SESSION_ID;
12453       else
12454         break;
12455     }
12456
12457   if (key == (u8) ~ 0)
12458     {
12459       errmsg ("l2tp session lookup key unset");
12460       return -99;
12461     }
12462
12463   M (L2TPV3_SET_LOOKUP_KEY, mp);
12464
12465   mp->key = key;
12466
12467   S (mp);
12468   W (ret);
12469   return ret;
12470 }
12471
12472 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12473   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12474 {
12475   vat_main_t *vam = &vat_main;
12476
12477   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12478          format_ip6_address, mp->our_address,
12479          format_ip6_address, mp->client_address,
12480          clib_net_to_host_u32 (mp->sw_if_index));
12481
12482   print (vam->ofp,
12483          "   local cookies %016llx %016llx remote cookie %016llx",
12484          clib_net_to_host_u64 (mp->local_cookie[0]),
12485          clib_net_to_host_u64 (mp->local_cookie[1]),
12486          clib_net_to_host_u64 (mp->remote_cookie));
12487
12488   print (vam->ofp, "   local session-id %d remote session-id %d",
12489          clib_net_to_host_u32 (mp->local_session_id),
12490          clib_net_to_host_u32 (mp->remote_session_id));
12491
12492   print (vam->ofp, "   l2 specific sublayer %s\n",
12493          mp->l2_sublayer_present ? "preset" : "absent");
12494
12495 }
12496
12497 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12498   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12499 {
12500   vat_main_t *vam = &vat_main;
12501   vat_json_node_t *node = NULL;
12502   struct in6_addr addr;
12503
12504   if (VAT_JSON_ARRAY != vam->json_tree.type)
12505     {
12506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12507       vat_json_init_array (&vam->json_tree);
12508     }
12509   node = vat_json_array_add (&vam->json_tree);
12510
12511   vat_json_init_object (node);
12512
12513   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12514   vat_json_object_add_ip6 (node, "our_address", addr);
12515   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12516   vat_json_object_add_ip6 (node, "client_address", addr);
12517
12518   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12519   vat_json_init_array (lc);
12520   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12521   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12522   vat_json_object_add_uint (node, "remote_cookie",
12523                             clib_net_to_host_u64 (mp->remote_cookie));
12524
12525   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12526   vat_json_object_add_uint (node, "local_session_id",
12527                             clib_net_to_host_u32 (mp->local_session_id));
12528   vat_json_object_add_uint (node, "remote_session_id",
12529                             clib_net_to_host_u32 (mp->remote_session_id));
12530   vat_json_object_add_string_copy (node, "l2_sublayer",
12531                                    mp->l2_sublayer_present ? (u8 *) "present"
12532                                    : (u8 *) "absent");
12533 }
12534
12535 static int
12536 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12537 {
12538   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12539   vl_api_control_ping_t *mp_ping;
12540   int ret;
12541
12542   /* Get list of l2tpv3-tunnel interfaces */
12543   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12544   S (mp);
12545
12546   /* Use a control ping for synchronization */
12547   MPING (CONTROL_PING, mp_ping);
12548   S (mp_ping);
12549
12550   W (ret);
12551   return ret;
12552 }
12553
12554
12555 static void vl_api_sw_interface_tap_v2_details_t_handler
12556   (vl_api_sw_interface_tap_v2_details_t * mp)
12557 {
12558   vat_main_t *vam = &vat_main;
12559
12560   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12561                     mp->host_ip4_prefix_len);
12562   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12563                     mp->host_ip6_prefix_len);
12564
12565   print (vam->ofp,
12566          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12567          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12568          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12569          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12570          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12571
12572   vec_free (ip4);
12573   vec_free (ip6);
12574 }
12575
12576 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12577   (vl_api_sw_interface_tap_v2_details_t * mp)
12578 {
12579   vat_main_t *vam = &vat_main;
12580   vat_json_node_t *node = NULL;
12581
12582   if (VAT_JSON_ARRAY != vam->json_tree.type)
12583     {
12584       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12585       vat_json_init_array (&vam->json_tree);
12586     }
12587   node = vat_json_array_add (&vam->json_tree);
12588
12589   vat_json_init_object (node);
12590   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12591   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12592   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12593   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12594   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12595   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12596   vat_json_object_add_string_copy (node, "host_mac_addr",
12597                                    format (0, "%U", format_ethernet_address,
12598                                            &mp->host_mac_addr));
12599   vat_json_object_add_string_copy (node, "host_namespace",
12600                                    mp->host_namespace);
12601   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12602   vat_json_object_add_string_copy (node, "host_ip4_addr",
12603                                    format (0, "%U/%d", format_ip4_address,
12604                                            mp->host_ip4_addr,
12605                                            mp->host_ip4_prefix_len));
12606   vat_json_object_add_string_copy (node, "host_ip6_addr",
12607                                    format (0, "%U/%d", format_ip6_address,
12608                                            mp->host_ip6_addr,
12609                                            mp->host_ip6_prefix_len));
12610
12611 }
12612
12613 static int
12614 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12615 {
12616   vl_api_sw_interface_tap_v2_dump_t *mp;
12617   vl_api_control_ping_t *mp_ping;
12618   int ret;
12619
12620   print (vam->ofp,
12621          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12622          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12623          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12624          "host_ip6_addr");
12625
12626   /* Get list of tap interfaces */
12627   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12628   S (mp);
12629
12630   /* Use a control ping for synchronization */
12631   MPING (CONTROL_PING, mp_ping);
12632   S (mp_ping);
12633
12634   W (ret);
12635   return ret;
12636 }
12637
12638 static void vl_api_sw_interface_virtio_pci_details_t_handler
12639   (vl_api_sw_interface_virtio_pci_details_t * mp)
12640 {
12641   vat_main_t *vam = &vat_main;
12642
12643   typedef union
12644   {
12645     struct
12646     {
12647       u16 domain;
12648       u8 bus;
12649       u8 slot:5;
12650       u8 function:3;
12651     };
12652     u32 as_u32;
12653   } pci_addr_t;
12654   pci_addr_t addr;
12655   addr.as_u32 = ntohl (mp->pci_addr);
12656   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12657                          addr.slot, addr.function);
12658
12659   print (vam->ofp,
12660          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12661          pci_addr, ntohl (mp->sw_if_index),
12662          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12663          format_ethernet_address, mp->mac_addr,
12664          clib_net_to_host_u64 (mp->features));
12665   vec_free (pci_addr);
12666 }
12667
12668 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12669   (vl_api_sw_interface_virtio_pci_details_t * mp)
12670 {
12671   vat_main_t *vam = &vat_main;
12672   vat_json_node_t *node = NULL;
12673
12674   if (VAT_JSON_ARRAY != vam->json_tree.type)
12675     {
12676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12677       vat_json_init_array (&vam->json_tree);
12678     }
12679   node = vat_json_array_add (&vam->json_tree);
12680
12681   vat_json_init_object (node);
12682   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12683   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12684   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12685   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12686   vat_json_object_add_uint (node, "features",
12687                             clib_net_to_host_u64 (mp->features));
12688   vat_json_object_add_string_copy (node, "mac_addr",
12689                                    format (0, "%U", format_ethernet_address,
12690                                            &mp->mac_addr));
12691 }
12692
12693 static int
12694 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12695 {
12696   vl_api_sw_interface_virtio_pci_dump_t *mp;
12697   vl_api_control_ping_t *mp_ping;
12698   int ret;
12699
12700   print (vam->ofp,
12701          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12702          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12703          "mac_addr", "features");
12704
12705   /* Get list of tap interfaces */
12706   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12707   S (mp);
12708
12709   /* Use a control ping for synchronization */
12710   MPING (CONTROL_PING, mp_ping);
12711   S (mp_ping);
12712
12713   W (ret);
12714   return ret;
12715 }
12716
12717 static int
12718 api_vxlan_offload_rx (vat_main_t * vam)
12719 {
12720   unformat_input_t *line_input = vam->input;
12721   vl_api_vxlan_offload_rx_t *mp;
12722   u32 hw_if_index = ~0, rx_if_index = ~0;
12723   u8 is_add = 1;
12724   int ret;
12725
12726   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12727     {
12728       if (unformat (line_input, "del"))
12729         is_add = 0;
12730       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12731                          &hw_if_index))
12732         ;
12733       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12734         ;
12735       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12736                          &rx_if_index))
12737         ;
12738       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12739         ;
12740       else
12741         {
12742           errmsg ("parse error '%U'", format_unformat_error, line_input);
12743           return -99;
12744         }
12745     }
12746
12747   if (hw_if_index == ~0)
12748     {
12749       errmsg ("no hw interface");
12750       return -99;
12751     }
12752
12753   if (rx_if_index == ~0)
12754     {
12755       errmsg ("no rx tunnel");
12756       return -99;
12757     }
12758
12759   M (VXLAN_OFFLOAD_RX, mp);
12760
12761   mp->hw_if_index = ntohl (hw_if_index);
12762   mp->sw_if_index = ntohl (rx_if_index);
12763   mp->enable = is_add;
12764
12765   S (mp);
12766   W (ret);
12767   return ret;
12768 }
12769
12770 static uword unformat_vxlan_decap_next
12771   (unformat_input_t * input, va_list * args)
12772 {
12773   u32 *result = va_arg (*args, u32 *);
12774   u32 tmp;
12775
12776   if (unformat (input, "l2"))
12777     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12778   else if (unformat (input, "%d", &tmp))
12779     *result = tmp;
12780   else
12781     return 0;
12782   return 1;
12783 }
12784
12785 static int
12786 api_vxlan_add_del_tunnel (vat_main_t * vam)
12787 {
12788   unformat_input_t *line_input = vam->input;
12789   vl_api_vxlan_add_del_tunnel_t *mp;
12790   ip46_address_t src, dst;
12791   u8 is_add = 1;
12792   u8 ipv4_set = 0, ipv6_set = 0;
12793   u8 src_set = 0;
12794   u8 dst_set = 0;
12795   u8 grp_set = 0;
12796   u32 instance = ~0;
12797   u32 mcast_sw_if_index = ~0;
12798   u32 encap_vrf_id = 0;
12799   u32 decap_next_index = ~0;
12800   u32 vni = 0;
12801   int ret;
12802
12803   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12804   clib_memset (&src, 0, sizeof src);
12805   clib_memset (&dst, 0, sizeof dst);
12806
12807   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12808     {
12809       if (unformat (line_input, "del"))
12810         is_add = 0;
12811       else if (unformat (line_input, "instance %d", &instance))
12812         ;
12813       else
12814         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12815         {
12816           ipv4_set = 1;
12817           src_set = 1;
12818         }
12819       else
12820         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12821         {
12822           ipv4_set = 1;
12823           dst_set = 1;
12824         }
12825       else
12826         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12827         {
12828           ipv6_set = 1;
12829           src_set = 1;
12830         }
12831       else
12832         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12833         {
12834           ipv6_set = 1;
12835           dst_set = 1;
12836         }
12837       else if (unformat (line_input, "group %U %U",
12838                          unformat_ip4_address, &dst.ip4,
12839                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12840         {
12841           grp_set = dst_set = 1;
12842           ipv4_set = 1;
12843         }
12844       else if (unformat (line_input, "group %U",
12845                          unformat_ip4_address, &dst.ip4))
12846         {
12847           grp_set = dst_set = 1;
12848           ipv4_set = 1;
12849         }
12850       else if (unformat (line_input, "group %U %U",
12851                          unformat_ip6_address, &dst.ip6,
12852                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12853         {
12854           grp_set = dst_set = 1;
12855           ipv6_set = 1;
12856         }
12857       else if (unformat (line_input, "group %U",
12858                          unformat_ip6_address, &dst.ip6))
12859         {
12860           grp_set = dst_set = 1;
12861           ipv6_set = 1;
12862         }
12863       else
12864         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12865         ;
12866       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12867         ;
12868       else if (unformat (line_input, "decap-next %U",
12869                          unformat_vxlan_decap_next, &decap_next_index))
12870         ;
12871       else if (unformat (line_input, "vni %d", &vni))
12872         ;
12873       else
12874         {
12875           errmsg ("parse error '%U'", format_unformat_error, line_input);
12876           return -99;
12877         }
12878     }
12879
12880   if (src_set == 0)
12881     {
12882       errmsg ("tunnel src address not specified");
12883       return -99;
12884     }
12885   if (dst_set == 0)
12886     {
12887       errmsg ("tunnel dst address not specified");
12888       return -99;
12889     }
12890
12891   if (grp_set && !ip46_address_is_multicast (&dst))
12892     {
12893       errmsg ("tunnel group address not multicast");
12894       return -99;
12895     }
12896   if (grp_set && mcast_sw_if_index == ~0)
12897     {
12898       errmsg ("tunnel nonexistent multicast device");
12899       return -99;
12900     }
12901   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12902     {
12903       errmsg ("tunnel dst address must be unicast");
12904       return -99;
12905     }
12906
12907
12908   if (ipv4_set && ipv6_set)
12909     {
12910       errmsg ("both IPv4 and IPv6 addresses specified");
12911       return -99;
12912     }
12913
12914   if ((vni == 0) || (vni >> 24))
12915     {
12916       errmsg ("vni not specified or out of range");
12917       return -99;
12918     }
12919
12920   M (VXLAN_ADD_DEL_TUNNEL, mp);
12921
12922   if (ipv6_set)
12923     {
12924       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12925       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12926     }
12927   else
12928     {
12929       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12930       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12931     }
12932
12933   mp->instance = htonl (instance);
12934   mp->encap_vrf_id = ntohl (encap_vrf_id);
12935   mp->decap_next_index = ntohl (decap_next_index);
12936   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12937   mp->vni = ntohl (vni);
12938   mp->is_add = is_add;
12939   mp->is_ipv6 = ipv6_set;
12940
12941   S (mp);
12942   W (ret);
12943   return ret;
12944 }
12945
12946 static void vl_api_vxlan_tunnel_details_t_handler
12947   (vl_api_vxlan_tunnel_details_t * mp)
12948 {
12949   vat_main_t *vam = &vat_main;
12950   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12951   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12952
12953   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12954          ntohl (mp->sw_if_index),
12955          ntohl (mp->instance),
12956          format_ip46_address, &src, IP46_TYPE_ANY,
12957          format_ip46_address, &dst, IP46_TYPE_ANY,
12958          ntohl (mp->encap_vrf_id),
12959          ntohl (mp->decap_next_index), ntohl (mp->vni),
12960          ntohl (mp->mcast_sw_if_index));
12961 }
12962
12963 static void vl_api_vxlan_tunnel_details_t_handler_json
12964   (vl_api_vxlan_tunnel_details_t * mp)
12965 {
12966   vat_main_t *vam = &vat_main;
12967   vat_json_node_t *node = NULL;
12968
12969   if (VAT_JSON_ARRAY != vam->json_tree.type)
12970     {
12971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12972       vat_json_init_array (&vam->json_tree);
12973     }
12974   node = vat_json_array_add (&vam->json_tree);
12975
12976   vat_json_init_object (node);
12977   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12978
12979   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12980
12981   if (mp->is_ipv6)
12982     {
12983       struct in6_addr ip6;
12984
12985       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12986       vat_json_object_add_ip6 (node, "src_address", ip6);
12987       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12988       vat_json_object_add_ip6 (node, "dst_address", ip6);
12989     }
12990   else
12991     {
12992       struct in_addr ip4;
12993
12994       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12995       vat_json_object_add_ip4 (node, "src_address", ip4);
12996       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12997       vat_json_object_add_ip4 (node, "dst_address", ip4);
12998     }
12999   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13000   vat_json_object_add_uint (node, "decap_next_index",
13001                             ntohl (mp->decap_next_index));
13002   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13003   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13004   vat_json_object_add_uint (node, "mcast_sw_if_index",
13005                             ntohl (mp->mcast_sw_if_index));
13006 }
13007
13008 static int
13009 api_vxlan_tunnel_dump (vat_main_t * vam)
13010 {
13011   unformat_input_t *i = vam->input;
13012   vl_api_vxlan_tunnel_dump_t *mp;
13013   vl_api_control_ping_t *mp_ping;
13014   u32 sw_if_index;
13015   u8 sw_if_index_set = 0;
13016   int ret;
13017
13018   /* Parse args required to build the message */
13019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13020     {
13021       if (unformat (i, "sw_if_index %d", &sw_if_index))
13022         sw_if_index_set = 1;
13023       else
13024         break;
13025     }
13026
13027   if (sw_if_index_set == 0)
13028     {
13029       sw_if_index = ~0;
13030     }
13031
13032   if (!vam->json_output)
13033     {
13034       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13035              "sw_if_index", "instance", "src_address", "dst_address",
13036              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13037     }
13038
13039   /* Get list of vxlan-tunnel interfaces */
13040   M (VXLAN_TUNNEL_DUMP, mp);
13041
13042   mp->sw_if_index = htonl (sw_if_index);
13043
13044   S (mp);
13045
13046   /* Use a control ping for synchronization */
13047   MPING (CONTROL_PING, mp_ping);
13048   S (mp_ping);
13049
13050   W (ret);
13051   return ret;
13052 }
13053
13054 static uword unformat_geneve_decap_next
13055   (unformat_input_t * input, va_list * args)
13056 {
13057   u32 *result = va_arg (*args, u32 *);
13058   u32 tmp;
13059
13060   if (unformat (input, "l2"))
13061     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13062   else if (unformat (input, "%d", &tmp))
13063     *result = tmp;
13064   else
13065     return 0;
13066   return 1;
13067 }
13068
13069 static int
13070 api_geneve_add_del_tunnel (vat_main_t * vam)
13071 {
13072   unformat_input_t *line_input = vam->input;
13073   vl_api_geneve_add_del_tunnel_t *mp;
13074   ip46_address_t src, dst;
13075   u8 is_add = 1;
13076   u8 ipv4_set = 0, ipv6_set = 0;
13077   u8 src_set = 0;
13078   u8 dst_set = 0;
13079   u8 grp_set = 0;
13080   u32 mcast_sw_if_index = ~0;
13081   u32 encap_vrf_id = 0;
13082   u32 decap_next_index = ~0;
13083   u32 vni = 0;
13084   int ret;
13085
13086   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13087   clib_memset (&src, 0, sizeof src);
13088   clib_memset (&dst, 0, sizeof dst);
13089
13090   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13091     {
13092       if (unformat (line_input, "del"))
13093         is_add = 0;
13094       else
13095         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13096         {
13097           ipv4_set = 1;
13098           src_set = 1;
13099         }
13100       else
13101         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13102         {
13103           ipv4_set = 1;
13104           dst_set = 1;
13105         }
13106       else
13107         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13108         {
13109           ipv6_set = 1;
13110           src_set = 1;
13111         }
13112       else
13113         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13114         {
13115           ipv6_set = 1;
13116           dst_set = 1;
13117         }
13118       else if (unformat (line_input, "group %U %U",
13119                          unformat_ip4_address, &dst.ip4,
13120                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13121         {
13122           grp_set = dst_set = 1;
13123           ipv4_set = 1;
13124         }
13125       else if (unformat (line_input, "group %U",
13126                          unformat_ip4_address, &dst.ip4))
13127         {
13128           grp_set = dst_set = 1;
13129           ipv4_set = 1;
13130         }
13131       else if (unformat (line_input, "group %U %U",
13132                          unformat_ip6_address, &dst.ip6,
13133                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13134         {
13135           grp_set = dst_set = 1;
13136           ipv6_set = 1;
13137         }
13138       else if (unformat (line_input, "group %U",
13139                          unformat_ip6_address, &dst.ip6))
13140         {
13141           grp_set = dst_set = 1;
13142           ipv6_set = 1;
13143         }
13144       else
13145         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13146         ;
13147       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13148         ;
13149       else if (unformat (line_input, "decap-next %U",
13150                          unformat_geneve_decap_next, &decap_next_index))
13151         ;
13152       else if (unformat (line_input, "vni %d", &vni))
13153         ;
13154       else
13155         {
13156           errmsg ("parse error '%U'", format_unformat_error, line_input);
13157           return -99;
13158         }
13159     }
13160
13161   if (src_set == 0)
13162     {
13163       errmsg ("tunnel src address not specified");
13164       return -99;
13165     }
13166   if (dst_set == 0)
13167     {
13168       errmsg ("tunnel dst address not specified");
13169       return -99;
13170     }
13171
13172   if (grp_set && !ip46_address_is_multicast (&dst))
13173     {
13174       errmsg ("tunnel group address not multicast");
13175       return -99;
13176     }
13177   if (grp_set && mcast_sw_if_index == ~0)
13178     {
13179       errmsg ("tunnel nonexistent multicast device");
13180       return -99;
13181     }
13182   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13183     {
13184       errmsg ("tunnel dst address must be unicast");
13185       return -99;
13186     }
13187
13188
13189   if (ipv4_set && ipv6_set)
13190     {
13191       errmsg ("both IPv4 and IPv6 addresses specified");
13192       return -99;
13193     }
13194
13195   if ((vni == 0) || (vni >> 24))
13196     {
13197       errmsg ("vni not specified or out of range");
13198       return -99;
13199     }
13200
13201   M (GENEVE_ADD_DEL_TUNNEL, mp);
13202
13203   if (ipv6_set)
13204     {
13205       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13206       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13207     }
13208   else
13209     {
13210       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13211       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13212     }
13213   mp->encap_vrf_id = ntohl (encap_vrf_id);
13214   mp->decap_next_index = ntohl (decap_next_index);
13215   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13216   mp->vni = ntohl (vni);
13217   mp->is_add = is_add;
13218   mp->is_ipv6 = ipv6_set;
13219
13220   S (mp);
13221   W (ret);
13222   return ret;
13223 }
13224
13225 static void vl_api_geneve_tunnel_details_t_handler
13226   (vl_api_geneve_tunnel_details_t * mp)
13227 {
13228   vat_main_t *vam = &vat_main;
13229   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13230   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13231
13232   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13233          ntohl (mp->sw_if_index),
13234          format_ip46_address, &src, IP46_TYPE_ANY,
13235          format_ip46_address, &dst, IP46_TYPE_ANY,
13236          ntohl (mp->encap_vrf_id),
13237          ntohl (mp->decap_next_index), ntohl (mp->vni),
13238          ntohl (mp->mcast_sw_if_index));
13239 }
13240
13241 static void vl_api_geneve_tunnel_details_t_handler_json
13242   (vl_api_geneve_tunnel_details_t * mp)
13243 {
13244   vat_main_t *vam = &vat_main;
13245   vat_json_node_t *node = NULL;
13246
13247   if (VAT_JSON_ARRAY != vam->json_tree.type)
13248     {
13249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13250       vat_json_init_array (&vam->json_tree);
13251     }
13252   node = vat_json_array_add (&vam->json_tree);
13253
13254   vat_json_init_object (node);
13255   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13256   if (mp->is_ipv6)
13257     {
13258       struct in6_addr ip6;
13259
13260       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13261       vat_json_object_add_ip6 (node, "src_address", ip6);
13262       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13263       vat_json_object_add_ip6 (node, "dst_address", ip6);
13264     }
13265   else
13266     {
13267       struct in_addr ip4;
13268
13269       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13270       vat_json_object_add_ip4 (node, "src_address", ip4);
13271       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13272       vat_json_object_add_ip4 (node, "dst_address", ip4);
13273     }
13274   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13275   vat_json_object_add_uint (node, "decap_next_index",
13276                             ntohl (mp->decap_next_index));
13277   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13278   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13279   vat_json_object_add_uint (node, "mcast_sw_if_index",
13280                             ntohl (mp->mcast_sw_if_index));
13281 }
13282
13283 static int
13284 api_geneve_tunnel_dump (vat_main_t * vam)
13285 {
13286   unformat_input_t *i = vam->input;
13287   vl_api_geneve_tunnel_dump_t *mp;
13288   vl_api_control_ping_t *mp_ping;
13289   u32 sw_if_index;
13290   u8 sw_if_index_set = 0;
13291   int ret;
13292
13293   /* Parse args required to build the message */
13294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13295     {
13296       if (unformat (i, "sw_if_index %d", &sw_if_index))
13297         sw_if_index_set = 1;
13298       else
13299         break;
13300     }
13301
13302   if (sw_if_index_set == 0)
13303     {
13304       sw_if_index = ~0;
13305     }
13306
13307   if (!vam->json_output)
13308     {
13309       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13310              "sw_if_index", "local_address", "remote_address",
13311              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13312     }
13313
13314   /* Get list of geneve-tunnel interfaces */
13315   M (GENEVE_TUNNEL_DUMP, mp);
13316
13317   mp->sw_if_index = htonl (sw_if_index);
13318
13319   S (mp);
13320
13321   /* Use a control ping for synchronization */
13322   M (CONTROL_PING, mp_ping);
13323   S (mp_ping);
13324
13325   W (ret);
13326   return ret;
13327 }
13328
13329 static int
13330 api_gre_add_del_tunnel (vat_main_t * vam)
13331 {
13332   unformat_input_t *line_input = vam->input;
13333   vl_api_gre_add_del_tunnel_t *mp;
13334   ip4_address_t src4, dst4;
13335   ip6_address_t src6, dst6;
13336   u8 is_add = 1;
13337   u8 ipv4_set = 0;
13338   u8 ipv6_set = 0;
13339   u8 t_type = GRE_TUNNEL_TYPE_L3;
13340   u8 src_set = 0;
13341   u8 dst_set = 0;
13342   u32 outer_fib_id = 0;
13343   u32 session_id = 0;
13344   u32 instance = ~0;
13345   int ret;
13346
13347   clib_memset (&src4, 0, sizeof src4);
13348   clib_memset (&dst4, 0, sizeof dst4);
13349   clib_memset (&src6, 0, sizeof src6);
13350   clib_memset (&dst6, 0, sizeof dst6);
13351
13352   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (line_input, "del"))
13355         is_add = 0;
13356       else if (unformat (line_input, "instance %d", &instance))
13357         ;
13358       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13359         {
13360           src_set = 1;
13361           ipv4_set = 1;
13362         }
13363       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13364         {
13365           dst_set = 1;
13366           ipv4_set = 1;
13367         }
13368       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13369         {
13370           src_set = 1;
13371           ipv6_set = 1;
13372         }
13373       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13374         {
13375           dst_set = 1;
13376           ipv6_set = 1;
13377         }
13378       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13379         ;
13380       else if (unformat (line_input, "teb"))
13381         t_type = GRE_TUNNEL_TYPE_TEB;
13382       else if (unformat (line_input, "erspan %d", &session_id))
13383         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13384       else
13385         {
13386           errmsg ("parse error '%U'", format_unformat_error, line_input);
13387           return -99;
13388         }
13389     }
13390
13391   if (src_set == 0)
13392     {
13393       errmsg ("tunnel src address not specified");
13394       return -99;
13395     }
13396   if (dst_set == 0)
13397     {
13398       errmsg ("tunnel dst address not specified");
13399       return -99;
13400     }
13401   if (ipv4_set && ipv6_set)
13402     {
13403       errmsg ("both IPv4 and IPv6 addresses specified");
13404       return -99;
13405     }
13406
13407
13408   M (GRE_ADD_DEL_TUNNEL, mp);
13409
13410   if (ipv4_set)
13411     {
13412       clib_memcpy (&mp->src_address, &src4, 4);
13413       clib_memcpy (&mp->dst_address, &dst4, 4);
13414     }
13415   else
13416     {
13417       clib_memcpy (&mp->src_address, &src6, 16);
13418       clib_memcpy (&mp->dst_address, &dst6, 16);
13419     }
13420   mp->instance = htonl (instance);
13421   mp->outer_fib_id = htonl (outer_fib_id);
13422   mp->is_add = is_add;
13423   mp->session_id = htons ((u16) session_id);
13424   mp->tunnel_type = t_type;
13425   mp->is_ipv6 = ipv6_set;
13426
13427   S (mp);
13428   W (ret);
13429   return ret;
13430 }
13431
13432 static void vl_api_gre_tunnel_details_t_handler
13433   (vl_api_gre_tunnel_details_t * mp)
13434 {
13435   vat_main_t *vam = &vat_main;
13436   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13437   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13438
13439   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13440          ntohl (mp->sw_if_index),
13441          ntohl (mp->instance),
13442          format_ip46_address, &src, IP46_TYPE_ANY,
13443          format_ip46_address, &dst, IP46_TYPE_ANY,
13444          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13445 }
13446
13447 static void vl_api_gre_tunnel_details_t_handler_json
13448   (vl_api_gre_tunnel_details_t * mp)
13449 {
13450   vat_main_t *vam = &vat_main;
13451   vat_json_node_t *node = NULL;
13452   struct in_addr ip4;
13453   struct in6_addr ip6;
13454
13455   if (VAT_JSON_ARRAY != vam->json_tree.type)
13456     {
13457       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13458       vat_json_init_array (&vam->json_tree);
13459     }
13460   node = vat_json_array_add (&vam->json_tree);
13461
13462   vat_json_init_object (node);
13463   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13464   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13465   if (!mp->is_ipv6)
13466     {
13467       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13468       vat_json_object_add_ip4 (node, "src_address", ip4);
13469       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13470       vat_json_object_add_ip4 (node, "dst_address", ip4);
13471     }
13472   else
13473     {
13474       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13475       vat_json_object_add_ip6 (node, "src_address", ip6);
13476       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13477       vat_json_object_add_ip6 (node, "dst_address", ip6);
13478     }
13479   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13480   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13481   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13482   vat_json_object_add_uint (node, "session_id", mp->session_id);
13483 }
13484
13485 static int
13486 api_gre_tunnel_dump (vat_main_t * vam)
13487 {
13488   unformat_input_t *i = vam->input;
13489   vl_api_gre_tunnel_dump_t *mp;
13490   vl_api_control_ping_t *mp_ping;
13491   u32 sw_if_index;
13492   u8 sw_if_index_set = 0;
13493   int ret;
13494
13495   /* Parse args required to build the message */
13496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13497     {
13498       if (unformat (i, "sw_if_index %d", &sw_if_index))
13499         sw_if_index_set = 1;
13500       else
13501         break;
13502     }
13503
13504   if (sw_if_index_set == 0)
13505     {
13506       sw_if_index = ~0;
13507     }
13508
13509   if (!vam->json_output)
13510     {
13511       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13512              "sw_if_index", "instance", "src_address", "dst_address",
13513              "tunnel_type", "outer_fib_id", "session_id");
13514     }
13515
13516   /* Get list of gre-tunnel interfaces */
13517   M (GRE_TUNNEL_DUMP, mp);
13518
13519   mp->sw_if_index = htonl (sw_if_index);
13520
13521   S (mp);
13522
13523   /* Use a control ping for synchronization */
13524   MPING (CONTROL_PING, mp_ping);
13525   S (mp_ping);
13526
13527   W (ret);
13528   return ret;
13529 }
13530
13531 static int
13532 api_l2_fib_clear_table (vat_main_t * vam)
13533 {
13534 //  unformat_input_t * i = vam->input;
13535   vl_api_l2_fib_clear_table_t *mp;
13536   int ret;
13537
13538   M (L2_FIB_CLEAR_TABLE, mp);
13539
13540   S (mp);
13541   W (ret);
13542   return ret;
13543 }
13544
13545 static int
13546 api_l2_interface_efp_filter (vat_main_t * vam)
13547 {
13548   unformat_input_t *i = vam->input;
13549   vl_api_l2_interface_efp_filter_t *mp;
13550   u32 sw_if_index;
13551   u8 enable = 1;
13552   u8 sw_if_index_set = 0;
13553   int ret;
13554
13555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13556     {
13557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13558         sw_if_index_set = 1;
13559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13560         sw_if_index_set = 1;
13561       else if (unformat (i, "enable"))
13562         enable = 1;
13563       else if (unformat (i, "disable"))
13564         enable = 0;
13565       else
13566         {
13567           clib_warning ("parse error '%U'", format_unformat_error, i);
13568           return -99;
13569         }
13570     }
13571
13572   if (sw_if_index_set == 0)
13573     {
13574       errmsg ("missing sw_if_index");
13575       return -99;
13576     }
13577
13578   M (L2_INTERFACE_EFP_FILTER, mp);
13579
13580   mp->sw_if_index = ntohl (sw_if_index);
13581   mp->enable_disable = enable;
13582
13583   S (mp);
13584   W (ret);
13585   return ret;
13586 }
13587
13588 #define foreach_vtr_op                          \
13589 _("disable",  L2_VTR_DISABLED)                  \
13590 _("push-1",  L2_VTR_PUSH_1)                     \
13591 _("push-2",  L2_VTR_PUSH_2)                     \
13592 _("pop-1",  L2_VTR_POP_1)                       \
13593 _("pop-2",  L2_VTR_POP_2)                       \
13594 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13595 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13596 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13597 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13598
13599 static int
13600 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13601 {
13602   unformat_input_t *i = vam->input;
13603   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13604   u32 sw_if_index;
13605   u8 sw_if_index_set = 0;
13606   u8 vtr_op_set = 0;
13607   u32 vtr_op = 0;
13608   u32 push_dot1q = 1;
13609   u32 tag1 = ~0;
13610   u32 tag2 = ~0;
13611   int ret;
13612
13613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13614     {
13615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13616         sw_if_index_set = 1;
13617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13618         sw_if_index_set = 1;
13619       else if (unformat (i, "vtr_op %d", &vtr_op))
13620         vtr_op_set = 1;
13621 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13622       foreach_vtr_op
13623 #undef _
13624         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13625         ;
13626       else if (unformat (i, "tag1 %d", &tag1))
13627         ;
13628       else if (unformat (i, "tag2 %d", &tag2))
13629         ;
13630       else
13631         {
13632           clib_warning ("parse error '%U'", format_unformat_error, i);
13633           return -99;
13634         }
13635     }
13636
13637   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13638     {
13639       errmsg ("missing vtr operation or sw_if_index");
13640       return -99;
13641     }
13642
13643   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13644   mp->sw_if_index = ntohl (sw_if_index);
13645   mp->vtr_op = ntohl (vtr_op);
13646   mp->push_dot1q = ntohl (push_dot1q);
13647   mp->tag1 = ntohl (tag1);
13648   mp->tag2 = ntohl (tag2);
13649
13650   S (mp);
13651   W (ret);
13652   return ret;
13653 }
13654
13655 static int
13656 api_create_vhost_user_if (vat_main_t * vam)
13657 {
13658   unformat_input_t *i = vam->input;
13659   vl_api_create_vhost_user_if_t *mp;
13660   u8 *file_name;
13661   u8 is_server = 0;
13662   u8 file_name_set = 0;
13663   u32 custom_dev_instance = ~0;
13664   u8 hwaddr[6];
13665   u8 use_custom_mac = 0;
13666   u8 disable_mrg_rxbuf = 0;
13667   u8 disable_indirect_desc = 0;
13668   u8 *tag = 0;
13669   int ret;
13670
13671   /* Shut up coverity */
13672   clib_memset (hwaddr, 0, sizeof (hwaddr));
13673
13674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13675     {
13676       if (unformat (i, "socket %s", &file_name))
13677         {
13678           file_name_set = 1;
13679         }
13680       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13681         ;
13682       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13683         use_custom_mac = 1;
13684       else if (unformat (i, "server"))
13685         is_server = 1;
13686       else if (unformat (i, "disable_mrg_rxbuf"))
13687         disable_mrg_rxbuf = 1;
13688       else if (unformat (i, "disable_indirect_desc"))
13689         disable_indirect_desc = 1;
13690       else if (unformat (i, "tag %s", &tag))
13691         ;
13692       else
13693         break;
13694     }
13695
13696   if (file_name_set == 0)
13697     {
13698       errmsg ("missing socket file name");
13699       return -99;
13700     }
13701
13702   if (vec_len (file_name) > 255)
13703     {
13704       errmsg ("socket file name too long");
13705       return -99;
13706     }
13707   vec_add1 (file_name, 0);
13708
13709   M (CREATE_VHOST_USER_IF, mp);
13710
13711   mp->is_server = is_server;
13712   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13713   mp->disable_indirect_desc = disable_indirect_desc;
13714   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13715   vec_free (file_name);
13716   if (custom_dev_instance != ~0)
13717     {
13718       mp->renumber = 1;
13719       mp->custom_dev_instance = ntohl (custom_dev_instance);
13720     }
13721
13722   mp->use_custom_mac = use_custom_mac;
13723   clib_memcpy (mp->mac_address, hwaddr, 6);
13724   if (tag)
13725     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13726   vec_free (tag);
13727
13728   S (mp);
13729   W (ret);
13730   return ret;
13731 }
13732
13733 static int
13734 api_modify_vhost_user_if (vat_main_t * vam)
13735 {
13736   unformat_input_t *i = vam->input;
13737   vl_api_modify_vhost_user_if_t *mp;
13738   u8 *file_name;
13739   u8 is_server = 0;
13740   u8 file_name_set = 0;
13741   u32 custom_dev_instance = ~0;
13742   u8 sw_if_index_set = 0;
13743   u32 sw_if_index = (u32) ~ 0;
13744   int ret;
13745
13746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13749         sw_if_index_set = 1;
13750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13751         sw_if_index_set = 1;
13752       else if (unformat (i, "socket %s", &file_name))
13753         {
13754           file_name_set = 1;
13755         }
13756       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13757         ;
13758       else if (unformat (i, "server"))
13759         is_server = 1;
13760       else
13761         break;
13762     }
13763
13764   if (sw_if_index_set == 0)
13765     {
13766       errmsg ("missing sw_if_index or interface name");
13767       return -99;
13768     }
13769
13770   if (file_name_set == 0)
13771     {
13772       errmsg ("missing socket file name");
13773       return -99;
13774     }
13775
13776   if (vec_len (file_name) > 255)
13777     {
13778       errmsg ("socket file name too long");
13779       return -99;
13780     }
13781   vec_add1 (file_name, 0);
13782
13783   M (MODIFY_VHOST_USER_IF, mp);
13784
13785   mp->sw_if_index = ntohl (sw_if_index);
13786   mp->is_server = is_server;
13787   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13788   vec_free (file_name);
13789   if (custom_dev_instance != ~0)
13790     {
13791       mp->renumber = 1;
13792       mp->custom_dev_instance = ntohl (custom_dev_instance);
13793     }
13794
13795   S (mp);
13796   W (ret);
13797   return ret;
13798 }
13799
13800 static int
13801 api_delete_vhost_user_if (vat_main_t * vam)
13802 {
13803   unformat_input_t *i = vam->input;
13804   vl_api_delete_vhost_user_if_t *mp;
13805   u32 sw_if_index = ~0;
13806   u8 sw_if_index_set = 0;
13807   int ret;
13808
13809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13810     {
13811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13812         sw_if_index_set = 1;
13813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13814         sw_if_index_set = 1;
13815       else
13816         break;
13817     }
13818
13819   if (sw_if_index_set == 0)
13820     {
13821       errmsg ("missing sw_if_index or interface name");
13822       return -99;
13823     }
13824
13825
13826   M (DELETE_VHOST_USER_IF, mp);
13827
13828   mp->sw_if_index = ntohl (sw_if_index);
13829
13830   S (mp);
13831   W (ret);
13832   return ret;
13833 }
13834
13835 static void vl_api_sw_interface_vhost_user_details_t_handler
13836   (vl_api_sw_interface_vhost_user_details_t * mp)
13837 {
13838   vat_main_t *vam = &vat_main;
13839
13840   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13841          (char *) mp->interface_name,
13842          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13843          clib_net_to_host_u64 (mp->features), mp->is_server,
13844          ntohl (mp->num_regions), (char *) mp->sock_filename);
13845   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13846 }
13847
13848 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13849   (vl_api_sw_interface_vhost_user_details_t * mp)
13850 {
13851   vat_main_t *vam = &vat_main;
13852   vat_json_node_t *node = NULL;
13853
13854   if (VAT_JSON_ARRAY != vam->json_tree.type)
13855     {
13856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13857       vat_json_init_array (&vam->json_tree);
13858     }
13859   node = vat_json_array_add (&vam->json_tree);
13860
13861   vat_json_init_object (node);
13862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13863   vat_json_object_add_string_copy (node, "interface_name",
13864                                    mp->interface_name);
13865   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13866                             ntohl (mp->virtio_net_hdr_sz));
13867   vat_json_object_add_uint (node, "features",
13868                             clib_net_to_host_u64 (mp->features));
13869   vat_json_object_add_uint (node, "is_server", mp->is_server);
13870   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13871   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13872   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13873 }
13874
13875 static int
13876 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13877 {
13878   vl_api_sw_interface_vhost_user_dump_t *mp;
13879   vl_api_control_ping_t *mp_ping;
13880   int ret;
13881   print (vam->ofp,
13882          "Interface name            idx hdr_sz features server regions filename");
13883
13884   /* Get list of vhost-user interfaces */
13885   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13886   S (mp);
13887
13888   /* Use a control ping for synchronization */
13889   MPING (CONTROL_PING, mp_ping);
13890   S (mp_ping);
13891
13892   W (ret);
13893   return ret;
13894 }
13895
13896 static int
13897 api_show_version (vat_main_t * vam)
13898 {
13899   vl_api_show_version_t *mp;
13900   int ret;
13901
13902   M (SHOW_VERSION, mp);
13903
13904   S (mp);
13905   W (ret);
13906   return ret;
13907 }
13908
13909
13910 static int
13911 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13912 {
13913   unformat_input_t *line_input = vam->input;
13914   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13915   ip4_address_t local4, remote4;
13916   ip6_address_t local6, remote6;
13917   u8 is_add = 1;
13918   u8 ipv4_set = 0, ipv6_set = 0;
13919   u8 local_set = 0;
13920   u8 remote_set = 0;
13921   u8 grp_set = 0;
13922   u32 mcast_sw_if_index = ~0;
13923   u32 encap_vrf_id = 0;
13924   u32 decap_vrf_id = 0;
13925   u8 protocol = ~0;
13926   u32 vni;
13927   u8 vni_set = 0;
13928   int ret;
13929
13930   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13931   clib_memset (&local4, 0, sizeof local4);
13932   clib_memset (&remote4, 0, sizeof remote4);
13933   clib_memset (&local6, 0, sizeof local6);
13934   clib_memset (&remote6, 0, sizeof remote6);
13935
13936   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13937     {
13938       if (unformat (line_input, "del"))
13939         is_add = 0;
13940       else if (unformat (line_input, "local %U",
13941                          unformat_ip4_address, &local4))
13942         {
13943           local_set = 1;
13944           ipv4_set = 1;
13945         }
13946       else if (unformat (line_input, "remote %U",
13947                          unformat_ip4_address, &remote4))
13948         {
13949           remote_set = 1;
13950           ipv4_set = 1;
13951         }
13952       else if (unformat (line_input, "local %U",
13953                          unformat_ip6_address, &local6))
13954         {
13955           local_set = 1;
13956           ipv6_set = 1;
13957         }
13958       else if (unformat (line_input, "remote %U",
13959                          unformat_ip6_address, &remote6))
13960         {
13961           remote_set = 1;
13962           ipv6_set = 1;
13963         }
13964       else if (unformat (line_input, "group %U %U",
13965                          unformat_ip4_address, &remote4,
13966                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13967         {
13968           grp_set = remote_set = 1;
13969           ipv4_set = 1;
13970         }
13971       else if (unformat (line_input, "group %U",
13972                          unformat_ip4_address, &remote4))
13973         {
13974           grp_set = remote_set = 1;
13975           ipv4_set = 1;
13976         }
13977       else if (unformat (line_input, "group %U %U",
13978                          unformat_ip6_address, &remote6,
13979                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13980         {
13981           grp_set = remote_set = 1;
13982           ipv6_set = 1;
13983         }
13984       else if (unformat (line_input, "group %U",
13985                          unformat_ip6_address, &remote6))
13986         {
13987           grp_set = remote_set = 1;
13988           ipv6_set = 1;
13989         }
13990       else
13991         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13992         ;
13993       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13994         ;
13995       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13996         ;
13997       else if (unformat (line_input, "vni %d", &vni))
13998         vni_set = 1;
13999       else if (unformat (line_input, "next-ip4"))
14000         protocol = 1;
14001       else if (unformat (line_input, "next-ip6"))
14002         protocol = 2;
14003       else if (unformat (line_input, "next-ethernet"))
14004         protocol = 3;
14005       else if (unformat (line_input, "next-nsh"))
14006         protocol = 4;
14007       else
14008         {
14009           errmsg ("parse error '%U'", format_unformat_error, line_input);
14010           return -99;
14011         }
14012     }
14013
14014   if (local_set == 0)
14015     {
14016       errmsg ("tunnel local address not specified");
14017       return -99;
14018     }
14019   if (remote_set == 0)
14020     {
14021       errmsg ("tunnel remote address not specified");
14022       return -99;
14023     }
14024   if (grp_set && mcast_sw_if_index == ~0)
14025     {
14026       errmsg ("tunnel nonexistent multicast device");
14027       return -99;
14028     }
14029   if (ipv4_set && ipv6_set)
14030     {
14031       errmsg ("both IPv4 and IPv6 addresses specified");
14032       return -99;
14033     }
14034
14035   if (vni_set == 0)
14036     {
14037       errmsg ("vni not specified");
14038       return -99;
14039     }
14040
14041   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14042
14043
14044   if (ipv6_set)
14045     {
14046       clib_memcpy (&mp->local, &local6, sizeof (local6));
14047       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14048     }
14049   else
14050     {
14051       clib_memcpy (&mp->local, &local4, sizeof (local4));
14052       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14053     }
14054
14055   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14056   mp->encap_vrf_id = ntohl (encap_vrf_id);
14057   mp->decap_vrf_id = ntohl (decap_vrf_id);
14058   mp->protocol = protocol;
14059   mp->vni = ntohl (vni);
14060   mp->is_add = is_add;
14061   mp->is_ipv6 = ipv6_set;
14062
14063   S (mp);
14064   W (ret);
14065   return ret;
14066 }
14067
14068 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14069   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14070 {
14071   vat_main_t *vam = &vat_main;
14072   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14073   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14074
14075   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14076          ntohl (mp->sw_if_index),
14077          format_ip46_address, &local, IP46_TYPE_ANY,
14078          format_ip46_address, &remote, IP46_TYPE_ANY,
14079          ntohl (mp->vni), mp->protocol,
14080          ntohl (mp->mcast_sw_if_index),
14081          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14082 }
14083
14084
14085 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14086   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14087 {
14088   vat_main_t *vam = &vat_main;
14089   vat_json_node_t *node = NULL;
14090   struct in_addr ip4;
14091   struct in6_addr ip6;
14092
14093   if (VAT_JSON_ARRAY != vam->json_tree.type)
14094     {
14095       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14096       vat_json_init_array (&vam->json_tree);
14097     }
14098   node = vat_json_array_add (&vam->json_tree);
14099
14100   vat_json_init_object (node);
14101   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14102   if (mp->is_ipv6)
14103     {
14104       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14105       vat_json_object_add_ip6 (node, "local", ip6);
14106       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14107       vat_json_object_add_ip6 (node, "remote", ip6);
14108     }
14109   else
14110     {
14111       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14112       vat_json_object_add_ip4 (node, "local", ip4);
14113       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14114       vat_json_object_add_ip4 (node, "remote", ip4);
14115     }
14116   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14117   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14118   vat_json_object_add_uint (node, "mcast_sw_if_index",
14119                             ntohl (mp->mcast_sw_if_index));
14120   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14121   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14122   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14123 }
14124
14125 static int
14126 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14127 {
14128   unformat_input_t *i = vam->input;
14129   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14130   vl_api_control_ping_t *mp_ping;
14131   u32 sw_if_index;
14132   u8 sw_if_index_set = 0;
14133   int ret;
14134
14135   /* Parse args required to build the message */
14136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14137     {
14138       if (unformat (i, "sw_if_index %d", &sw_if_index))
14139         sw_if_index_set = 1;
14140       else
14141         break;
14142     }
14143
14144   if (sw_if_index_set == 0)
14145     {
14146       sw_if_index = ~0;
14147     }
14148
14149   if (!vam->json_output)
14150     {
14151       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14152              "sw_if_index", "local", "remote", "vni",
14153              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14154     }
14155
14156   /* Get list of vxlan-tunnel interfaces */
14157   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14158
14159   mp->sw_if_index = htonl (sw_if_index);
14160
14161   S (mp);
14162
14163   /* Use a control ping for synchronization */
14164   MPING (CONTROL_PING, mp_ping);
14165   S (mp_ping);
14166
14167   W (ret);
14168   return ret;
14169 }
14170
14171 static void vl_api_l2_fib_table_details_t_handler
14172   (vl_api_l2_fib_table_details_t * mp)
14173 {
14174   vat_main_t *vam = &vat_main;
14175
14176   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14177          "       %d       %d     %d",
14178          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14179          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14180          mp->bvi_mac);
14181 }
14182
14183 static void vl_api_l2_fib_table_details_t_handler_json
14184   (vl_api_l2_fib_table_details_t * mp)
14185 {
14186   vat_main_t *vam = &vat_main;
14187   vat_json_node_t *node = NULL;
14188
14189   if (VAT_JSON_ARRAY != vam->json_tree.type)
14190     {
14191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14192       vat_json_init_array (&vam->json_tree);
14193     }
14194   node = vat_json_array_add (&vam->json_tree);
14195
14196   vat_json_init_object (node);
14197   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14198   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14199   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14200   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14201   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14202   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14203 }
14204
14205 static int
14206 api_l2_fib_table_dump (vat_main_t * vam)
14207 {
14208   unformat_input_t *i = vam->input;
14209   vl_api_l2_fib_table_dump_t *mp;
14210   vl_api_control_ping_t *mp_ping;
14211   u32 bd_id;
14212   u8 bd_id_set = 0;
14213   int ret;
14214
14215   /* Parse args required to build the message */
14216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14217     {
14218       if (unformat (i, "bd_id %d", &bd_id))
14219         bd_id_set = 1;
14220       else
14221         break;
14222     }
14223
14224   if (bd_id_set == 0)
14225     {
14226       errmsg ("missing bridge domain");
14227       return -99;
14228     }
14229
14230   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14231
14232   /* Get list of l2 fib entries */
14233   M (L2_FIB_TABLE_DUMP, mp);
14234
14235   mp->bd_id = ntohl (bd_id);
14236   S (mp);
14237
14238   /* Use a control ping for synchronization */
14239   MPING (CONTROL_PING, mp_ping);
14240   S (mp_ping);
14241
14242   W (ret);
14243   return ret;
14244 }
14245
14246
14247 static int
14248 api_interface_name_renumber (vat_main_t * vam)
14249 {
14250   unformat_input_t *line_input = vam->input;
14251   vl_api_interface_name_renumber_t *mp;
14252   u32 sw_if_index = ~0;
14253   u32 new_show_dev_instance = ~0;
14254   int ret;
14255
14256   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14257     {
14258       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14259                     &sw_if_index))
14260         ;
14261       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14262         ;
14263       else if (unformat (line_input, "new_show_dev_instance %d",
14264                          &new_show_dev_instance))
14265         ;
14266       else
14267         break;
14268     }
14269
14270   if (sw_if_index == ~0)
14271     {
14272       errmsg ("missing interface name or sw_if_index");
14273       return -99;
14274     }
14275
14276   if (new_show_dev_instance == ~0)
14277     {
14278       errmsg ("missing new_show_dev_instance");
14279       return -99;
14280     }
14281
14282   M (INTERFACE_NAME_RENUMBER, mp);
14283
14284   mp->sw_if_index = ntohl (sw_if_index);
14285   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14286
14287   S (mp);
14288   W (ret);
14289   return ret;
14290 }
14291
14292 static int
14293 api_ip_probe_neighbor (vat_main_t * vam)
14294 {
14295   unformat_input_t *i = vam->input;
14296   vl_api_ip_probe_neighbor_t *mp;
14297   vl_api_address_t dst_adr;
14298   u8 int_set = 0;
14299   u8 adr_set = 0;
14300   u32 sw_if_index;
14301   int ret;
14302
14303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14304     {
14305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14306         int_set = 1;
14307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14308         int_set = 1;
14309       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14310         adr_set = 1;
14311       else
14312         break;
14313     }
14314
14315   if (int_set == 0)
14316     {
14317       errmsg ("missing interface");
14318       return -99;
14319     }
14320
14321   if (adr_set == 0)
14322     {
14323       errmsg ("missing addresses");
14324       return -99;
14325     }
14326
14327   M (IP_PROBE_NEIGHBOR, mp);
14328
14329   mp->sw_if_index = ntohl (sw_if_index);
14330   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14331
14332   S (mp);
14333   W (ret);
14334   return ret;
14335 }
14336
14337 static int
14338 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14339 {
14340   unformat_input_t *i = vam->input;
14341   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14342   u8 mode = IP_SCAN_V46_NEIGHBORS;
14343   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14344   int ret;
14345
14346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14347     {
14348       if (unformat (i, "ip4"))
14349         mode = IP_SCAN_V4_NEIGHBORS;
14350       else if (unformat (i, "ip6"))
14351         mode = IP_SCAN_V6_NEIGHBORS;
14352       if (unformat (i, "both"))
14353         mode = IP_SCAN_V46_NEIGHBORS;
14354       else if (unformat (i, "disable"))
14355         mode = IP_SCAN_DISABLED;
14356       else if (unformat (i, "interval %d", &interval))
14357         ;
14358       else if (unformat (i, "max-time %d", &time))
14359         ;
14360       else if (unformat (i, "max-update %d", &update))
14361         ;
14362       else if (unformat (i, "delay %d", &delay))
14363         ;
14364       else if (unformat (i, "stale %d", &stale))
14365         ;
14366       else
14367         break;
14368     }
14369
14370   if (interval > 255)
14371     {
14372       errmsg ("interval cannot exceed 255 minutes.");
14373       return -99;
14374     }
14375   if (time > 255)
14376     {
14377       errmsg ("max-time cannot exceed 255 usec.");
14378       return -99;
14379     }
14380   if (update > 255)
14381     {
14382       errmsg ("max-update cannot exceed 255.");
14383       return -99;
14384     }
14385   if (delay > 255)
14386     {
14387       errmsg ("delay cannot exceed 255 msec.");
14388       return -99;
14389     }
14390   if (stale > 255)
14391     {
14392       errmsg ("stale cannot exceed 255 minutes.");
14393       return -99;
14394     }
14395
14396   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14397   mp->mode = mode;
14398   mp->scan_interval = interval;
14399   mp->max_proc_time = time;
14400   mp->max_update = update;
14401   mp->scan_int_delay = delay;
14402   mp->stale_threshold = stale;
14403
14404   S (mp);
14405   W (ret);
14406   return ret;
14407 }
14408
14409 static int
14410 api_want_ip4_arp_events (vat_main_t * vam)
14411 {
14412   unformat_input_t *line_input = vam->input;
14413   vl_api_want_ip4_arp_events_t *mp;
14414   ip4_address_t address;
14415   int address_set = 0;
14416   u32 enable_disable = 1;
14417   int ret;
14418
14419   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14420     {
14421       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14422         address_set = 1;
14423       else if (unformat (line_input, "del"))
14424         enable_disable = 0;
14425       else
14426         break;
14427     }
14428
14429   if (address_set == 0)
14430     {
14431       errmsg ("missing addresses");
14432       return -99;
14433     }
14434
14435   M (WANT_IP4_ARP_EVENTS, mp);
14436   mp->enable_disable = enable_disable;
14437   mp->pid = htonl (getpid ());
14438   clib_memcpy (mp->ip, &address, sizeof (address));
14439
14440   S (mp);
14441   W (ret);
14442   return ret;
14443 }
14444
14445 static int
14446 api_want_ip6_nd_events (vat_main_t * vam)
14447 {
14448   unformat_input_t *line_input = vam->input;
14449   vl_api_want_ip6_nd_events_t *mp;
14450   vl_api_ip6_address_t address;
14451   int address_set = 0;
14452   u32 enable_disable = 1;
14453   int ret;
14454
14455   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14456     {
14457       if (unformat
14458           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14459         address_set = 1;
14460       else if (unformat (line_input, "del"))
14461         enable_disable = 0;
14462       else
14463         break;
14464     }
14465
14466   if (address_set == 0)
14467     {
14468       errmsg ("missing addresses");
14469       return -99;
14470     }
14471
14472   M (WANT_IP6_ND_EVENTS, mp);
14473   mp->enable_disable = enable_disable;
14474   mp->pid = htonl (getpid ());
14475   clib_memcpy (&mp->ip, &address, sizeof (address));
14476
14477   S (mp);
14478   W (ret);
14479   return ret;
14480 }
14481
14482 static int
14483 api_want_l2_macs_events (vat_main_t * vam)
14484 {
14485   unformat_input_t *line_input = vam->input;
14486   vl_api_want_l2_macs_events_t *mp;
14487   u8 enable_disable = 1;
14488   u32 scan_delay = 0;
14489   u32 max_macs_in_event = 0;
14490   u32 learn_limit = 0;
14491   int ret;
14492
14493   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14494     {
14495       if (unformat (line_input, "learn-limit %d", &learn_limit))
14496         ;
14497       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14498         ;
14499       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14500         ;
14501       else if (unformat (line_input, "disable"))
14502         enable_disable = 0;
14503       else
14504         break;
14505     }
14506
14507   M (WANT_L2_MACS_EVENTS, mp);
14508   mp->enable_disable = enable_disable;
14509   mp->pid = htonl (getpid ());
14510   mp->learn_limit = htonl (learn_limit);
14511   mp->scan_delay = (u8) scan_delay;
14512   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14513   S (mp);
14514   W (ret);
14515   return ret;
14516 }
14517
14518 static int
14519 api_input_acl_set_interface (vat_main_t * vam)
14520 {
14521   unformat_input_t *i = vam->input;
14522   vl_api_input_acl_set_interface_t *mp;
14523   u32 sw_if_index;
14524   int sw_if_index_set;
14525   u32 ip4_table_index = ~0;
14526   u32 ip6_table_index = ~0;
14527   u32 l2_table_index = ~0;
14528   u8 is_add = 1;
14529   int ret;
14530
14531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14532     {
14533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14534         sw_if_index_set = 1;
14535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14536         sw_if_index_set = 1;
14537       else if (unformat (i, "del"))
14538         is_add = 0;
14539       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14540         ;
14541       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14542         ;
14543       else if (unformat (i, "l2-table %d", &l2_table_index))
14544         ;
14545       else
14546         {
14547           clib_warning ("parse error '%U'", format_unformat_error, i);
14548           return -99;
14549         }
14550     }
14551
14552   if (sw_if_index_set == 0)
14553     {
14554       errmsg ("missing interface name or sw_if_index");
14555       return -99;
14556     }
14557
14558   M (INPUT_ACL_SET_INTERFACE, mp);
14559
14560   mp->sw_if_index = ntohl (sw_if_index);
14561   mp->ip4_table_index = ntohl (ip4_table_index);
14562   mp->ip6_table_index = ntohl (ip6_table_index);
14563   mp->l2_table_index = ntohl (l2_table_index);
14564   mp->is_add = is_add;
14565
14566   S (mp);
14567   W (ret);
14568   return ret;
14569 }
14570
14571 static int
14572 api_output_acl_set_interface (vat_main_t * vam)
14573 {
14574   unformat_input_t *i = vam->input;
14575   vl_api_output_acl_set_interface_t *mp;
14576   u32 sw_if_index;
14577   int sw_if_index_set;
14578   u32 ip4_table_index = ~0;
14579   u32 ip6_table_index = ~0;
14580   u32 l2_table_index = ~0;
14581   u8 is_add = 1;
14582   int ret;
14583
14584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14585     {
14586       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14587         sw_if_index_set = 1;
14588       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14589         sw_if_index_set = 1;
14590       else if (unformat (i, "del"))
14591         is_add = 0;
14592       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14593         ;
14594       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14595         ;
14596       else if (unformat (i, "l2-table %d", &l2_table_index))
14597         ;
14598       else
14599         {
14600           clib_warning ("parse error '%U'", format_unformat_error, i);
14601           return -99;
14602         }
14603     }
14604
14605   if (sw_if_index_set == 0)
14606     {
14607       errmsg ("missing interface name or sw_if_index");
14608       return -99;
14609     }
14610
14611   M (OUTPUT_ACL_SET_INTERFACE, mp);
14612
14613   mp->sw_if_index = ntohl (sw_if_index);
14614   mp->ip4_table_index = ntohl (ip4_table_index);
14615   mp->ip6_table_index = ntohl (ip6_table_index);
14616   mp->l2_table_index = ntohl (l2_table_index);
14617   mp->is_add = is_add;
14618
14619   S (mp);
14620   W (ret);
14621   return ret;
14622 }
14623
14624 static int
14625 api_ip_address_dump (vat_main_t * vam)
14626 {
14627   unformat_input_t *i = vam->input;
14628   vl_api_ip_address_dump_t *mp;
14629   vl_api_control_ping_t *mp_ping;
14630   u32 sw_if_index = ~0;
14631   u8 sw_if_index_set = 0;
14632   u8 ipv4_set = 0;
14633   u8 ipv6_set = 0;
14634   int ret;
14635
14636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14637     {
14638       if (unformat (i, "sw_if_index %d", &sw_if_index))
14639         sw_if_index_set = 1;
14640       else
14641         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14642         sw_if_index_set = 1;
14643       else if (unformat (i, "ipv4"))
14644         ipv4_set = 1;
14645       else if (unformat (i, "ipv6"))
14646         ipv6_set = 1;
14647       else
14648         break;
14649     }
14650
14651   if (ipv4_set && ipv6_set)
14652     {
14653       errmsg ("ipv4 and ipv6 flags cannot be both set");
14654       return -99;
14655     }
14656
14657   if ((!ipv4_set) && (!ipv6_set))
14658     {
14659       errmsg ("no ipv4 nor ipv6 flag set");
14660       return -99;
14661     }
14662
14663   if (sw_if_index_set == 0)
14664     {
14665       errmsg ("missing interface name or sw_if_index");
14666       return -99;
14667     }
14668
14669   vam->current_sw_if_index = sw_if_index;
14670   vam->is_ipv6 = ipv6_set;
14671
14672   M (IP_ADDRESS_DUMP, mp);
14673   mp->sw_if_index = ntohl (sw_if_index);
14674   mp->is_ipv6 = ipv6_set;
14675   S (mp);
14676
14677   /* Use a control ping for synchronization */
14678   MPING (CONTROL_PING, mp_ping);
14679   S (mp_ping);
14680
14681   W (ret);
14682   return ret;
14683 }
14684
14685 static int
14686 api_ip_dump (vat_main_t * vam)
14687 {
14688   vl_api_ip_dump_t *mp;
14689   vl_api_control_ping_t *mp_ping;
14690   unformat_input_t *in = vam->input;
14691   int ipv4_set = 0;
14692   int ipv6_set = 0;
14693   int is_ipv6;
14694   int i;
14695   int ret;
14696
14697   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14698     {
14699       if (unformat (in, "ipv4"))
14700         ipv4_set = 1;
14701       else if (unformat (in, "ipv6"))
14702         ipv6_set = 1;
14703       else
14704         break;
14705     }
14706
14707   if (ipv4_set && ipv6_set)
14708     {
14709       errmsg ("ipv4 and ipv6 flags cannot be both set");
14710       return -99;
14711     }
14712
14713   if ((!ipv4_set) && (!ipv6_set))
14714     {
14715       errmsg ("no ipv4 nor ipv6 flag set");
14716       return -99;
14717     }
14718
14719   is_ipv6 = ipv6_set;
14720   vam->is_ipv6 = is_ipv6;
14721
14722   /* free old data */
14723   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14724     {
14725       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14726     }
14727   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14728
14729   M (IP_DUMP, mp);
14730   mp->is_ipv6 = ipv6_set;
14731   S (mp);
14732
14733   /* Use a control ping for synchronization */
14734   MPING (CONTROL_PING, mp_ping);
14735   S (mp_ping);
14736
14737   W (ret);
14738   return ret;
14739 }
14740
14741 static int
14742 api_ipsec_spd_add_del (vat_main_t * vam)
14743 {
14744   unformat_input_t *i = vam->input;
14745   vl_api_ipsec_spd_add_del_t *mp;
14746   u32 spd_id = ~0;
14747   u8 is_add = 1;
14748   int ret;
14749
14750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14751     {
14752       if (unformat (i, "spd_id %d", &spd_id))
14753         ;
14754       else if (unformat (i, "del"))
14755         is_add = 0;
14756       else
14757         {
14758           clib_warning ("parse error '%U'", format_unformat_error, i);
14759           return -99;
14760         }
14761     }
14762   if (spd_id == ~0)
14763     {
14764       errmsg ("spd_id must be set");
14765       return -99;
14766     }
14767
14768   M (IPSEC_SPD_ADD_DEL, mp);
14769
14770   mp->spd_id = ntohl (spd_id);
14771   mp->is_add = is_add;
14772
14773   S (mp);
14774   W (ret);
14775   return ret;
14776 }
14777
14778 static int
14779 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14780 {
14781   unformat_input_t *i = vam->input;
14782   vl_api_ipsec_interface_add_del_spd_t *mp;
14783   u32 sw_if_index;
14784   u8 sw_if_index_set = 0;
14785   u32 spd_id = (u32) ~ 0;
14786   u8 is_add = 1;
14787   int ret;
14788
14789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14790     {
14791       if (unformat (i, "del"))
14792         is_add = 0;
14793       else if (unformat (i, "spd_id %d", &spd_id))
14794         ;
14795       else
14796         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14797         sw_if_index_set = 1;
14798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14799         sw_if_index_set = 1;
14800       else
14801         {
14802           clib_warning ("parse error '%U'", format_unformat_error, i);
14803           return -99;
14804         }
14805
14806     }
14807
14808   if (spd_id == (u32) ~ 0)
14809     {
14810       errmsg ("spd_id must be set");
14811       return -99;
14812     }
14813
14814   if (sw_if_index_set == 0)
14815     {
14816       errmsg ("missing interface name or sw_if_index");
14817       return -99;
14818     }
14819
14820   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14821
14822   mp->spd_id = ntohl (spd_id);
14823   mp->sw_if_index = ntohl (sw_if_index);
14824   mp->is_add = is_add;
14825
14826   S (mp);
14827   W (ret);
14828   return ret;
14829 }
14830
14831 static int
14832 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14833 {
14834   unformat_input_t *i = vam->input;
14835   vl_api_ipsec_spd_add_del_entry_t *mp;
14836   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14837   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14838   i32 priority = 0;
14839   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14840   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14841   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14842   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14843   int ret;
14844
14845   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14846   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14847   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14848   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14849   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14850   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14851
14852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14853     {
14854       if (unformat (i, "del"))
14855         is_add = 0;
14856       if (unformat (i, "outbound"))
14857         is_outbound = 1;
14858       if (unformat (i, "inbound"))
14859         is_outbound = 0;
14860       else if (unformat (i, "spd_id %d", &spd_id))
14861         ;
14862       else if (unformat (i, "sa_id %d", &sa_id))
14863         ;
14864       else if (unformat (i, "priority %d", &priority))
14865         ;
14866       else if (unformat (i, "protocol %d", &protocol))
14867         ;
14868       else if (unformat (i, "lport_start %d", &lport_start))
14869         ;
14870       else if (unformat (i, "lport_stop %d", &lport_stop))
14871         ;
14872       else if (unformat (i, "rport_start %d", &rport_start))
14873         ;
14874       else if (unformat (i, "rport_stop %d", &rport_stop))
14875         ;
14876       else
14877         if (unformat
14878             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14879         {
14880           is_ipv6 = 0;
14881           is_ip_any = 0;
14882         }
14883       else
14884         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14885         {
14886           is_ipv6 = 0;
14887           is_ip_any = 0;
14888         }
14889       else
14890         if (unformat
14891             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14892         {
14893           is_ipv6 = 0;
14894           is_ip_any = 0;
14895         }
14896       else
14897         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14898         {
14899           is_ipv6 = 0;
14900           is_ip_any = 0;
14901         }
14902       else
14903         if (unformat
14904             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14905         {
14906           is_ipv6 = 1;
14907           is_ip_any = 0;
14908         }
14909       else
14910         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14911         {
14912           is_ipv6 = 1;
14913           is_ip_any = 0;
14914         }
14915       else
14916         if (unformat
14917             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14918         {
14919           is_ipv6 = 1;
14920           is_ip_any = 0;
14921         }
14922       else
14923         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14924         {
14925           is_ipv6 = 1;
14926           is_ip_any = 0;
14927         }
14928       else
14929         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14930         {
14931           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14932             {
14933               clib_warning ("unsupported action: 'resolve'");
14934               return -99;
14935             }
14936         }
14937       else
14938         {
14939           clib_warning ("parse error '%U'", format_unformat_error, i);
14940           return -99;
14941         }
14942
14943     }
14944
14945   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14946
14947   mp->spd_id = ntohl (spd_id);
14948   mp->priority = ntohl (priority);
14949   mp->is_outbound = is_outbound;
14950
14951   mp->is_ipv6 = is_ipv6;
14952   if (is_ipv6 || is_ip_any)
14953     {
14954       clib_memcpy (mp->remote_address_start, &raddr6_start,
14955                    sizeof (ip6_address_t));
14956       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14957                    sizeof (ip6_address_t));
14958       clib_memcpy (mp->local_address_start, &laddr6_start,
14959                    sizeof (ip6_address_t));
14960       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14961                    sizeof (ip6_address_t));
14962     }
14963   else
14964     {
14965       clib_memcpy (mp->remote_address_start, &raddr4_start,
14966                    sizeof (ip4_address_t));
14967       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14968                    sizeof (ip4_address_t));
14969       clib_memcpy (mp->local_address_start, &laddr4_start,
14970                    sizeof (ip4_address_t));
14971       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14972                    sizeof (ip4_address_t));
14973     }
14974   mp->protocol = (u8) protocol;
14975   mp->local_port_start = ntohs ((u16) lport_start);
14976   mp->local_port_stop = ntohs ((u16) lport_stop);
14977   mp->remote_port_start = ntohs ((u16) rport_start);
14978   mp->remote_port_stop = ntohs ((u16) rport_stop);
14979   mp->policy = (u8) policy;
14980   mp->sa_id = ntohl (sa_id);
14981   mp->is_add = is_add;
14982   mp->is_ip_any = is_ip_any;
14983   S (mp);
14984   W (ret);
14985   return ret;
14986 }
14987
14988 static int
14989 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14990 {
14991   unformat_input_t *i = vam->input;
14992   vl_api_ipsec_sad_add_del_entry_t *mp;
14993   u32 sad_id = 0, spi = 0;
14994   u8 *ck = 0, *ik = 0;
14995   u8 is_add = 1;
14996
14997   u8 protocol = IPSEC_PROTOCOL_AH;
14998   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14999   u32 crypto_alg = 0, integ_alg = 0;
15000   ip4_address_t tun_src4;
15001   ip4_address_t tun_dst4;
15002   ip6_address_t tun_src6;
15003   ip6_address_t tun_dst6;
15004   int ret;
15005
15006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15007     {
15008       if (unformat (i, "del"))
15009         is_add = 0;
15010       else if (unformat (i, "sad_id %d", &sad_id))
15011         ;
15012       else if (unformat (i, "spi %d", &spi))
15013         ;
15014       else if (unformat (i, "esp"))
15015         protocol = IPSEC_PROTOCOL_ESP;
15016       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15017         {
15018           is_tunnel = 1;
15019           is_tunnel_ipv6 = 0;
15020         }
15021       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15022         {
15023           is_tunnel = 1;
15024           is_tunnel_ipv6 = 0;
15025         }
15026       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15027         {
15028           is_tunnel = 1;
15029           is_tunnel_ipv6 = 1;
15030         }
15031       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15032         {
15033           is_tunnel = 1;
15034           is_tunnel_ipv6 = 1;
15035         }
15036       else
15037         if (unformat
15038             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15039         {
15040           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15041             {
15042               clib_warning ("unsupported crypto-alg: '%U'",
15043                             format_ipsec_crypto_alg, crypto_alg);
15044               return -99;
15045             }
15046         }
15047       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15048         ;
15049       else
15050         if (unformat
15051             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15052         {
15053           if (integ_alg >= IPSEC_INTEG_N_ALG)
15054             {
15055               clib_warning ("unsupported integ-alg: '%U'",
15056                             format_ipsec_integ_alg, integ_alg);
15057               return -99;
15058             }
15059         }
15060       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15061         ;
15062       else
15063         {
15064           clib_warning ("parse error '%U'", format_unformat_error, i);
15065           return -99;
15066         }
15067
15068     }
15069
15070   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15071
15072   mp->sad_id = ntohl (sad_id);
15073   mp->is_add = is_add;
15074   mp->protocol = protocol;
15075   mp->spi = ntohl (spi);
15076   mp->is_tunnel = is_tunnel;
15077   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15078   mp->crypto_algorithm = crypto_alg;
15079   mp->integrity_algorithm = integ_alg;
15080   mp->crypto_key_length = vec_len (ck);
15081   mp->integrity_key_length = vec_len (ik);
15082
15083   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15084     mp->crypto_key_length = sizeof (mp->crypto_key);
15085
15086   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15087     mp->integrity_key_length = sizeof (mp->integrity_key);
15088
15089   if (ck)
15090     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15091   if (ik)
15092     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15093
15094   if (is_tunnel)
15095     {
15096       if (is_tunnel_ipv6)
15097         {
15098           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15099                        sizeof (ip6_address_t));
15100           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15101                        sizeof (ip6_address_t));
15102         }
15103       else
15104         {
15105           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15106                        sizeof (ip4_address_t));
15107           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15108                        sizeof (ip4_address_t));
15109         }
15110     }
15111
15112   S (mp);
15113   W (ret);
15114   return ret;
15115 }
15116
15117 static int
15118 api_ipsec_sa_set_key (vat_main_t * vam)
15119 {
15120   unformat_input_t *i = vam->input;
15121   vl_api_ipsec_sa_set_key_t *mp;
15122   u32 sa_id;
15123   u8 *ck = 0, *ik = 0;
15124   int ret;
15125
15126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15127     {
15128       if (unformat (i, "sa_id %d", &sa_id))
15129         ;
15130       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15131         ;
15132       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15133         ;
15134       else
15135         {
15136           clib_warning ("parse error '%U'", format_unformat_error, i);
15137           return -99;
15138         }
15139     }
15140
15141   M (IPSEC_SA_SET_KEY, mp);
15142
15143   mp->sa_id = ntohl (sa_id);
15144   mp->crypto_key_length = vec_len (ck);
15145   mp->integrity_key_length = vec_len (ik);
15146
15147   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15148     mp->crypto_key_length = sizeof (mp->crypto_key);
15149
15150   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15151     mp->integrity_key_length = sizeof (mp->integrity_key);
15152
15153   if (ck)
15154     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15155   if (ik)
15156     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15157
15158   S (mp);
15159   W (ret);
15160   return ret;
15161 }
15162
15163 static int
15164 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15165 {
15166   unformat_input_t *i = vam->input;
15167   vl_api_ipsec_tunnel_if_add_del_t *mp;
15168   u32 local_spi = 0, remote_spi = 0;
15169   u32 crypto_alg = 0, integ_alg = 0;
15170   u8 *lck = NULL, *rck = NULL;
15171   u8 *lik = NULL, *rik = NULL;
15172   ip4_address_t local_ip = { {0} };
15173   ip4_address_t remote_ip = { {0} };
15174   u8 is_add = 1;
15175   u8 esn = 0;
15176   u8 anti_replay = 0;
15177   u8 renumber = 0;
15178   u32 instance = ~0;
15179   int ret;
15180
15181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15182     {
15183       if (unformat (i, "del"))
15184         is_add = 0;
15185       else if (unformat (i, "esn"))
15186         esn = 1;
15187       else if (unformat (i, "anti_replay"))
15188         anti_replay = 1;
15189       else if (unformat (i, "local_spi %d", &local_spi))
15190         ;
15191       else if (unformat (i, "remote_spi %d", &remote_spi))
15192         ;
15193       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15194         ;
15195       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15196         ;
15197       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15198         ;
15199       else
15200         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15201         ;
15202       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15203         ;
15204       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15205         ;
15206       else
15207         if (unformat
15208             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15209         {
15210           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15211             {
15212               errmsg ("unsupported crypto-alg: '%U'\n",
15213                       format_ipsec_crypto_alg, crypto_alg);
15214               return -99;
15215             }
15216         }
15217       else
15218         if (unformat
15219             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15220         {
15221           if (integ_alg >= IPSEC_INTEG_N_ALG)
15222             {
15223               errmsg ("unsupported integ-alg: '%U'\n",
15224                       format_ipsec_integ_alg, integ_alg);
15225               return -99;
15226             }
15227         }
15228       else if (unformat (i, "instance %u", &instance))
15229         renumber = 1;
15230       else
15231         {
15232           errmsg ("parse error '%U'\n", format_unformat_error, i);
15233           return -99;
15234         }
15235     }
15236
15237   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15238
15239   mp->is_add = is_add;
15240   mp->esn = esn;
15241   mp->anti_replay = anti_replay;
15242
15243   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15244   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15245
15246   mp->local_spi = htonl (local_spi);
15247   mp->remote_spi = htonl (remote_spi);
15248   mp->crypto_alg = (u8) crypto_alg;
15249
15250   mp->local_crypto_key_len = 0;
15251   if (lck)
15252     {
15253       mp->local_crypto_key_len = vec_len (lck);
15254       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15255         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15256       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15257     }
15258
15259   mp->remote_crypto_key_len = 0;
15260   if (rck)
15261     {
15262       mp->remote_crypto_key_len = vec_len (rck);
15263       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15264         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15265       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15266     }
15267
15268   mp->integ_alg = (u8) integ_alg;
15269
15270   mp->local_integ_key_len = 0;
15271   if (lik)
15272     {
15273       mp->local_integ_key_len = vec_len (lik);
15274       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15275         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15276       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15277     }
15278
15279   mp->remote_integ_key_len = 0;
15280   if (rik)
15281     {
15282       mp->remote_integ_key_len = vec_len (rik);
15283       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15284         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15285       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15286     }
15287
15288   if (renumber)
15289     {
15290       mp->renumber = renumber;
15291       mp->show_instance = ntohl (instance);
15292     }
15293
15294   S (mp);
15295   W (ret);
15296   return ret;
15297 }
15298
15299 static void
15300 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15301 {
15302   vat_main_t *vam = &vat_main;
15303
15304   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15305          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15306          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15307          "tunnel_src_addr %U tunnel_dst_addr %U "
15308          "salt %u seq_outbound %lu last_seq_inbound %lu "
15309          "replay_window %lu total_data_size %lu\n",
15310          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15311          mp->protocol,
15312          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15313          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15314          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15315          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15316          mp->tunnel_src_addr,
15317          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15318          mp->tunnel_dst_addr,
15319          ntohl (mp->salt),
15320          clib_net_to_host_u64 (mp->seq_outbound),
15321          clib_net_to_host_u64 (mp->last_seq_inbound),
15322          clib_net_to_host_u64 (mp->replay_window),
15323          clib_net_to_host_u64 (mp->total_data_size));
15324 }
15325
15326 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15327 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15328
15329 static void vl_api_ipsec_sa_details_t_handler_json
15330   (vl_api_ipsec_sa_details_t * mp)
15331 {
15332   vat_main_t *vam = &vat_main;
15333   vat_json_node_t *node = NULL;
15334   struct in_addr src_ip4, dst_ip4;
15335   struct in6_addr src_ip6, dst_ip6;
15336
15337   if (VAT_JSON_ARRAY != vam->json_tree.type)
15338     {
15339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15340       vat_json_init_array (&vam->json_tree);
15341     }
15342   node = vat_json_array_add (&vam->json_tree);
15343
15344   vat_json_init_object (node);
15345   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15347   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15348   vat_json_object_add_uint (node, "proto", mp->protocol);
15349   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15350   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15351   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15352   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15353   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15354   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15355   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15356                              mp->crypto_key_len);
15357   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15358                              mp->integ_key_len);
15359   if (mp->is_tunnel_ip6)
15360     {
15361       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15362       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15363       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15364       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15365     }
15366   else
15367     {
15368       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15369       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15370       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15371       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15372     }
15373   vat_json_object_add_uint (node, "replay_window",
15374                             clib_net_to_host_u64 (mp->replay_window));
15375   vat_json_object_add_uint (node, "total_data_size",
15376                             clib_net_to_host_u64 (mp->total_data_size));
15377
15378 }
15379
15380 static int
15381 api_ipsec_sa_dump (vat_main_t * vam)
15382 {
15383   unformat_input_t *i = vam->input;
15384   vl_api_ipsec_sa_dump_t *mp;
15385   vl_api_control_ping_t *mp_ping;
15386   u32 sa_id = ~0;
15387   int ret;
15388
15389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15390     {
15391       if (unformat (i, "sa_id %d", &sa_id))
15392         ;
15393       else
15394         {
15395           clib_warning ("parse error '%U'", format_unformat_error, i);
15396           return -99;
15397         }
15398     }
15399
15400   M (IPSEC_SA_DUMP, mp);
15401
15402   mp->sa_id = ntohl (sa_id);
15403
15404   S (mp);
15405
15406   /* Use a control ping for synchronization */
15407   M (CONTROL_PING, mp_ping);
15408   S (mp_ping);
15409
15410   W (ret);
15411   return ret;
15412 }
15413
15414 static int
15415 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15416 {
15417   unformat_input_t *i = vam->input;
15418   vl_api_ipsec_tunnel_if_set_key_t *mp;
15419   u32 sw_if_index = ~0;
15420   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15421   u8 *key = 0;
15422   u32 alg = ~0;
15423   int ret;
15424
15425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15426     {
15427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15428         ;
15429       else
15430         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15431         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15432       else
15433         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15434         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15435       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15436         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15437       else
15438         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15439         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15440       else if (unformat (i, "%U", unformat_hex_string, &key))
15441         ;
15442       else
15443         {
15444           clib_warning ("parse error '%U'", format_unformat_error, i);
15445           return -99;
15446         }
15447     }
15448
15449   if (sw_if_index == ~0)
15450     {
15451       errmsg ("interface must be specified");
15452       return -99;
15453     }
15454
15455   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15456     {
15457       errmsg ("key type must be specified");
15458       return -99;
15459     }
15460
15461   if (alg == ~0)
15462     {
15463       errmsg ("algorithm must be specified");
15464       return -99;
15465     }
15466
15467   if (vec_len (key) == 0)
15468     {
15469       errmsg ("key must be specified");
15470       return -99;
15471     }
15472
15473   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15474
15475   mp->sw_if_index = htonl (sw_if_index);
15476   mp->alg = alg;
15477   mp->key_type = key_type;
15478   mp->key_len = vec_len (key);
15479   clib_memcpy (mp->key, key, vec_len (key));
15480
15481   S (mp);
15482   W (ret);
15483
15484   return ret;
15485 }
15486
15487 static int
15488 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15489 {
15490   unformat_input_t *i = vam->input;
15491   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15492   u32 sw_if_index = ~0;
15493   u32 sa_id = ~0;
15494   u8 is_outbound = (u8) ~ 0;
15495   int ret;
15496
15497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15498     {
15499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15500         ;
15501       else if (unformat (i, "sa_id %d", &sa_id))
15502         ;
15503       else if (unformat (i, "outbound"))
15504         is_outbound = 1;
15505       else if (unformat (i, "inbound"))
15506         is_outbound = 0;
15507       else
15508         {
15509           clib_warning ("parse error '%U'", format_unformat_error, i);
15510           return -99;
15511         }
15512     }
15513
15514   if (sw_if_index == ~0)
15515     {
15516       errmsg ("interface must be specified");
15517       return -99;
15518     }
15519
15520   if (sa_id == ~0)
15521     {
15522       errmsg ("SA ID must be specified");
15523       return -99;
15524     }
15525
15526   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15527
15528   mp->sw_if_index = htonl (sw_if_index);
15529   mp->sa_id = htonl (sa_id);
15530   mp->is_outbound = is_outbound;
15531
15532   S (mp);
15533   W (ret);
15534
15535   return ret;
15536 }
15537
15538 static int
15539 api_ikev2_profile_add_del (vat_main_t * vam)
15540 {
15541   unformat_input_t *i = vam->input;
15542   vl_api_ikev2_profile_add_del_t *mp;
15543   u8 is_add = 1;
15544   u8 *name = 0;
15545   int ret;
15546
15547   const char *valid_chars = "a-zA-Z0-9_";
15548
15549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15550     {
15551       if (unformat (i, "del"))
15552         is_add = 0;
15553       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15554         vec_add1 (name, 0);
15555       else
15556         {
15557           errmsg ("parse error '%U'", format_unformat_error, i);
15558           return -99;
15559         }
15560     }
15561
15562   if (!vec_len (name))
15563     {
15564       errmsg ("profile name must be specified");
15565       return -99;
15566     }
15567
15568   if (vec_len (name) > 64)
15569     {
15570       errmsg ("profile name too long");
15571       return -99;
15572     }
15573
15574   M (IKEV2_PROFILE_ADD_DEL, mp);
15575
15576   clib_memcpy (mp->name, name, vec_len (name));
15577   mp->is_add = is_add;
15578   vec_free (name);
15579
15580   S (mp);
15581   W (ret);
15582   return ret;
15583 }
15584
15585 static int
15586 api_ikev2_profile_set_auth (vat_main_t * vam)
15587 {
15588   unformat_input_t *i = vam->input;
15589   vl_api_ikev2_profile_set_auth_t *mp;
15590   u8 *name = 0;
15591   u8 *data = 0;
15592   u32 auth_method = 0;
15593   u8 is_hex = 0;
15594   int ret;
15595
15596   const char *valid_chars = "a-zA-Z0-9_";
15597
15598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15599     {
15600       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15601         vec_add1 (name, 0);
15602       else if (unformat (i, "auth_method %U",
15603                          unformat_ikev2_auth_method, &auth_method))
15604         ;
15605       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15606         is_hex = 1;
15607       else if (unformat (i, "auth_data %v", &data))
15608         ;
15609       else
15610         {
15611           errmsg ("parse error '%U'", format_unformat_error, i);
15612           return -99;
15613         }
15614     }
15615
15616   if (!vec_len (name))
15617     {
15618       errmsg ("profile name must be specified");
15619       return -99;
15620     }
15621
15622   if (vec_len (name) > 64)
15623     {
15624       errmsg ("profile name too long");
15625       return -99;
15626     }
15627
15628   if (!vec_len (data))
15629     {
15630       errmsg ("auth_data must be specified");
15631       return -99;
15632     }
15633
15634   if (!auth_method)
15635     {
15636       errmsg ("auth_method must be specified");
15637       return -99;
15638     }
15639
15640   M (IKEV2_PROFILE_SET_AUTH, mp);
15641
15642   mp->is_hex = is_hex;
15643   mp->auth_method = (u8) auth_method;
15644   mp->data_len = vec_len (data);
15645   clib_memcpy (mp->name, name, vec_len (name));
15646   clib_memcpy (mp->data, data, vec_len (data));
15647   vec_free (name);
15648   vec_free (data);
15649
15650   S (mp);
15651   W (ret);
15652   return ret;
15653 }
15654
15655 static int
15656 api_ikev2_profile_set_id (vat_main_t * vam)
15657 {
15658   unformat_input_t *i = vam->input;
15659   vl_api_ikev2_profile_set_id_t *mp;
15660   u8 *name = 0;
15661   u8 *data = 0;
15662   u8 is_local = 0;
15663   u32 id_type = 0;
15664   ip4_address_t ip4;
15665   int ret;
15666
15667   const char *valid_chars = "a-zA-Z0-9_";
15668
15669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15672         vec_add1 (name, 0);
15673       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15674         ;
15675       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15676         {
15677           data = vec_new (u8, 4);
15678           clib_memcpy (data, ip4.as_u8, 4);
15679         }
15680       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15681         ;
15682       else if (unformat (i, "id_data %v", &data))
15683         ;
15684       else if (unformat (i, "local"))
15685         is_local = 1;
15686       else if (unformat (i, "remote"))
15687         is_local = 0;
15688       else
15689         {
15690           errmsg ("parse error '%U'", format_unformat_error, i);
15691           return -99;
15692         }
15693     }
15694
15695   if (!vec_len (name))
15696     {
15697       errmsg ("profile name must be specified");
15698       return -99;
15699     }
15700
15701   if (vec_len (name) > 64)
15702     {
15703       errmsg ("profile name too long");
15704       return -99;
15705     }
15706
15707   if (!vec_len (data))
15708     {
15709       errmsg ("id_data must be specified");
15710       return -99;
15711     }
15712
15713   if (!id_type)
15714     {
15715       errmsg ("id_type must be specified");
15716       return -99;
15717     }
15718
15719   M (IKEV2_PROFILE_SET_ID, mp);
15720
15721   mp->is_local = is_local;
15722   mp->id_type = (u8) id_type;
15723   mp->data_len = vec_len (data);
15724   clib_memcpy (mp->name, name, vec_len (name));
15725   clib_memcpy (mp->data, data, vec_len (data));
15726   vec_free (name);
15727   vec_free (data);
15728
15729   S (mp);
15730   W (ret);
15731   return ret;
15732 }
15733
15734 static int
15735 api_ikev2_profile_set_ts (vat_main_t * vam)
15736 {
15737   unformat_input_t *i = vam->input;
15738   vl_api_ikev2_profile_set_ts_t *mp;
15739   u8 *name = 0;
15740   u8 is_local = 0;
15741   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15742   ip4_address_t start_addr, end_addr;
15743
15744   const char *valid_chars = "a-zA-Z0-9_";
15745   int ret;
15746
15747   start_addr.as_u32 = 0;
15748   end_addr.as_u32 = (u32) ~ 0;
15749
15750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15751     {
15752       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15753         vec_add1 (name, 0);
15754       else if (unformat (i, "protocol %d", &proto))
15755         ;
15756       else if (unformat (i, "start_port %d", &start_port))
15757         ;
15758       else if (unformat (i, "end_port %d", &end_port))
15759         ;
15760       else
15761         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15762         ;
15763       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15764         ;
15765       else if (unformat (i, "local"))
15766         is_local = 1;
15767       else if (unformat (i, "remote"))
15768         is_local = 0;
15769       else
15770         {
15771           errmsg ("parse error '%U'", format_unformat_error, i);
15772           return -99;
15773         }
15774     }
15775
15776   if (!vec_len (name))
15777     {
15778       errmsg ("profile name must be specified");
15779       return -99;
15780     }
15781
15782   if (vec_len (name) > 64)
15783     {
15784       errmsg ("profile name too long");
15785       return -99;
15786     }
15787
15788   M (IKEV2_PROFILE_SET_TS, mp);
15789
15790   mp->is_local = is_local;
15791   mp->proto = (u8) proto;
15792   mp->start_port = (u16) start_port;
15793   mp->end_port = (u16) end_port;
15794   mp->start_addr = start_addr.as_u32;
15795   mp->end_addr = end_addr.as_u32;
15796   clib_memcpy (mp->name, name, vec_len (name));
15797   vec_free (name);
15798
15799   S (mp);
15800   W (ret);
15801   return ret;
15802 }
15803
15804 static int
15805 api_ikev2_set_local_key (vat_main_t * vam)
15806 {
15807   unformat_input_t *i = vam->input;
15808   vl_api_ikev2_set_local_key_t *mp;
15809   u8 *file = 0;
15810   int ret;
15811
15812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15813     {
15814       if (unformat (i, "file %v", &file))
15815         vec_add1 (file, 0);
15816       else
15817         {
15818           errmsg ("parse error '%U'", format_unformat_error, i);
15819           return -99;
15820         }
15821     }
15822
15823   if (!vec_len (file))
15824     {
15825       errmsg ("RSA key file must be specified");
15826       return -99;
15827     }
15828
15829   if (vec_len (file) > 256)
15830     {
15831       errmsg ("file name too long");
15832       return -99;
15833     }
15834
15835   M (IKEV2_SET_LOCAL_KEY, mp);
15836
15837   clib_memcpy (mp->key_file, file, vec_len (file));
15838   vec_free (file);
15839
15840   S (mp);
15841   W (ret);
15842   return ret;
15843 }
15844
15845 static int
15846 api_ikev2_set_responder (vat_main_t * vam)
15847 {
15848   unformat_input_t *i = vam->input;
15849   vl_api_ikev2_set_responder_t *mp;
15850   int ret;
15851   u8 *name = 0;
15852   u32 sw_if_index = ~0;
15853   ip4_address_t address;
15854
15855   const char *valid_chars = "a-zA-Z0-9_";
15856
15857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15858     {
15859       if (unformat
15860           (i, "%U interface %d address %U", unformat_token, valid_chars,
15861            &name, &sw_if_index, unformat_ip4_address, &address))
15862         vec_add1 (name, 0);
15863       else
15864         {
15865           errmsg ("parse error '%U'", format_unformat_error, i);
15866           return -99;
15867         }
15868     }
15869
15870   if (!vec_len (name))
15871     {
15872       errmsg ("profile name must be specified");
15873       return -99;
15874     }
15875
15876   if (vec_len (name) > 64)
15877     {
15878       errmsg ("profile name too long");
15879       return -99;
15880     }
15881
15882   M (IKEV2_SET_RESPONDER, mp);
15883
15884   clib_memcpy (mp->name, name, vec_len (name));
15885   vec_free (name);
15886
15887   mp->sw_if_index = sw_if_index;
15888   clib_memcpy (mp->address, &address, sizeof (address));
15889
15890   S (mp);
15891   W (ret);
15892   return ret;
15893 }
15894
15895 static int
15896 api_ikev2_set_ike_transforms (vat_main_t * vam)
15897 {
15898   unformat_input_t *i = vam->input;
15899   vl_api_ikev2_set_ike_transforms_t *mp;
15900   int ret;
15901   u8 *name = 0;
15902   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15903
15904   const char *valid_chars = "a-zA-Z0-9_";
15905
15906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15907     {
15908       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15909                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15910         vec_add1 (name, 0);
15911       else
15912         {
15913           errmsg ("parse error '%U'", format_unformat_error, i);
15914           return -99;
15915         }
15916     }
15917
15918   if (!vec_len (name))
15919     {
15920       errmsg ("profile name must be specified");
15921       return -99;
15922     }
15923
15924   if (vec_len (name) > 64)
15925     {
15926       errmsg ("profile name too long");
15927       return -99;
15928     }
15929
15930   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15931
15932   clib_memcpy (mp->name, name, vec_len (name));
15933   vec_free (name);
15934   mp->crypto_alg = crypto_alg;
15935   mp->crypto_key_size = crypto_key_size;
15936   mp->integ_alg = integ_alg;
15937   mp->dh_group = dh_group;
15938
15939   S (mp);
15940   W (ret);
15941   return ret;
15942 }
15943
15944
15945 static int
15946 api_ikev2_set_esp_transforms (vat_main_t * vam)
15947 {
15948   unformat_input_t *i = vam->input;
15949   vl_api_ikev2_set_esp_transforms_t *mp;
15950   int ret;
15951   u8 *name = 0;
15952   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15953
15954   const char *valid_chars = "a-zA-Z0-9_";
15955
15956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15957     {
15958       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15959                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15960         vec_add1 (name, 0);
15961       else
15962         {
15963           errmsg ("parse error '%U'", format_unformat_error, i);
15964           return -99;
15965         }
15966     }
15967
15968   if (!vec_len (name))
15969     {
15970       errmsg ("profile name must be specified");
15971       return -99;
15972     }
15973
15974   if (vec_len (name) > 64)
15975     {
15976       errmsg ("profile name too long");
15977       return -99;
15978     }
15979
15980   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15981
15982   clib_memcpy (mp->name, name, vec_len (name));
15983   vec_free (name);
15984   mp->crypto_alg = crypto_alg;
15985   mp->crypto_key_size = crypto_key_size;
15986   mp->integ_alg = integ_alg;
15987   mp->dh_group = dh_group;
15988
15989   S (mp);
15990   W (ret);
15991   return ret;
15992 }
15993
15994 static int
15995 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15996 {
15997   unformat_input_t *i = vam->input;
15998   vl_api_ikev2_set_sa_lifetime_t *mp;
15999   int ret;
16000   u8 *name = 0;
16001   u64 lifetime, lifetime_maxdata;
16002   u32 lifetime_jitter, handover;
16003
16004   const char *valid_chars = "a-zA-Z0-9_";
16005
16006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16007     {
16008       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16009                     &lifetime, &lifetime_jitter, &handover,
16010                     &lifetime_maxdata))
16011         vec_add1 (name, 0);
16012       else
16013         {
16014           errmsg ("parse error '%U'", format_unformat_error, i);
16015           return -99;
16016         }
16017     }
16018
16019   if (!vec_len (name))
16020     {
16021       errmsg ("profile name must be specified");
16022       return -99;
16023     }
16024
16025   if (vec_len (name) > 64)
16026     {
16027       errmsg ("profile name too long");
16028       return -99;
16029     }
16030
16031   M (IKEV2_SET_SA_LIFETIME, mp);
16032
16033   clib_memcpy (mp->name, name, vec_len (name));
16034   vec_free (name);
16035   mp->lifetime = lifetime;
16036   mp->lifetime_jitter = lifetime_jitter;
16037   mp->handover = handover;
16038   mp->lifetime_maxdata = lifetime_maxdata;
16039
16040   S (mp);
16041   W (ret);
16042   return ret;
16043 }
16044
16045 static int
16046 api_ikev2_initiate_sa_init (vat_main_t * vam)
16047 {
16048   unformat_input_t *i = vam->input;
16049   vl_api_ikev2_initiate_sa_init_t *mp;
16050   int ret;
16051   u8 *name = 0;
16052
16053   const char *valid_chars = "a-zA-Z0-9_";
16054
16055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16056     {
16057       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16058         vec_add1 (name, 0);
16059       else
16060         {
16061           errmsg ("parse error '%U'", format_unformat_error, i);
16062           return -99;
16063         }
16064     }
16065
16066   if (!vec_len (name))
16067     {
16068       errmsg ("profile name must be specified");
16069       return -99;
16070     }
16071
16072   if (vec_len (name) > 64)
16073     {
16074       errmsg ("profile name too long");
16075       return -99;
16076     }
16077
16078   M (IKEV2_INITIATE_SA_INIT, mp);
16079
16080   clib_memcpy (mp->name, name, vec_len (name));
16081   vec_free (name);
16082
16083   S (mp);
16084   W (ret);
16085   return ret;
16086 }
16087
16088 static int
16089 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16090 {
16091   unformat_input_t *i = vam->input;
16092   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16093   int ret;
16094   u64 ispi;
16095
16096
16097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16098     {
16099       if (unformat (i, "%lx", &ispi))
16100         ;
16101       else
16102         {
16103           errmsg ("parse error '%U'", format_unformat_error, i);
16104           return -99;
16105         }
16106     }
16107
16108   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16109
16110   mp->ispi = ispi;
16111
16112   S (mp);
16113   W (ret);
16114   return ret;
16115 }
16116
16117 static int
16118 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16119 {
16120   unformat_input_t *i = vam->input;
16121   vl_api_ikev2_initiate_del_child_sa_t *mp;
16122   int ret;
16123   u32 ispi;
16124
16125
16126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16127     {
16128       if (unformat (i, "%x", &ispi))
16129         ;
16130       else
16131         {
16132           errmsg ("parse error '%U'", format_unformat_error, i);
16133           return -99;
16134         }
16135     }
16136
16137   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16138
16139   mp->ispi = ispi;
16140
16141   S (mp);
16142   W (ret);
16143   return ret;
16144 }
16145
16146 static int
16147 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16148 {
16149   unformat_input_t *i = vam->input;
16150   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16151   int ret;
16152   u32 ispi;
16153
16154
16155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16156     {
16157       if (unformat (i, "%x", &ispi))
16158         ;
16159       else
16160         {
16161           errmsg ("parse error '%U'", format_unformat_error, i);
16162           return -99;
16163         }
16164     }
16165
16166   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16167
16168   mp->ispi = ispi;
16169
16170   S (mp);
16171   W (ret);
16172   return ret;
16173 }
16174
16175 static int
16176 api_get_first_msg_id (vat_main_t * vam)
16177 {
16178   vl_api_get_first_msg_id_t *mp;
16179   unformat_input_t *i = vam->input;
16180   u8 *name;
16181   u8 name_set = 0;
16182   int ret;
16183
16184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16185     {
16186       if (unformat (i, "client %s", &name))
16187         name_set = 1;
16188       else
16189         break;
16190     }
16191
16192   if (name_set == 0)
16193     {
16194       errmsg ("missing client name");
16195       return -99;
16196     }
16197   vec_add1 (name, 0);
16198
16199   if (vec_len (name) > 63)
16200     {
16201       errmsg ("client name too long");
16202       return -99;
16203     }
16204
16205   M (GET_FIRST_MSG_ID, mp);
16206   clib_memcpy (mp->name, name, vec_len (name));
16207   S (mp);
16208   W (ret);
16209   return ret;
16210 }
16211
16212 static int
16213 api_cop_interface_enable_disable (vat_main_t * vam)
16214 {
16215   unformat_input_t *line_input = vam->input;
16216   vl_api_cop_interface_enable_disable_t *mp;
16217   u32 sw_if_index = ~0;
16218   u8 enable_disable = 1;
16219   int ret;
16220
16221   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16222     {
16223       if (unformat (line_input, "disable"))
16224         enable_disable = 0;
16225       if (unformat (line_input, "enable"))
16226         enable_disable = 1;
16227       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16228                          vam, &sw_if_index))
16229         ;
16230       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16231         ;
16232       else
16233         break;
16234     }
16235
16236   if (sw_if_index == ~0)
16237     {
16238       errmsg ("missing interface name or sw_if_index");
16239       return -99;
16240     }
16241
16242   /* Construct the API message */
16243   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16244   mp->sw_if_index = ntohl (sw_if_index);
16245   mp->enable_disable = enable_disable;
16246
16247   /* send it... */
16248   S (mp);
16249   /* Wait for the reply */
16250   W (ret);
16251   return ret;
16252 }
16253
16254 static int
16255 api_cop_whitelist_enable_disable (vat_main_t * vam)
16256 {
16257   unformat_input_t *line_input = vam->input;
16258   vl_api_cop_whitelist_enable_disable_t *mp;
16259   u32 sw_if_index = ~0;
16260   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16261   u32 fib_id = 0;
16262   int ret;
16263
16264   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16265     {
16266       if (unformat (line_input, "ip4"))
16267         ip4 = 1;
16268       else if (unformat (line_input, "ip6"))
16269         ip6 = 1;
16270       else if (unformat (line_input, "default"))
16271         default_cop = 1;
16272       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16273                          vam, &sw_if_index))
16274         ;
16275       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16276         ;
16277       else if (unformat (line_input, "fib-id %d", &fib_id))
16278         ;
16279       else
16280         break;
16281     }
16282
16283   if (sw_if_index == ~0)
16284     {
16285       errmsg ("missing interface name or sw_if_index");
16286       return -99;
16287     }
16288
16289   /* Construct the API message */
16290   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16291   mp->sw_if_index = ntohl (sw_if_index);
16292   mp->fib_id = ntohl (fib_id);
16293   mp->ip4 = ip4;
16294   mp->ip6 = ip6;
16295   mp->default_cop = default_cop;
16296
16297   /* send it... */
16298   S (mp);
16299   /* Wait for the reply */
16300   W (ret);
16301   return ret;
16302 }
16303
16304 static int
16305 api_get_node_graph (vat_main_t * vam)
16306 {
16307   vl_api_get_node_graph_t *mp;
16308   int ret;
16309
16310   M (GET_NODE_GRAPH, mp);
16311
16312   /* send it... */
16313   S (mp);
16314   /* Wait for the reply */
16315   W (ret);
16316   return ret;
16317 }
16318
16319 /* *INDENT-OFF* */
16320 /** Used for parsing LISP eids */
16321 typedef CLIB_PACKED(struct{
16322   u8 addr[16];   /**< eid address */
16323   u32 len;       /**< prefix length if IP */
16324   u8 type;      /**< type of eid */
16325 }) lisp_eid_vat_t;
16326 /* *INDENT-ON* */
16327
16328 static uword
16329 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16330 {
16331   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16332
16333   clib_memset (a, 0, sizeof (a[0]));
16334
16335   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16336     {
16337       a->type = 0;              /* ipv4 type */
16338     }
16339   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16340     {
16341       a->type = 1;              /* ipv6 type */
16342     }
16343   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16344     {
16345       a->type = 2;              /* mac type */
16346     }
16347   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16348     {
16349       a->type = 3;              /* NSH type */
16350       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16351       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16352     }
16353   else
16354     {
16355       return 0;
16356     }
16357
16358   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16359     {
16360       return 0;
16361     }
16362
16363   return 1;
16364 }
16365
16366 static int
16367 lisp_eid_size_vat (u8 type)
16368 {
16369   switch (type)
16370     {
16371     case 0:
16372       return 4;
16373     case 1:
16374       return 16;
16375     case 2:
16376       return 6;
16377     case 3:
16378       return 5;
16379     }
16380   return 0;
16381 }
16382
16383 static void
16384 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16385 {
16386   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16387 }
16388
16389 static int
16390 api_one_add_del_locator_set (vat_main_t * vam)
16391 {
16392   unformat_input_t *input = vam->input;
16393   vl_api_one_add_del_locator_set_t *mp;
16394   u8 is_add = 1;
16395   u8 *locator_set_name = NULL;
16396   u8 locator_set_name_set = 0;
16397   vl_api_local_locator_t locator, *locators = 0;
16398   u32 sw_if_index, priority, weight;
16399   u32 data_len = 0;
16400
16401   int ret;
16402   /* Parse args required to build the message */
16403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16404     {
16405       if (unformat (input, "del"))
16406         {
16407           is_add = 0;
16408         }
16409       else if (unformat (input, "locator-set %s", &locator_set_name))
16410         {
16411           locator_set_name_set = 1;
16412         }
16413       else if (unformat (input, "sw_if_index %u p %u w %u",
16414                          &sw_if_index, &priority, &weight))
16415         {
16416           locator.sw_if_index = htonl (sw_if_index);
16417           locator.priority = priority;
16418           locator.weight = weight;
16419           vec_add1 (locators, locator);
16420         }
16421       else
16422         if (unformat
16423             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16424              &sw_if_index, &priority, &weight))
16425         {
16426           locator.sw_if_index = htonl (sw_if_index);
16427           locator.priority = priority;
16428           locator.weight = weight;
16429           vec_add1 (locators, locator);
16430         }
16431       else
16432         break;
16433     }
16434
16435   if (locator_set_name_set == 0)
16436     {
16437       errmsg ("missing locator-set name");
16438       vec_free (locators);
16439       return -99;
16440     }
16441
16442   if (vec_len (locator_set_name) > 64)
16443     {
16444       errmsg ("locator-set name too long");
16445       vec_free (locator_set_name);
16446       vec_free (locators);
16447       return -99;
16448     }
16449   vec_add1 (locator_set_name, 0);
16450
16451   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16452
16453   /* Construct the API message */
16454   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16455
16456   mp->is_add = is_add;
16457   clib_memcpy (mp->locator_set_name, locator_set_name,
16458                vec_len (locator_set_name));
16459   vec_free (locator_set_name);
16460
16461   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16462   if (locators)
16463     clib_memcpy (mp->locators, locators, data_len);
16464   vec_free (locators);
16465
16466   /* send it... */
16467   S (mp);
16468
16469   /* Wait for a reply... */
16470   W (ret);
16471   return ret;
16472 }
16473
16474 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16475
16476 static int
16477 api_one_add_del_locator (vat_main_t * vam)
16478 {
16479   unformat_input_t *input = vam->input;
16480   vl_api_one_add_del_locator_t *mp;
16481   u32 tmp_if_index = ~0;
16482   u32 sw_if_index = ~0;
16483   u8 sw_if_index_set = 0;
16484   u8 sw_if_index_if_name_set = 0;
16485   u32 priority = ~0;
16486   u8 priority_set = 0;
16487   u32 weight = ~0;
16488   u8 weight_set = 0;
16489   u8 is_add = 1;
16490   u8 *locator_set_name = NULL;
16491   u8 locator_set_name_set = 0;
16492   int ret;
16493
16494   /* Parse args required to build the message */
16495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16496     {
16497       if (unformat (input, "del"))
16498         {
16499           is_add = 0;
16500         }
16501       else if (unformat (input, "locator-set %s", &locator_set_name))
16502         {
16503           locator_set_name_set = 1;
16504         }
16505       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16506                          &tmp_if_index))
16507         {
16508           sw_if_index_if_name_set = 1;
16509           sw_if_index = tmp_if_index;
16510         }
16511       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16512         {
16513           sw_if_index_set = 1;
16514           sw_if_index = tmp_if_index;
16515         }
16516       else if (unformat (input, "p %d", &priority))
16517         {
16518           priority_set = 1;
16519         }
16520       else if (unformat (input, "w %d", &weight))
16521         {
16522           weight_set = 1;
16523         }
16524       else
16525         break;
16526     }
16527
16528   if (locator_set_name_set == 0)
16529     {
16530       errmsg ("missing locator-set name");
16531       return -99;
16532     }
16533
16534   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16535     {
16536       errmsg ("missing sw_if_index");
16537       vec_free (locator_set_name);
16538       return -99;
16539     }
16540
16541   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16542     {
16543       errmsg ("cannot use both params interface name and sw_if_index");
16544       vec_free (locator_set_name);
16545       return -99;
16546     }
16547
16548   if (priority_set == 0)
16549     {
16550       errmsg ("missing locator-set priority");
16551       vec_free (locator_set_name);
16552       return -99;
16553     }
16554
16555   if (weight_set == 0)
16556     {
16557       errmsg ("missing locator-set weight");
16558       vec_free (locator_set_name);
16559       return -99;
16560     }
16561
16562   if (vec_len (locator_set_name) > 64)
16563     {
16564       errmsg ("locator-set name too long");
16565       vec_free (locator_set_name);
16566       return -99;
16567     }
16568   vec_add1 (locator_set_name, 0);
16569
16570   /* Construct the API message */
16571   M (ONE_ADD_DEL_LOCATOR, mp);
16572
16573   mp->is_add = is_add;
16574   mp->sw_if_index = ntohl (sw_if_index);
16575   mp->priority = priority;
16576   mp->weight = weight;
16577   clib_memcpy (mp->locator_set_name, locator_set_name,
16578                vec_len (locator_set_name));
16579   vec_free (locator_set_name);
16580
16581   /* send it... */
16582   S (mp);
16583
16584   /* Wait for a reply... */
16585   W (ret);
16586   return ret;
16587 }
16588
16589 #define api_lisp_add_del_locator api_one_add_del_locator
16590
16591 uword
16592 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16593 {
16594   u32 *key_id = va_arg (*args, u32 *);
16595   u8 *s = 0;
16596
16597   if (unformat (input, "%s", &s))
16598     {
16599       if (!strcmp ((char *) s, "sha1"))
16600         key_id[0] = HMAC_SHA_1_96;
16601       else if (!strcmp ((char *) s, "sha256"))
16602         key_id[0] = HMAC_SHA_256_128;
16603       else
16604         {
16605           clib_warning ("invalid key_id: '%s'", s);
16606           key_id[0] = HMAC_NO_KEY;
16607         }
16608     }
16609   else
16610     return 0;
16611
16612   vec_free (s);
16613   return 1;
16614 }
16615
16616 static int
16617 api_one_add_del_local_eid (vat_main_t * vam)
16618 {
16619   unformat_input_t *input = vam->input;
16620   vl_api_one_add_del_local_eid_t *mp;
16621   u8 is_add = 1;
16622   u8 eid_set = 0;
16623   lisp_eid_vat_t _eid, *eid = &_eid;
16624   u8 *locator_set_name = 0;
16625   u8 locator_set_name_set = 0;
16626   u32 vni = 0;
16627   u16 key_id = 0;
16628   u8 *key = 0;
16629   int ret;
16630
16631   /* Parse args required to build the message */
16632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16633     {
16634       if (unformat (input, "del"))
16635         {
16636           is_add = 0;
16637         }
16638       else if (unformat (input, "vni %d", &vni))
16639         {
16640           ;
16641         }
16642       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16643         {
16644           eid_set = 1;
16645         }
16646       else if (unformat (input, "locator-set %s", &locator_set_name))
16647         {
16648           locator_set_name_set = 1;
16649         }
16650       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16651         ;
16652       else if (unformat (input, "secret-key %_%v%_", &key))
16653         ;
16654       else
16655         break;
16656     }
16657
16658   if (locator_set_name_set == 0)
16659     {
16660       errmsg ("missing locator-set name");
16661       return -99;
16662     }
16663
16664   if (0 == eid_set)
16665     {
16666       errmsg ("EID address not set!");
16667       vec_free (locator_set_name);
16668       return -99;
16669     }
16670
16671   if (key && (0 == key_id))
16672     {
16673       errmsg ("invalid key_id!");
16674       return -99;
16675     }
16676
16677   if (vec_len (key) > 64)
16678     {
16679       errmsg ("key too long");
16680       vec_free (key);
16681       return -99;
16682     }
16683
16684   if (vec_len (locator_set_name) > 64)
16685     {
16686       errmsg ("locator-set name too long");
16687       vec_free (locator_set_name);
16688       return -99;
16689     }
16690   vec_add1 (locator_set_name, 0);
16691
16692   /* Construct the API message */
16693   M (ONE_ADD_DEL_LOCAL_EID, mp);
16694
16695   mp->is_add = is_add;
16696   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16697   mp->eid_type = eid->type;
16698   mp->prefix_len = eid->len;
16699   mp->vni = clib_host_to_net_u32 (vni);
16700   mp->key_id = clib_host_to_net_u16 (key_id);
16701   clib_memcpy (mp->locator_set_name, locator_set_name,
16702                vec_len (locator_set_name));
16703   clib_memcpy (mp->key, key, vec_len (key));
16704
16705   vec_free (locator_set_name);
16706   vec_free (key);
16707
16708   /* send it... */
16709   S (mp);
16710
16711   /* Wait for a reply... */
16712   W (ret);
16713   return ret;
16714 }
16715
16716 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16717
16718 static int
16719 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16720 {
16721   u32 dp_table = 0, vni = 0;;
16722   unformat_input_t *input = vam->input;
16723   vl_api_gpe_add_del_fwd_entry_t *mp;
16724   u8 is_add = 1;
16725   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16726   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16727   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16728   u32 action = ~0, w;
16729   ip4_address_t rmt_rloc4, lcl_rloc4;
16730   ip6_address_t rmt_rloc6, lcl_rloc6;
16731   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16732   int ret;
16733
16734   clib_memset (&rloc, 0, sizeof (rloc));
16735
16736   /* Parse args required to build the message */
16737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16738     {
16739       if (unformat (input, "del"))
16740         is_add = 0;
16741       else if (unformat (input, "add"))
16742         is_add = 1;
16743       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16744         {
16745           rmt_eid_set = 1;
16746         }
16747       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16748         {
16749           lcl_eid_set = 1;
16750         }
16751       else if (unformat (input, "vrf %d", &dp_table))
16752         ;
16753       else if (unformat (input, "bd %d", &dp_table))
16754         ;
16755       else if (unformat (input, "vni %d", &vni))
16756         ;
16757       else if (unformat (input, "w %d", &w))
16758         {
16759           if (!curr_rloc)
16760             {
16761               errmsg ("No RLOC configured for setting priority/weight!");
16762               return -99;
16763             }
16764           curr_rloc->weight = w;
16765         }
16766       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16767                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16768         {
16769           rloc.is_ip4 = 1;
16770
16771           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16772           rloc.weight = 0;
16773           vec_add1 (lcl_locs, rloc);
16774
16775           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16776           vec_add1 (rmt_locs, rloc);
16777           /* weight saved in rmt loc */
16778           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16779         }
16780       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16781                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16782         {
16783           rloc.is_ip4 = 0;
16784           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16785           rloc.weight = 0;
16786           vec_add1 (lcl_locs, rloc);
16787
16788           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16789           vec_add1 (rmt_locs, rloc);
16790           /* weight saved in rmt loc */
16791           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16792         }
16793       else if (unformat (input, "action %d", &action))
16794         {
16795           ;
16796         }
16797       else
16798         {
16799           clib_warning ("parse error '%U'", format_unformat_error, input);
16800           return -99;
16801         }
16802     }
16803
16804   if (!rmt_eid_set)
16805     {
16806       errmsg ("remote eid addresses not set");
16807       return -99;
16808     }
16809
16810   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16811     {
16812       errmsg ("eid types don't match");
16813       return -99;
16814     }
16815
16816   if (0 == rmt_locs && (u32) ~ 0 == action)
16817     {
16818       errmsg ("action not set for negative mapping");
16819       return -99;
16820     }
16821
16822   /* Construct the API message */
16823   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16824       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16825
16826   mp->is_add = is_add;
16827   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16828   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16829   mp->eid_type = rmt_eid->type;
16830   mp->dp_table = clib_host_to_net_u32 (dp_table);
16831   mp->vni = clib_host_to_net_u32 (vni);
16832   mp->rmt_len = rmt_eid->len;
16833   mp->lcl_len = lcl_eid->len;
16834   mp->action = action;
16835
16836   if (0 != rmt_locs && 0 != lcl_locs)
16837     {
16838       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16839       clib_memcpy (mp->locs, lcl_locs,
16840                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16841
16842       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16843       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16844                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16845     }
16846   vec_free (lcl_locs);
16847   vec_free (rmt_locs);
16848
16849   /* send it... */
16850   S (mp);
16851
16852   /* Wait for a reply... */
16853   W (ret);
16854   return ret;
16855 }
16856
16857 static int
16858 api_one_add_del_map_server (vat_main_t * vam)
16859 {
16860   unformat_input_t *input = vam->input;
16861   vl_api_one_add_del_map_server_t *mp;
16862   u8 is_add = 1;
16863   u8 ipv4_set = 0;
16864   u8 ipv6_set = 0;
16865   ip4_address_t ipv4;
16866   ip6_address_t ipv6;
16867   int ret;
16868
16869   /* Parse args required to build the message */
16870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16871     {
16872       if (unformat (input, "del"))
16873         {
16874           is_add = 0;
16875         }
16876       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16877         {
16878           ipv4_set = 1;
16879         }
16880       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16881         {
16882           ipv6_set = 1;
16883         }
16884       else
16885         break;
16886     }
16887
16888   if (ipv4_set && ipv6_set)
16889     {
16890       errmsg ("both eid v4 and v6 addresses set");
16891       return -99;
16892     }
16893
16894   if (!ipv4_set && !ipv6_set)
16895     {
16896       errmsg ("eid addresses not set");
16897       return -99;
16898     }
16899
16900   /* Construct the API message */
16901   M (ONE_ADD_DEL_MAP_SERVER, mp);
16902
16903   mp->is_add = is_add;
16904   if (ipv6_set)
16905     {
16906       mp->is_ipv6 = 1;
16907       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16908     }
16909   else
16910     {
16911       mp->is_ipv6 = 0;
16912       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16913     }
16914
16915   /* send it... */
16916   S (mp);
16917
16918   /* Wait for a reply... */
16919   W (ret);
16920   return ret;
16921 }
16922
16923 #define api_lisp_add_del_map_server api_one_add_del_map_server
16924
16925 static int
16926 api_one_add_del_map_resolver (vat_main_t * vam)
16927 {
16928   unformat_input_t *input = vam->input;
16929   vl_api_one_add_del_map_resolver_t *mp;
16930   u8 is_add = 1;
16931   u8 ipv4_set = 0;
16932   u8 ipv6_set = 0;
16933   ip4_address_t ipv4;
16934   ip6_address_t ipv6;
16935   int ret;
16936
16937   /* Parse args required to build the message */
16938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16939     {
16940       if (unformat (input, "del"))
16941         {
16942           is_add = 0;
16943         }
16944       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16945         {
16946           ipv4_set = 1;
16947         }
16948       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16949         {
16950           ipv6_set = 1;
16951         }
16952       else
16953         break;
16954     }
16955
16956   if (ipv4_set && ipv6_set)
16957     {
16958       errmsg ("both eid v4 and v6 addresses set");
16959       return -99;
16960     }
16961
16962   if (!ipv4_set && !ipv6_set)
16963     {
16964       errmsg ("eid addresses not set");
16965       return -99;
16966     }
16967
16968   /* Construct the API message */
16969   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16970
16971   mp->is_add = is_add;
16972   if (ipv6_set)
16973     {
16974       mp->is_ipv6 = 1;
16975       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16976     }
16977   else
16978     {
16979       mp->is_ipv6 = 0;
16980       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16981     }
16982
16983   /* send it... */
16984   S (mp);
16985
16986   /* Wait for a reply... */
16987   W (ret);
16988   return ret;
16989 }
16990
16991 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16992
16993 static int
16994 api_lisp_gpe_enable_disable (vat_main_t * vam)
16995 {
16996   unformat_input_t *input = vam->input;
16997   vl_api_gpe_enable_disable_t *mp;
16998   u8 is_set = 0;
16999   u8 is_en = 1;
17000   int ret;
17001
17002   /* Parse args required to build the message */
17003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17004     {
17005       if (unformat (input, "enable"))
17006         {
17007           is_set = 1;
17008           is_en = 1;
17009         }
17010       else if (unformat (input, "disable"))
17011         {
17012           is_set = 1;
17013           is_en = 0;
17014         }
17015       else
17016         break;
17017     }
17018
17019   if (is_set == 0)
17020     {
17021       errmsg ("Value not set");
17022       return -99;
17023     }
17024
17025   /* Construct the API message */
17026   M (GPE_ENABLE_DISABLE, mp);
17027
17028   mp->is_en = is_en;
17029
17030   /* send it... */
17031   S (mp);
17032
17033   /* Wait for a reply... */
17034   W (ret);
17035   return ret;
17036 }
17037
17038 static int
17039 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17040 {
17041   unformat_input_t *input = vam->input;
17042   vl_api_one_rloc_probe_enable_disable_t *mp;
17043   u8 is_set = 0;
17044   u8 is_en = 0;
17045   int ret;
17046
17047   /* Parse args required to build the message */
17048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17049     {
17050       if (unformat (input, "enable"))
17051         {
17052           is_set = 1;
17053           is_en = 1;
17054         }
17055       else if (unformat (input, "disable"))
17056         is_set = 1;
17057       else
17058         break;
17059     }
17060
17061   if (!is_set)
17062     {
17063       errmsg ("Value not set");
17064       return -99;
17065     }
17066
17067   /* Construct the API message */
17068   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17069
17070   mp->is_enabled = is_en;
17071
17072   /* send it... */
17073   S (mp);
17074
17075   /* Wait for a reply... */
17076   W (ret);
17077   return ret;
17078 }
17079
17080 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17081
17082 static int
17083 api_one_map_register_enable_disable (vat_main_t * vam)
17084 {
17085   unformat_input_t *input = vam->input;
17086   vl_api_one_map_register_enable_disable_t *mp;
17087   u8 is_set = 0;
17088   u8 is_en = 0;
17089   int ret;
17090
17091   /* Parse args required to build the message */
17092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17093     {
17094       if (unformat (input, "enable"))
17095         {
17096           is_set = 1;
17097           is_en = 1;
17098         }
17099       else if (unformat (input, "disable"))
17100         is_set = 1;
17101       else
17102         break;
17103     }
17104
17105   if (!is_set)
17106     {
17107       errmsg ("Value not set");
17108       return -99;
17109     }
17110
17111   /* Construct the API message */
17112   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17113
17114   mp->is_enabled = is_en;
17115
17116   /* send it... */
17117   S (mp);
17118
17119   /* Wait for a reply... */
17120   W (ret);
17121   return ret;
17122 }
17123
17124 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17125
17126 static int
17127 api_one_enable_disable (vat_main_t * vam)
17128 {
17129   unformat_input_t *input = vam->input;
17130   vl_api_one_enable_disable_t *mp;
17131   u8 is_set = 0;
17132   u8 is_en = 0;
17133   int ret;
17134
17135   /* Parse args required to build the message */
17136   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17137     {
17138       if (unformat (input, "enable"))
17139         {
17140           is_set = 1;
17141           is_en = 1;
17142         }
17143       else if (unformat (input, "disable"))
17144         {
17145           is_set = 1;
17146         }
17147       else
17148         break;
17149     }
17150
17151   if (!is_set)
17152     {
17153       errmsg ("Value not set");
17154       return -99;
17155     }
17156
17157   /* Construct the API message */
17158   M (ONE_ENABLE_DISABLE, mp);
17159
17160   mp->is_en = is_en;
17161
17162   /* send it... */
17163   S (mp);
17164
17165   /* Wait for a reply... */
17166   W (ret);
17167   return ret;
17168 }
17169
17170 #define api_lisp_enable_disable api_one_enable_disable
17171
17172 static int
17173 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17174 {
17175   unformat_input_t *input = vam->input;
17176   vl_api_one_enable_disable_xtr_mode_t *mp;
17177   u8 is_set = 0;
17178   u8 is_en = 0;
17179   int ret;
17180
17181   /* Parse args required to build the message */
17182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17183     {
17184       if (unformat (input, "enable"))
17185         {
17186           is_set = 1;
17187           is_en = 1;
17188         }
17189       else if (unformat (input, "disable"))
17190         {
17191           is_set = 1;
17192         }
17193       else
17194         break;
17195     }
17196
17197   if (!is_set)
17198     {
17199       errmsg ("Value not set");
17200       return -99;
17201     }
17202
17203   /* Construct the API message */
17204   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17205
17206   mp->is_en = is_en;
17207
17208   /* send it... */
17209   S (mp);
17210
17211   /* Wait for a reply... */
17212   W (ret);
17213   return ret;
17214 }
17215
17216 static int
17217 api_one_show_xtr_mode (vat_main_t * vam)
17218 {
17219   vl_api_one_show_xtr_mode_t *mp;
17220   int ret;
17221
17222   /* Construct the API message */
17223   M (ONE_SHOW_XTR_MODE, mp);
17224
17225   /* send it... */
17226   S (mp);
17227
17228   /* Wait for a reply... */
17229   W (ret);
17230   return ret;
17231 }
17232
17233 static int
17234 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17235 {
17236   unformat_input_t *input = vam->input;
17237   vl_api_one_enable_disable_pitr_mode_t *mp;
17238   u8 is_set = 0;
17239   u8 is_en = 0;
17240   int ret;
17241
17242   /* Parse args required to build the message */
17243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17244     {
17245       if (unformat (input, "enable"))
17246         {
17247           is_set = 1;
17248           is_en = 1;
17249         }
17250       else if (unformat (input, "disable"))
17251         {
17252           is_set = 1;
17253         }
17254       else
17255         break;
17256     }
17257
17258   if (!is_set)
17259     {
17260       errmsg ("Value not set");
17261       return -99;
17262     }
17263
17264   /* Construct the API message */
17265   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17266
17267   mp->is_en = is_en;
17268
17269   /* send it... */
17270   S (mp);
17271
17272   /* Wait for a reply... */
17273   W (ret);
17274   return ret;
17275 }
17276
17277 static int
17278 api_one_show_pitr_mode (vat_main_t * vam)
17279 {
17280   vl_api_one_show_pitr_mode_t *mp;
17281   int ret;
17282
17283   /* Construct the API message */
17284   M (ONE_SHOW_PITR_MODE, mp);
17285
17286   /* send it... */
17287   S (mp);
17288
17289   /* Wait for a reply... */
17290   W (ret);
17291   return ret;
17292 }
17293
17294 static int
17295 api_one_enable_disable_petr_mode (vat_main_t * vam)
17296 {
17297   unformat_input_t *input = vam->input;
17298   vl_api_one_enable_disable_petr_mode_t *mp;
17299   u8 is_set = 0;
17300   u8 is_en = 0;
17301   int ret;
17302
17303   /* Parse args required to build the message */
17304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17305     {
17306       if (unformat (input, "enable"))
17307         {
17308           is_set = 1;
17309           is_en = 1;
17310         }
17311       else if (unformat (input, "disable"))
17312         {
17313           is_set = 1;
17314         }
17315       else
17316         break;
17317     }
17318
17319   if (!is_set)
17320     {
17321       errmsg ("Value not set");
17322       return -99;
17323     }
17324
17325   /* Construct the API message */
17326   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17327
17328   mp->is_en = is_en;
17329
17330   /* send it... */
17331   S (mp);
17332
17333   /* Wait for a reply... */
17334   W (ret);
17335   return ret;
17336 }
17337
17338 static int
17339 api_one_show_petr_mode (vat_main_t * vam)
17340 {
17341   vl_api_one_show_petr_mode_t *mp;
17342   int ret;
17343
17344   /* Construct the API message */
17345   M (ONE_SHOW_PETR_MODE, mp);
17346
17347   /* send it... */
17348   S (mp);
17349
17350   /* Wait for a reply... */
17351   W (ret);
17352   return ret;
17353 }
17354
17355 static int
17356 api_show_one_map_register_state (vat_main_t * vam)
17357 {
17358   vl_api_show_one_map_register_state_t *mp;
17359   int ret;
17360
17361   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17362
17363   /* send */
17364   S (mp);
17365
17366   /* wait for reply */
17367   W (ret);
17368   return ret;
17369 }
17370
17371 #define api_show_lisp_map_register_state api_show_one_map_register_state
17372
17373 static int
17374 api_show_one_rloc_probe_state (vat_main_t * vam)
17375 {
17376   vl_api_show_one_rloc_probe_state_t *mp;
17377   int ret;
17378
17379   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17380
17381   /* send */
17382   S (mp);
17383
17384   /* wait for reply */
17385   W (ret);
17386   return ret;
17387 }
17388
17389 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17390
17391 static int
17392 api_one_add_del_ndp_entry (vat_main_t * vam)
17393 {
17394   vl_api_one_add_del_ndp_entry_t *mp;
17395   unformat_input_t *input = vam->input;
17396   u8 is_add = 1;
17397   u8 mac_set = 0;
17398   u8 bd_set = 0;
17399   u8 ip_set = 0;
17400   u8 mac[6] = { 0, };
17401   u8 ip6[16] = { 0, };
17402   u32 bd = ~0;
17403   int ret;
17404
17405   /* Parse args required to build the message */
17406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17407     {
17408       if (unformat (input, "del"))
17409         is_add = 0;
17410       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17411         mac_set = 1;
17412       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17413         ip_set = 1;
17414       else if (unformat (input, "bd %d", &bd))
17415         bd_set = 1;
17416       else
17417         {
17418           errmsg ("parse error '%U'", format_unformat_error, input);
17419           return -99;
17420         }
17421     }
17422
17423   if (!bd_set || !ip_set || (!mac_set && is_add))
17424     {
17425       errmsg ("Missing BD, IP or MAC!");
17426       return -99;
17427     }
17428
17429   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17430   mp->is_add = is_add;
17431   clib_memcpy (mp->mac, mac, 6);
17432   mp->bd = clib_host_to_net_u32 (bd);
17433   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17434
17435   /* send */
17436   S (mp);
17437
17438   /* wait for reply */
17439   W (ret);
17440   return ret;
17441 }
17442
17443 static int
17444 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17445 {
17446   vl_api_one_add_del_l2_arp_entry_t *mp;
17447   unformat_input_t *input = vam->input;
17448   u8 is_add = 1;
17449   u8 mac_set = 0;
17450   u8 bd_set = 0;
17451   u8 ip_set = 0;
17452   u8 mac[6] = { 0, };
17453   u32 ip4 = 0, bd = ~0;
17454   int ret;
17455
17456   /* Parse args required to build the message */
17457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17458     {
17459       if (unformat (input, "del"))
17460         is_add = 0;
17461       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17462         mac_set = 1;
17463       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17464         ip_set = 1;
17465       else if (unformat (input, "bd %d", &bd))
17466         bd_set = 1;
17467       else
17468         {
17469           errmsg ("parse error '%U'", format_unformat_error, input);
17470           return -99;
17471         }
17472     }
17473
17474   if (!bd_set || !ip_set || (!mac_set && is_add))
17475     {
17476       errmsg ("Missing BD, IP or MAC!");
17477       return -99;
17478     }
17479
17480   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17481   mp->is_add = is_add;
17482   clib_memcpy (mp->mac, mac, 6);
17483   mp->bd = clib_host_to_net_u32 (bd);
17484   mp->ip4 = ip4;
17485
17486   /* send */
17487   S (mp);
17488
17489   /* wait for reply */
17490   W (ret);
17491   return ret;
17492 }
17493
17494 static int
17495 api_one_ndp_bd_get (vat_main_t * vam)
17496 {
17497   vl_api_one_ndp_bd_get_t *mp;
17498   int ret;
17499
17500   M (ONE_NDP_BD_GET, mp);
17501
17502   /* send */
17503   S (mp);
17504
17505   /* wait for reply */
17506   W (ret);
17507   return ret;
17508 }
17509
17510 static int
17511 api_one_ndp_entries_get (vat_main_t * vam)
17512 {
17513   vl_api_one_ndp_entries_get_t *mp;
17514   unformat_input_t *input = vam->input;
17515   u8 bd_set = 0;
17516   u32 bd = ~0;
17517   int ret;
17518
17519   /* Parse args required to build the message */
17520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17521     {
17522       if (unformat (input, "bd %d", &bd))
17523         bd_set = 1;
17524       else
17525         {
17526           errmsg ("parse error '%U'", format_unformat_error, input);
17527           return -99;
17528         }
17529     }
17530
17531   if (!bd_set)
17532     {
17533       errmsg ("Expected bridge domain!");
17534       return -99;
17535     }
17536
17537   M (ONE_NDP_ENTRIES_GET, mp);
17538   mp->bd = clib_host_to_net_u32 (bd);
17539
17540   /* send */
17541   S (mp);
17542
17543   /* wait for reply */
17544   W (ret);
17545   return ret;
17546 }
17547
17548 static int
17549 api_one_l2_arp_bd_get (vat_main_t * vam)
17550 {
17551   vl_api_one_l2_arp_bd_get_t *mp;
17552   int ret;
17553
17554   M (ONE_L2_ARP_BD_GET, mp);
17555
17556   /* send */
17557   S (mp);
17558
17559   /* wait for reply */
17560   W (ret);
17561   return ret;
17562 }
17563
17564 static int
17565 api_one_l2_arp_entries_get (vat_main_t * vam)
17566 {
17567   vl_api_one_l2_arp_entries_get_t *mp;
17568   unformat_input_t *input = vam->input;
17569   u8 bd_set = 0;
17570   u32 bd = ~0;
17571   int ret;
17572
17573   /* Parse args required to build the message */
17574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17575     {
17576       if (unformat (input, "bd %d", &bd))
17577         bd_set = 1;
17578       else
17579         {
17580           errmsg ("parse error '%U'", format_unformat_error, input);
17581           return -99;
17582         }
17583     }
17584
17585   if (!bd_set)
17586     {
17587       errmsg ("Expected bridge domain!");
17588       return -99;
17589     }
17590
17591   M (ONE_L2_ARP_ENTRIES_GET, mp);
17592   mp->bd = clib_host_to_net_u32 (bd);
17593
17594   /* send */
17595   S (mp);
17596
17597   /* wait for reply */
17598   W (ret);
17599   return ret;
17600 }
17601
17602 static int
17603 api_one_stats_enable_disable (vat_main_t * vam)
17604 {
17605   vl_api_one_stats_enable_disable_t *mp;
17606   unformat_input_t *input = vam->input;
17607   u8 is_set = 0;
17608   u8 is_en = 0;
17609   int ret;
17610
17611   /* Parse args required to build the message */
17612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17613     {
17614       if (unformat (input, "enable"))
17615         {
17616           is_set = 1;
17617           is_en = 1;
17618         }
17619       else if (unformat (input, "disable"))
17620         {
17621           is_set = 1;
17622         }
17623       else
17624         break;
17625     }
17626
17627   if (!is_set)
17628     {
17629       errmsg ("Value not set");
17630       return -99;
17631     }
17632
17633   M (ONE_STATS_ENABLE_DISABLE, mp);
17634   mp->is_en = is_en;
17635
17636   /* send */
17637   S (mp);
17638
17639   /* wait for reply */
17640   W (ret);
17641   return ret;
17642 }
17643
17644 static int
17645 api_show_one_stats_enable_disable (vat_main_t * vam)
17646 {
17647   vl_api_show_one_stats_enable_disable_t *mp;
17648   int ret;
17649
17650   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17651
17652   /* send */
17653   S (mp);
17654
17655   /* wait for reply */
17656   W (ret);
17657   return ret;
17658 }
17659
17660 static int
17661 api_show_one_map_request_mode (vat_main_t * vam)
17662 {
17663   vl_api_show_one_map_request_mode_t *mp;
17664   int ret;
17665
17666   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17667
17668   /* send */
17669   S (mp);
17670
17671   /* wait for reply */
17672   W (ret);
17673   return ret;
17674 }
17675
17676 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17677
17678 static int
17679 api_one_map_request_mode (vat_main_t * vam)
17680 {
17681   unformat_input_t *input = vam->input;
17682   vl_api_one_map_request_mode_t *mp;
17683   u8 mode = 0;
17684   int ret;
17685
17686   /* Parse args required to build the message */
17687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17688     {
17689       if (unformat (input, "dst-only"))
17690         mode = 0;
17691       else if (unformat (input, "src-dst"))
17692         mode = 1;
17693       else
17694         {
17695           errmsg ("parse error '%U'", format_unformat_error, input);
17696           return -99;
17697         }
17698     }
17699
17700   M (ONE_MAP_REQUEST_MODE, mp);
17701
17702   mp->mode = mode;
17703
17704   /* send */
17705   S (mp);
17706
17707   /* wait for reply */
17708   W (ret);
17709   return ret;
17710 }
17711
17712 #define api_lisp_map_request_mode api_one_map_request_mode
17713
17714 /**
17715  * Enable/disable ONE proxy ITR.
17716  *
17717  * @param vam vpp API test context
17718  * @return return code
17719  */
17720 static int
17721 api_one_pitr_set_locator_set (vat_main_t * vam)
17722 {
17723   u8 ls_name_set = 0;
17724   unformat_input_t *input = vam->input;
17725   vl_api_one_pitr_set_locator_set_t *mp;
17726   u8 is_add = 1;
17727   u8 *ls_name = 0;
17728   int ret;
17729
17730   /* Parse args required to build the message */
17731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17732     {
17733       if (unformat (input, "del"))
17734         is_add = 0;
17735       else if (unformat (input, "locator-set %s", &ls_name))
17736         ls_name_set = 1;
17737       else
17738         {
17739           errmsg ("parse error '%U'", format_unformat_error, input);
17740           return -99;
17741         }
17742     }
17743
17744   if (!ls_name_set)
17745     {
17746       errmsg ("locator-set name not set!");
17747       return -99;
17748     }
17749
17750   M (ONE_PITR_SET_LOCATOR_SET, mp);
17751
17752   mp->is_add = is_add;
17753   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17754   vec_free (ls_name);
17755
17756   /* send */
17757   S (mp);
17758
17759   /* wait for reply */
17760   W (ret);
17761   return ret;
17762 }
17763
17764 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17765
17766 static int
17767 api_one_nsh_set_locator_set (vat_main_t * vam)
17768 {
17769   u8 ls_name_set = 0;
17770   unformat_input_t *input = vam->input;
17771   vl_api_one_nsh_set_locator_set_t *mp;
17772   u8 is_add = 1;
17773   u8 *ls_name = 0;
17774   int ret;
17775
17776   /* Parse args required to build the message */
17777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17778     {
17779       if (unformat (input, "del"))
17780         is_add = 0;
17781       else if (unformat (input, "ls %s", &ls_name))
17782         ls_name_set = 1;
17783       else
17784         {
17785           errmsg ("parse error '%U'", format_unformat_error, input);
17786           return -99;
17787         }
17788     }
17789
17790   if (!ls_name_set && is_add)
17791     {
17792       errmsg ("locator-set name not set!");
17793       return -99;
17794     }
17795
17796   M (ONE_NSH_SET_LOCATOR_SET, mp);
17797
17798   mp->is_add = is_add;
17799   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17800   vec_free (ls_name);
17801
17802   /* send */
17803   S (mp);
17804
17805   /* wait for reply */
17806   W (ret);
17807   return ret;
17808 }
17809
17810 static int
17811 api_show_one_pitr (vat_main_t * vam)
17812 {
17813   vl_api_show_one_pitr_t *mp;
17814   int ret;
17815
17816   if (!vam->json_output)
17817     {
17818       print (vam->ofp, "%=20s", "lisp status:");
17819     }
17820
17821   M (SHOW_ONE_PITR, mp);
17822   /* send it... */
17823   S (mp);
17824
17825   /* Wait for a reply... */
17826   W (ret);
17827   return ret;
17828 }
17829
17830 #define api_show_lisp_pitr api_show_one_pitr
17831
17832 static int
17833 api_one_use_petr (vat_main_t * vam)
17834 {
17835   unformat_input_t *input = vam->input;
17836   vl_api_one_use_petr_t *mp;
17837   u8 is_add = 0;
17838   ip_address_t ip;
17839   int ret;
17840
17841   clib_memset (&ip, 0, sizeof (ip));
17842
17843   /* Parse args required to build the message */
17844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17845     {
17846       if (unformat (input, "disable"))
17847         is_add = 0;
17848       else
17849         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17850         {
17851           is_add = 1;
17852           ip_addr_version (&ip) = IP4;
17853         }
17854       else
17855         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17856         {
17857           is_add = 1;
17858           ip_addr_version (&ip) = IP6;
17859         }
17860       else
17861         {
17862           errmsg ("parse error '%U'", format_unformat_error, input);
17863           return -99;
17864         }
17865     }
17866
17867   M (ONE_USE_PETR, mp);
17868
17869   mp->is_add = is_add;
17870   if (is_add)
17871     {
17872       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17873       if (mp->is_ip4)
17874         clib_memcpy (mp->address, &ip, 4);
17875       else
17876         clib_memcpy (mp->address, &ip, 16);
17877     }
17878
17879   /* send */
17880   S (mp);
17881
17882   /* wait for reply */
17883   W (ret);
17884   return ret;
17885 }
17886
17887 #define api_lisp_use_petr api_one_use_petr
17888
17889 static int
17890 api_show_one_nsh_mapping (vat_main_t * vam)
17891 {
17892   vl_api_show_one_use_petr_t *mp;
17893   int ret;
17894
17895   if (!vam->json_output)
17896     {
17897       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17898     }
17899
17900   M (SHOW_ONE_NSH_MAPPING, mp);
17901   /* send it... */
17902   S (mp);
17903
17904   /* Wait for a reply... */
17905   W (ret);
17906   return ret;
17907 }
17908
17909 static int
17910 api_show_one_use_petr (vat_main_t * vam)
17911 {
17912   vl_api_show_one_use_petr_t *mp;
17913   int ret;
17914
17915   if (!vam->json_output)
17916     {
17917       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17918     }
17919
17920   M (SHOW_ONE_USE_PETR, mp);
17921   /* send it... */
17922   S (mp);
17923
17924   /* Wait for a reply... */
17925   W (ret);
17926   return ret;
17927 }
17928
17929 #define api_show_lisp_use_petr api_show_one_use_petr
17930
17931 /**
17932  * Add/delete mapping between vni and vrf
17933  */
17934 static int
17935 api_one_eid_table_add_del_map (vat_main_t * vam)
17936 {
17937   unformat_input_t *input = vam->input;
17938   vl_api_one_eid_table_add_del_map_t *mp;
17939   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17940   u32 vni, vrf, bd_index;
17941   int ret;
17942
17943   /* Parse args required to build the message */
17944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17945     {
17946       if (unformat (input, "del"))
17947         is_add = 0;
17948       else if (unformat (input, "vrf %d", &vrf))
17949         vrf_set = 1;
17950       else if (unformat (input, "bd_index %d", &bd_index))
17951         bd_index_set = 1;
17952       else if (unformat (input, "vni %d", &vni))
17953         vni_set = 1;
17954       else
17955         break;
17956     }
17957
17958   if (!vni_set || (!vrf_set && !bd_index_set))
17959     {
17960       errmsg ("missing arguments!");
17961       return -99;
17962     }
17963
17964   if (vrf_set && bd_index_set)
17965     {
17966       errmsg ("error: both vrf and bd entered!");
17967       return -99;
17968     }
17969
17970   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17971
17972   mp->is_add = is_add;
17973   mp->vni = htonl (vni);
17974   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17975   mp->is_l2 = bd_index_set;
17976
17977   /* send */
17978   S (mp);
17979
17980   /* wait for reply */
17981   W (ret);
17982   return ret;
17983 }
17984
17985 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17986
17987 uword
17988 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17989 {
17990   u32 *action = va_arg (*args, u32 *);
17991   u8 *s = 0;
17992
17993   if (unformat (input, "%s", &s))
17994     {
17995       if (!strcmp ((char *) s, "no-action"))
17996         action[0] = 0;
17997       else if (!strcmp ((char *) s, "natively-forward"))
17998         action[0] = 1;
17999       else if (!strcmp ((char *) s, "send-map-request"))
18000         action[0] = 2;
18001       else if (!strcmp ((char *) s, "drop"))
18002         action[0] = 3;
18003       else
18004         {
18005           clib_warning ("invalid action: '%s'", s);
18006           action[0] = 3;
18007         }
18008     }
18009   else
18010     return 0;
18011
18012   vec_free (s);
18013   return 1;
18014 }
18015
18016 /**
18017  * Add/del remote mapping to/from ONE control plane
18018  *
18019  * @param vam vpp API test context
18020  * @return return code
18021  */
18022 static int
18023 api_one_add_del_remote_mapping (vat_main_t * vam)
18024 {
18025   unformat_input_t *input = vam->input;
18026   vl_api_one_add_del_remote_mapping_t *mp;
18027   u32 vni = 0;
18028   lisp_eid_vat_t _eid, *eid = &_eid;
18029   lisp_eid_vat_t _seid, *seid = &_seid;
18030   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18031   u32 action = ~0, p, w, data_len;
18032   ip4_address_t rloc4;
18033   ip6_address_t rloc6;
18034   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18035   int ret;
18036
18037   clib_memset (&rloc, 0, sizeof (rloc));
18038
18039   /* Parse args required to build the message */
18040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18041     {
18042       if (unformat (input, "del-all"))
18043         {
18044           del_all = 1;
18045         }
18046       else if (unformat (input, "del"))
18047         {
18048           is_add = 0;
18049         }
18050       else if (unformat (input, "add"))
18051         {
18052           is_add = 1;
18053         }
18054       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18055         {
18056           eid_set = 1;
18057         }
18058       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18059         {
18060           seid_set = 1;
18061         }
18062       else if (unformat (input, "vni %d", &vni))
18063         {
18064           ;
18065         }
18066       else if (unformat (input, "p %d w %d", &p, &w))
18067         {
18068           if (!curr_rloc)
18069             {
18070               errmsg ("No RLOC configured for setting priority/weight!");
18071               return -99;
18072             }
18073           curr_rloc->priority = p;
18074           curr_rloc->weight = w;
18075         }
18076       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18077         {
18078           rloc.is_ip4 = 1;
18079           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18080           vec_add1 (rlocs, rloc);
18081           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18082         }
18083       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18084         {
18085           rloc.is_ip4 = 0;
18086           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18087           vec_add1 (rlocs, rloc);
18088           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18089         }
18090       else if (unformat (input, "action %U",
18091                          unformat_negative_mapping_action, &action))
18092         {
18093           ;
18094         }
18095       else
18096         {
18097           clib_warning ("parse error '%U'", format_unformat_error, input);
18098           return -99;
18099         }
18100     }
18101
18102   if (0 == eid_set)
18103     {
18104       errmsg ("missing params!");
18105       return -99;
18106     }
18107
18108   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18109     {
18110       errmsg ("no action set for negative map-reply!");
18111       return -99;
18112     }
18113
18114   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18115
18116   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18117   mp->is_add = is_add;
18118   mp->vni = htonl (vni);
18119   mp->action = (u8) action;
18120   mp->is_src_dst = seid_set;
18121   mp->eid_len = eid->len;
18122   mp->seid_len = seid->len;
18123   mp->del_all = del_all;
18124   mp->eid_type = eid->type;
18125   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18126   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18127
18128   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18129   clib_memcpy (mp->rlocs, rlocs, data_len);
18130   vec_free (rlocs);
18131
18132   /* send it... */
18133   S (mp);
18134
18135   /* Wait for a reply... */
18136   W (ret);
18137   return ret;
18138 }
18139
18140 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18141
18142 /**
18143  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18144  * forwarding entries in data-plane accordingly.
18145  *
18146  * @param vam vpp API test context
18147  * @return return code
18148  */
18149 static int
18150 api_one_add_del_adjacency (vat_main_t * vam)
18151 {
18152   unformat_input_t *input = vam->input;
18153   vl_api_one_add_del_adjacency_t *mp;
18154   u32 vni = 0;
18155   ip4_address_t leid4, reid4;
18156   ip6_address_t leid6, reid6;
18157   u8 reid_mac[6] = { 0 };
18158   u8 leid_mac[6] = { 0 };
18159   u8 reid_type, leid_type;
18160   u32 leid_len = 0, reid_len = 0, len;
18161   u8 is_add = 1;
18162   int ret;
18163
18164   leid_type = reid_type = (u8) ~ 0;
18165
18166   /* Parse args required to build the message */
18167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18168     {
18169       if (unformat (input, "del"))
18170         {
18171           is_add = 0;
18172         }
18173       else if (unformat (input, "add"))
18174         {
18175           is_add = 1;
18176         }
18177       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18178                          &reid4, &len))
18179         {
18180           reid_type = 0;        /* ipv4 */
18181           reid_len = len;
18182         }
18183       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18184                          &reid6, &len))
18185         {
18186           reid_type = 1;        /* ipv6 */
18187           reid_len = len;
18188         }
18189       else if (unformat (input, "reid %U", unformat_ethernet_address,
18190                          reid_mac))
18191         {
18192           reid_type = 2;        /* mac */
18193         }
18194       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18195                          &leid4, &len))
18196         {
18197           leid_type = 0;        /* ipv4 */
18198           leid_len = len;
18199         }
18200       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18201                          &leid6, &len))
18202         {
18203           leid_type = 1;        /* ipv6 */
18204           leid_len = len;
18205         }
18206       else if (unformat (input, "leid %U", unformat_ethernet_address,
18207                          leid_mac))
18208         {
18209           leid_type = 2;        /* mac */
18210         }
18211       else if (unformat (input, "vni %d", &vni))
18212         {
18213           ;
18214         }
18215       else
18216         {
18217           errmsg ("parse error '%U'", format_unformat_error, input);
18218           return -99;
18219         }
18220     }
18221
18222   if ((u8) ~ 0 == reid_type)
18223     {
18224       errmsg ("missing params!");
18225       return -99;
18226     }
18227
18228   if (leid_type != reid_type)
18229     {
18230       errmsg ("remote and local EIDs are of different types!");
18231       return -99;
18232     }
18233
18234   M (ONE_ADD_DEL_ADJACENCY, mp);
18235   mp->is_add = is_add;
18236   mp->vni = htonl (vni);
18237   mp->leid_len = leid_len;
18238   mp->reid_len = reid_len;
18239   mp->eid_type = reid_type;
18240
18241   switch (mp->eid_type)
18242     {
18243     case 0:
18244       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18245       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18246       break;
18247     case 1:
18248       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18249       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18250       break;
18251     case 2:
18252       clib_memcpy (mp->leid, leid_mac, 6);
18253       clib_memcpy (mp->reid, reid_mac, 6);
18254       break;
18255     default:
18256       errmsg ("unknown EID type %d!", mp->eid_type);
18257       return 0;
18258     }
18259
18260   /* send it... */
18261   S (mp);
18262
18263   /* Wait for a reply... */
18264   W (ret);
18265   return ret;
18266 }
18267
18268 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18269
18270 uword
18271 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18272 {
18273   u32 *mode = va_arg (*args, u32 *);
18274
18275   if (unformat (input, "lisp"))
18276     *mode = 0;
18277   else if (unformat (input, "vxlan"))
18278     *mode = 1;
18279   else
18280     return 0;
18281
18282   return 1;
18283 }
18284
18285 static int
18286 api_gpe_get_encap_mode (vat_main_t * vam)
18287 {
18288   vl_api_gpe_get_encap_mode_t *mp;
18289   int ret;
18290
18291   /* Construct the API message */
18292   M (GPE_GET_ENCAP_MODE, mp);
18293
18294   /* send it... */
18295   S (mp);
18296
18297   /* Wait for a reply... */
18298   W (ret);
18299   return ret;
18300 }
18301
18302 static int
18303 api_gpe_set_encap_mode (vat_main_t * vam)
18304 {
18305   unformat_input_t *input = vam->input;
18306   vl_api_gpe_set_encap_mode_t *mp;
18307   int ret;
18308   u32 mode = 0;
18309
18310   /* Parse args required to build the message */
18311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18312     {
18313       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18314         ;
18315       else
18316         break;
18317     }
18318
18319   /* Construct the API message */
18320   M (GPE_SET_ENCAP_MODE, mp);
18321
18322   mp->mode = mode;
18323
18324   /* send it... */
18325   S (mp);
18326
18327   /* Wait for a reply... */
18328   W (ret);
18329   return ret;
18330 }
18331
18332 static int
18333 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18334 {
18335   unformat_input_t *input = vam->input;
18336   vl_api_gpe_add_del_iface_t *mp;
18337   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18338   u32 dp_table = 0, vni = 0;
18339   int ret;
18340
18341   /* Parse args required to build the message */
18342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18343     {
18344       if (unformat (input, "up"))
18345         {
18346           action_set = 1;
18347           is_add = 1;
18348         }
18349       else if (unformat (input, "down"))
18350         {
18351           action_set = 1;
18352           is_add = 0;
18353         }
18354       else if (unformat (input, "table_id %d", &dp_table))
18355         {
18356           dp_table_set = 1;
18357         }
18358       else if (unformat (input, "bd_id %d", &dp_table))
18359         {
18360           dp_table_set = 1;
18361           is_l2 = 1;
18362         }
18363       else if (unformat (input, "vni %d", &vni))
18364         {
18365           vni_set = 1;
18366         }
18367       else
18368         break;
18369     }
18370
18371   if (action_set == 0)
18372     {
18373       errmsg ("Action not set");
18374       return -99;
18375     }
18376   if (dp_table_set == 0 || vni_set == 0)
18377     {
18378       errmsg ("vni and dp_table must be set");
18379       return -99;
18380     }
18381
18382   /* Construct the API message */
18383   M (GPE_ADD_DEL_IFACE, mp);
18384
18385   mp->is_add = is_add;
18386   mp->dp_table = clib_host_to_net_u32 (dp_table);
18387   mp->is_l2 = is_l2;
18388   mp->vni = clib_host_to_net_u32 (vni);
18389
18390   /* send it... */
18391   S (mp);
18392
18393   /* Wait for a reply... */
18394   W (ret);
18395   return ret;
18396 }
18397
18398 static int
18399 api_one_map_register_fallback_threshold (vat_main_t * vam)
18400 {
18401   unformat_input_t *input = vam->input;
18402   vl_api_one_map_register_fallback_threshold_t *mp;
18403   u32 value = 0;
18404   u8 is_set = 0;
18405   int ret;
18406
18407   /* Parse args required to build the message */
18408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18409     {
18410       if (unformat (input, "%u", &value))
18411         is_set = 1;
18412       else
18413         {
18414           clib_warning ("parse error '%U'", format_unformat_error, input);
18415           return -99;
18416         }
18417     }
18418
18419   if (!is_set)
18420     {
18421       errmsg ("fallback threshold value is missing!");
18422       return -99;
18423     }
18424
18425   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18426   mp->value = clib_host_to_net_u32 (value);
18427
18428   /* send it... */
18429   S (mp);
18430
18431   /* Wait for a reply... */
18432   W (ret);
18433   return ret;
18434 }
18435
18436 static int
18437 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18438 {
18439   vl_api_show_one_map_register_fallback_threshold_t *mp;
18440   int ret;
18441
18442   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18443
18444   /* send it... */
18445   S (mp);
18446
18447   /* Wait for a reply... */
18448   W (ret);
18449   return ret;
18450 }
18451
18452 uword
18453 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18454 {
18455   u32 *proto = va_arg (*args, u32 *);
18456
18457   if (unformat (input, "udp"))
18458     *proto = 1;
18459   else if (unformat (input, "api"))
18460     *proto = 2;
18461   else
18462     return 0;
18463
18464   return 1;
18465 }
18466
18467 static int
18468 api_one_set_transport_protocol (vat_main_t * vam)
18469 {
18470   unformat_input_t *input = vam->input;
18471   vl_api_one_set_transport_protocol_t *mp;
18472   u8 is_set = 0;
18473   u32 protocol = 0;
18474   int ret;
18475
18476   /* Parse args required to build the message */
18477   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18478     {
18479       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18480         is_set = 1;
18481       else
18482         {
18483           clib_warning ("parse error '%U'", format_unformat_error, input);
18484           return -99;
18485         }
18486     }
18487
18488   if (!is_set)
18489     {
18490       errmsg ("Transport protocol missing!");
18491       return -99;
18492     }
18493
18494   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18495   mp->protocol = (u8) protocol;
18496
18497   /* send it... */
18498   S (mp);
18499
18500   /* Wait for a reply... */
18501   W (ret);
18502   return ret;
18503 }
18504
18505 static int
18506 api_one_get_transport_protocol (vat_main_t * vam)
18507 {
18508   vl_api_one_get_transport_protocol_t *mp;
18509   int ret;
18510
18511   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18512
18513   /* send it... */
18514   S (mp);
18515
18516   /* Wait for a reply... */
18517   W (ret);
18518   return ret;
18519 }
18520
18521 static int
18522 api_one_map_register_set_ttl (vat_main_t * vam)
18523 {
18524   unformat_input_t *input = vam->input;
18525   vl_api_one_map_register_set_ttl_t *mp;
18526   u32 ttl = 0;
18527   u8 is_set = 0;
18528   int ret;
18529
18530   /* Parse args required to build the message */
18531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18532     {
18533       if (unformat (input, "%u", &ttl))
18534         is_set = 1;
18535       else
18536         {
18537           clib_warning ("parse error '%U'", format_unformat_error, input);
18538           return -99;
18539         }
18540     }
18541
18542   if (!is_set)
18543     {
18544       errmsg ("TTL value missing!");
18545       return -99;
18546     }
18547
18548   M (ONE_MAP_REGISTER_SET_TTL, mp);
18549   mp->ttl = clib_host_to_net_u32 (ttl);
18550
18551   /* send it... */
18552   S (mp);
18553
18554   /* Wait for a reply... */
18555   W (ret);
18556   return ret;
18557 }
18558
18559 static int
18560 api_show_one_map_register_ttl (vat_main_t * vam)
18561 {
18562   vl_api_show_one_map_register_ttl_t *mp;
18563   int ret;
18564
18565   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18566
18567   /* send it... */
18568   S (mp);
18569
18570   /* Wait for a reply... */
18571   W (ret);
18572   return ret;
18573 }
18574
18575 /**
18576  * Add/del map request itr rlocs from ONE control plane and updates
18577  *
18578  * @param vam vpp API test context
18579  * @return return code
18580  */
18581 static int
18582 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18583 {
18584   unformat_input_t *input = vam->input;
18585   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18586   u8 *locator_set_name = 0;
18587   u8 locator_set_name_set = 0;
18588   u8 is_add = 1;
18589   int ret;
18590
18591   /* Parse args required to build the message */
18592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18593     {
18594       if (unformat (input, "del"))
18595         {
18596           is_add = 0;
18597         }
18598       else if (unformat (input, "%_%v%_", &locator_set_name))
18599         {
18600           locator_set_name_set = 1;
18601         }
18602       else
18603         {
18604           clib_warning ("parse error '%U'", format_unformat_error, input);
18605           return -99;
18606         }
18607     }
18608
18609   if (is_add && !locator_set_name_set)
18610     {
18611       errmsg ("itr-rloc is not set!");
18612       return -99;
18613     }
18614
18615   if (is_add && vec_len (locator_set_name) > 64)
18616     {
18617       errmsg ("itr-rloc locator-set name too long");
18618       vec_free (locator_set_name);
18619       return -99;
18620     }
18621
18622   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18623   mp->is_add = is_add;
18624   if (is_add)
18625     {
18626       clib_memcpy (mp->locator_set_name, locator_set_name,
18627                    vec_len (locator_set_name));
18628     }
18629   else
18630     {
18631       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18632     }
18633   vec_free (locator_set_name);
18634
18635   /* send it... */
18636   S (mp);
18637
18638   /* Wait for a reply... */
18639   W (ret);
18640   return ret;
18641 }
18642
18643 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18644
18645 static int
18646 api_one_locator_dump (vat_main_t * vam)
18647 {
18648   unformat_input_t *input = vam->input;
18649   vl_api_one_locator_dump_t *mp;
18650   vl_api_control_ping_t *mp_ping;
18651   u8 is_index_set = 0, is_name_set = 0;
18652   u8 *ls_name = 0;
18653   u32 ls_index = ~0;
18654   int ret;
18655
18656   /* Parse args required to build the message */
18657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18658     {
18659       if (unformat (input, "ls_name %_%v%_", &ls_name))
18660         {
18661           is_name_set = 1;
18662         }
18663       else if (unformat (input, "ls_index %d", &ls_index))
18664         {
18665           is_index_set = 1;
18666         }
18667       else
18668         {
18669           errmsg ("parse error '%U'", format_unformat_error, input);
18670           return -99;
18671         }
18672     }
18673
18674   if (!is_index_set && !is_name_set)
18675     {
18676       errmsg ("error: expected one of index or name!");
18677       return -99;
18678     }
18679
18680   if (is_index_set && is_name_set)
18681     {
18682       errmsg ("error: only one param expected!");
18683       return -99;
18684     }
18685
18686   if (vec_len (ls_name) > 62)
18687     {
18688       errmsg ("error: locator set name too long!");
18689       return -99;
18690     }
18691
18692   if (!vam->json_output)
18693     {
18694       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18695     }
18696
18697   M (ONE_LOCATOR_DUMP, mp);
18698   mp->is_index_set = is_index_set;
18699
18700   if (is_index_set)
18701     mp->ls_index = clib_host_to_net_u32 (ls_index);
18702   else
18703     {
18704       vec_add1 (ls_name, 0);
18705       strncpy ((char *) mp->ls_name, (char *) ls_name,
18706                sizeof (mp->ls_name) - 1);
18707     }
18708
18709   /* send it... */
18710   S (mp);
18711
18712   /* Use a control ping for synchronization */
18713   MPING (CONTROL_PING, mp_ping);
18714   S (mp_ping);
18715
18716   /* Wait for a reply... */
18717   W (ret);
18718   return ret;
18719 }
18720
18721 #define api_lisp_locator_dump api_one_locator_dump
18722
18723 static int
18724 api_one_locator_set_dump (vat_main_t * vam)
18725 {
18726   vl_api_one_locator_set_dump_t *mp;
18727   vl_api_control_ping_t *mp_ping;
18728   unformat_input_t *input = vam->input;
18729   u8 filter = 0;
18730   int ret;
18731
18732   /* Parse args required to build the message */
18733   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18734     {
18735       if (unformat (input, "local"))
18736         {
18737           filter = 1;
18738         }
18739       else if (unformat (input, "remote"))
18740         {
18741           filter = 2;
18742         }
18743       else
18744         {
18745           errmsg ("parse error '%U'", format_unformat_error, input);
18746           return -99;
18747         }
18748     }
18749
18750   if (!vam->json_output)
18751     {
18752       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18753     }
18754
18755   M (ONE_LOCATOR_SET_DUMP, mp);
18756
18757   mp->filter = filter;
18758
18759   /* send it... */
18760   S (mp);
18761
18762   /* Use a control ping for synchronization */
18763   MPING (CONTROL_PING, mp_ping);
18764   S (mp_ping);
18765
18766   /* Wait for a reply... */
18767   W (ret);
18768   return ret;
18769 }
18770
18771 #define api_lisp_locator_set_dump api_one_locator_set_dump
18772
18773 static int
18774 api_one_eid_table_map_dump (vat_main_t * vam)
18775 {
18776   u8 is_l2 = 0;
18777   u8 mode_set = 0;
18778   unformat_input_t *input = vam->input;
18779   vl_api_one_eid_table_map_dump_t *mp;
18780   vl_api_control_ping_t *mp_ping;
18781   int ret;
18782
18783   /* Parse args required to build the message */
18784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18785     {
18786       if (unformat (input, "l2"))
18787         {
18788           is_l2 = 1;
18789           mode_set = 1;
18790         }
18791       else if (unformat (input, "l3"))
18792         {
18793           is_l2 = 0;
18794           mode_set = 1;
18795         }
18796       else
18797         {
18798           errmsg ("parse error '%U'", format_unformat_error, input);
18799           return -99;
18800         }
18801     }
18802
18803   if (!mode_set)
18804     {
18805       errmsg ("expected one of 'l2' or 'l3' parameter!");
18806       return -99;
18807     }
18808
18809   if (!vam->json_output)
18810     {
18811       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18812     }
18813
18814   M (ONE_EID_TABLE_MAP_DUMP, mp);
18815   mp->is_l2 = is_l2;
18816
18817   /* send it... */
18818   S (mp);
18819
18820   /* Use a control ping for synchronization */
18821   MPING (CONTROL_PING, mp_ping);
18822   S (mp_ping);
18823
18824   /* Wait for a reply... */
18825   W (ret);
18826   return ret;
18827 }
18828
18829 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18830
18831 static int
18832 api_one_eid_table_vni_dump (vat_main_t * vam)
18833 {
18834   vl_api_one_eid_table_vni_dump_t *mp;
18835   vl_api_control_ping_t *mp_ping;
18836   int ret;
18837
18838   if (!vam->json_output)
18839     {
18840       print (vam->ofp, "VNI");
18841     }
18842
18843   M (ONE_EID_TABLE_VNI_DUMP, mp);
18844
18845   /* send it... */
18846   S (mp);
18847
18848   /* Use a control ping for synchronization */
18849   MPING (CONTROL_PING, mp_ping);
18850   S (mp_ping);
18851
18852   /* Wait for a reply... */
18853   W (ret);
18854   return ret;
18855 }
18856
18857 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18858
18859 static int
18860 api_one_eid_table_dump (vat_main_t * vam)
18861 {
18862   unformat_input_t *i = vam->input;
18863   vl_api_one_eid_table_dump_t *mp;
18864   vl_api_control_ping_t *mp_ping;
18865   struct in_addr ip4;
18866   struct in6_addr ip6;
18867   u8 mac[6];
18868   u8 eid_type = ~0, eid_set = 0;
18869   u32 prefix_length = ~0, t, vni = 0;
18870   u8 filter = 0;
18871   int ret;
18872   lisp_nsh_api_t nsh;
18873
18874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18875     {
18876       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18877         {
18878           eid_set = 1;
18879           eid_type = 0;
18880           prefix_length = t;
18881         }
18882       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18883         {
18884           eid_set = 1;
18885           eid_type = 1;
18886           prefix_length = t;
18887         }
18888       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18889         {
18890           eid_set = 1;
18891           eid_type = 2;
18892         }
18893       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18894         {
18895           eid_set = 1;
18896           eid_type = 3;
18897         }
18898       else if (unformat (i, "vni %d", &t))
18899         {
18900           vni = t;
18901         }
18902       else if (unformat (i, "local"))
18903         {
18904           filter = 1;
18905         }
18906       else if (unformat (i, "remote"))
18907         {
18908           filter = 2;
18909         }
18910       else
18911         {
18912           errmsg ("parse error '%U'", format_unformat_error, i);
18913           return -99;
18914         }
18915     }
18916
18917   if (!vam->json_output)
18918     {
18919       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18920              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18921     }
18922
18923   M (ONE_EID_TABLE_DUMP, mp);
18924
18925   mp->filter = filter;
18926   if (eid_set)
18927     {
18928       mp->eid_set = 1;
18929       mp->vni = htonl (vni);
18930       mp->eid_type = eid_type;
18931       switch (eid_type)
18932         {
18933         case 0:
18934           mp->prefix_length = prefix_length;
18935           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18936           break;
18937         case 1:
18938           mp->prefix_length = prefix_length;
18939           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18940           break;
18941         case 2:
18942           clib_memcpy (mp->eid, mac, sizeof (mac));
18943           break;
18944         case 3:
18945           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18946           break;
18947         default:
18948           errmsg ("unknown EID type %d!", eid_type);
18949           return -99;
18950         }
18951     }
18952
18953   /* send it... */
18954   S (mp);
18955
18956   /* Use a control ping for synchronization */
18957   MPING (CONTROL_PING, mp_ping);
18958   S (mp_ping);
18959
18960   /* Wait for a reply... */
18961   W (ret);
18962   return ret;
18963 }
18964
18965 #define api_lisp_eid_table_dump api_one_eid_table_dump
18966
18967 static int
18968 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18969 {
18970   unformat_input_t *i = vam->input;
18971   vl_api_gpe_fwd_entries_get_t *mp;
18972   u8 vni_set = 0;
18973   u32 vni = ~0;
18974   int ret;
18975
18976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18977     {
18978       if (unformat (i, "vni %d", &vni))
18979         {
18980           vni_set = 1;
18981         }
18982       else
18983         {
18984           errmsg ("parse error '%U'", format_unformat_error, i);
18985           return -99;
18986         }
18987     }
18988
18989   if (!vni_set)
18990     {
18991       errmsg ("vni not set!");
18992       return -99;
18993     }
18994
18995   if (!vam->json_output)
18996     {
18997       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18998              "leid", "reid");
18999     }
19000
19001   M (GPE_FWD_ENTRIES_GET, mp);
19002   mp->vni = clib_host_to_net_u32 (vni);
19003
19004   /* send it... */
19005   S (mp);
19006
19007   /* Wait for a reply... */
19008   W (ret);
19009   return ret;
19010 }
19011
19012 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19013 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19014 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19015 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19016 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19017 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19018 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19019 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19020
19021 static int
19022 api_one_adjacencies_get (vat_main_t * vam)
19023 {
19024   unformat_input_t *i = vam->input;
19025   vl_api_one_adjacencies_get_t *mp;
19026   u8 vni_set = 0;
19027   u32 vni = ~0;
19028   int ret;
19029
19030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19031     {
19032       if (unformat (i, "vni %d", &vni))
19033         {
19034           vni_set = 1;
19035         }
19036       else
19037         {
19038           errmsg ("parse error '%U'", format_unformat_error, i);
19039           return -99;
19040         }
19041     }
19042
19043   if (!vni_set)
19044     {
19045       errmsg ("vni not set!");
19046       return -99;
19047     }
19048
19049   if (!vam->json_output)
19050     {
19051       print (vam->ofp, "%s %40s", "leid", "reid");
19052     }
19053
19054   M (ONE_ADJACENCIES_GET, mp);
19055   mp->vni = clib_host_to_net_u32 (vni);
19056
19057   /* send it... */
19058   S (mp);
19059
19060   /* Wait for a reply... */
19061   W (ret);
19062   return ret;
19063 }
19064
19065 #define api_lisp_adjacencies_get api_one_adjacencies_get
19066
19067 static int
19068 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19069 {
19070   unformat_input_t *i = vam->input;
19071   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19072   int ret;
19073   u8 ip_family_set = 0, is_ip4 = 1;
19074
19075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19076     {
19077       if (unformat (i, "ip4"))
19078         {
19079           ip_family_set = 1;
19080           is_ip4 = 1;
19081         }
19082       else if (unformat (i, "ip6"))
19083         {
19084           ip_family_set = 1;
19085           is_ip4 = 0;
19086         }
19087       else
19088         {
19089           errmsg ("parse error '%U'", format_unformat_error, i);
19090           return -99;
19091         }
19092     }
19093
19094   if (!ip_family_set)
19095     {
19096       errmsg ("ip family not set!");
19097       return -99;
19098     }
19099
19100   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19101   mp->is_ip4 = is_ip4;
19102
19103   /* send it... */
19104   S (mp);
19105
19106   /* Wait for a reply... */
19107   W (ret);
19108   return ret;
19109 }
19110
19111 static int
19112 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19113 {
19114   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19115   int ret;
19116
19117   if (!vam->json_output)
19118     {
19119       print (vam->ofp, "VNIs");
19120     }
19121
19122   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19123
19124   /* send it... */
19125   S (mp);
19126
19127   /* Wait for a reply... */
19128   W (ret);
19129   return ret;
19130 }
19131
19132 static int
19133 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19134 {
19135   unformat_input_t *i = vam->input;
19136   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19137   int ret = 0;
19138   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19139   struct in_addr ip4;
19140   struct in6_addr ip6;
19141   u32 table_id = 0, nh_sw_if_index = ~0;
19142
19143   clib_memset (&ip4, 0, sizeof (ip4));
19144   clib_memset (&ip6, 0, sizeof (ip6));
19145
19146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19147     {
19148       if (unformat (i, "del"))
19149         is_add = 0;
19150       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19151                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19152         {
19153           ip_set = 1;
19154           is_ip4 = 1;
19155         }
19156       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19157                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19158         {
19159           ip_set = 1;
19160           is_ip4 = 0;
19161         }
19162       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19163         {
19164           ip_set = 1;
19165           is_ip4 = 1;
19166           nh_sw_if_index = ~0;
19167         }
19168       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19169         {
19170           ip_set = 1;
19171           is_ip4 = 0;
19172           nh_sw_if_index = ~0;
19173         }
19174       else if (unformat (i, "table %d", &table_id))
19175         ;
19176       else
19177         {
19178           errmsg ("parse error '%U'", format_unformat_error, i);
19179           return -99;
19180         }
19181     }
19182
19183   if (!ip_set)
19184     {
19185       errmsg ("nh addr not set!");
19186       return -99;
19187     }
19188
19189   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19190   mp->is_add = is_add;
19191   mp->table_id = clib_host_to_net_u32 (table_id);
19192   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19193   mp->is_ip4 = is_ip4;
19194   if (is_ip4)
19195     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19196   else
19197     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19198
19199   /* send it... */
19200   S (mp);
19201
19202   /* Wait for a reply... */
19203   W (ret);
19204   return ret;
19205 }
19206
19207 static int
19208 api_one_map_server_dump (vat_main_t * vam)
19209 {
19210   vl_api_one_map_server_dump_t *mp;
19211   vl_api_control_ping_t *mp_ping;
19212   int ret;
19213
19214   if (!vam->json_output)
19215     {
19216       print (vam->ofp, "%=20s", "Map server");
19217     }
19218
19219   M (ONE_MAP_SERVER_DUMP, mp);
19220   /* send it... */
19221   S (mp);
19222
19223   /* Use a control ping for synchronization */
19224   MPING (CONTROL_PING, mp_ping);
19225   S (mp_ping);
19226
19227   /* Wait for a reply... */
19228   W (ret);
19229   return ret;
19230 }
19231
19232 #define api_lisp_map_server_dump api_one_map_server_dump
19233
19234 static int
19235 api_one_map_resolver_dump (vat_main_t * vam)
19236 {
19237   vl_api_one_map_resolver_dump_t *mp;
19238   vl_api_control_ping_t *mp_ping;
19239   int ret;
19240
19241   if (!vam->json_output)
19242     {
19243       print (vam->ofp, "%=20s", "Map resolver");
19244     }
19245
19246   M (ONE_MAP_RESOLVER_DUMP, mp);
19247   /* send it... */
19248   S (mp);
19249
19250   /* Use a control ping for synchronization */
19251   MPING (CONTROL_PING, mp_ping);
19252   S (mp_ping);
19253
19254   /* Wait for a reply... */
19255   W (ret);
19256   return ret;
19257 }
19258
19259 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19260
19261 static int
19262 api_one_stats_flush (vat_main_t * vam)
19263 {
19264   vl_api_one_stats_flush_t *mp;
19265   int ret = 0;
19266
19267   M (ONE_STATS_FLUSH, mp);
19268   S (mp);
19269   W (ret);
19270   return ret;
19271 }
19272
19273 static int
19274 api_one_stats_dump (vat_main_t * vam)
19275 {
19276   vl_api_one_stats_dump_t *mp;
19277   vl_api_control_ping_t *mp_ping;
19278   int ret;
19279
19280   M (ONE_STATS_DUMP, mp);
19281   /* send it... */
19282   S (mp);
19283
19284   /* Use a control ping for synchronization */
19285   MPING (CONTROL_PING, mp_ping);
19286   S (mp_ping);
19287
19288   /* Wait for a reply... */
19289   W (ret);
19290   return ret;
19291 }
19292
19293 static int
19294 api_show_one_status (vat_main_t * vam)
19295 {
19296   vl_api_show_one_status_t *mp;
19297   int ret;
19298
19299   if (!vam->json_output)
19300     {
19301       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19302     }
19303
19304   M (SHOW_ONE_STATUS, mp);
19305   /* send it... */
19306   S (mp);
19307   /* Wait for a reply... */
19308   W (ret);
19309   return ret;
19310 }
19311
19312 #define api_show_lisp_status api_show_one_status
19313
19314 static int
19315 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19316 {
19317   vl_api_gpe_fwd_entry_path_dump_t *mp;
19318   vl_api_control_ping_t *mp_ping;
19319   unformat_input_t *i = vam->input;
19320   u32 fwd_entry_index = ~0;
19321   int ret;
19322
19323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19324     {
19325       if (unformat (i, "index %d", &fwd_entry_index))
19326         ;
19327       else
19328         break;
19329     }
19330
19331   if (~0 == fwd_entry_index)
19332     {
19333       errmsg ("no index specified!");
19334       return -99;
19335     }
19336
19337   if (!vam->json_output)
19338     {
19339       print (vam->ofp, "first line");
19340     }
19341
19342   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19343
19344   /* send it... */
19345   S (mp);
19346   /* Use a control ping for synchronization */
19347   MPING (CONTROL_PING, mp_ping);
19348   S (mp_ping);
19349
19350   /* Wait for a reply... */
19351   W (ret);
19352   return ret;
19353 }
19354
19355 static int
19356 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19357 {
19358   vl_api_one_get_map_request_itr_rlocs_t *mp;
19359   int ret;
19360
19361   if (!vam->json_output)
19362     {
19363       print (vam->ofp, "%=20s", "itr-rlocs:");
19364     }
19365
19366   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19367   /* send it... */
19368   S (mp);
19369   /* Wait for a reply... */
19370   W (ret);
19371   return ret;
19372 }
19373
19374 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19375
19376 static int
19377 api_af_packet_create (vat_main_t * vam)
19378 {
19379   unformat_input_t *i = vam->input;
19380   vl_api_af_packet_create_t *mp;
19381   u8 *host_if_name = 0;
19382   u8 hw_addr[6];
19383   u8 random_hw_addr = 1;
19384   int ret;
19385
19386   clib_memset (hw_addr, 0, sizeof (hw_addr));
19387
19388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19389     {
19390       if (unformat (i, "name %s", &host_if_name))
19391         vec_add1 (host_if_name, 0);
19392       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19393         random_hw_addr = 0;
19394       else
19395         break;
19396     }
19397
19398   if (!vec_len (host_if_name))
19399     {
19400       errmsg ("host-interface name must be specified");
19401       return -99;
19402     }
19403
19404   if (vec_len (host_if_name) > 64)
19405     {
19406       errmsg ("host-interface name too long");
19407       return -99;
19408     }
19409
19410   M (AF_PACKET_CREATE, mp);
19411
19412   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19413   clib_memcpy (mp->hw_addr, hw_addr, 6);
19414   mp->use_random_hw_addr = random_hw_addr;
19415   vec_free (host_if_name);
19416
19417   S (mp);
19418
19419   /* *INDENT-OFF* */
19420   W2 (ret,
19421       ({
19422         if (ret == 0)
19423           fprintf (vam->ofp ? vam->ofp : stderr,
19424                    " new sw_if_index = %d\n", vam->sw_if_index);
19425       }));
19426   /* *INDENT-ON* */
19427   return ret;
19428 }
19429
19430 static int
19431 api_af_packet_delete (vat_main_t * vam)
19432 {
19433   unformat_input_t *i = vam->input;
19434   vl_api_af_packet_delete_t *mp;
19435   u8 *host_if_name = 0;
19436   int ret;
19437
19438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19439     {
19440       if (unformat (i, "name %s", &host_if_name))
19441         vec_add1 (host_if_name, 0);
19442       else
19443         break;
19444     }
19445
19446   if (!vec_len (host_if_name))
19447     {
19448       errmsg ("host-interface name must be specified");
19449       return -99;
19450     }
19451
19452   if (vec_len (host_if_name) > 64)
19453     {
19454       errmsg ("host-interface name too long");
19455       return -99;
19456     }
19457
19458   M (AF_PACKET_DELETE, mp);
19459
19460   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19461   vec_free (host_if_name);
19462
19463   S (mp);
19464   W (ret);
19465   return ret;
19466 }
19467
19468 static void vl_api_af_packet_details_t_handler
19469   (vl_api_af_packet_details_t * mp)
19470 {
19471   vat_main_t *vam = &vat_main;
19472
19473   print (vam->ofp, "%-16s %d",
19474          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19475 }
19476
19477 static void vl_api_af_packet_details_t_handler_json
19478   (vl_api_af_packet_details_t * mp)
19479 {
19480   vat_main_t *vam = &vat_main;
19481   vat_json_node_t *node = NULL;
19482
19483   if (VAT_JSON_ARRAY != vam->json_tree.type)
19484     {
19485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19486       vat_json_init_array (&vam->json_tree);
19487     }
19488   node = vat_json_array_add (&vam->json_tree);
19489
19490   vat_json_init_object (node);
19491   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19492   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19493 }
19494
19495 static int
19496 api_af_packet_dump (vat_main_t * vam)
19497 {
19498   vl_api_af_packet_dump_t *mp;
19499   vl_api_control_ping_t *mp_ping;
19500   int ret;
19501
19502   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19503   /* Get list of tap interfaces */
19504   M (AF_PACKET_DUMP, mp);
19505   S (mp);
19506
19507   /* Use a control ping for synchronization */
19508   MPING (CONTROL_PING, mp_ping);
19509   S (mp_ping);
19510
19511   W (ret);
19512   return ret;
19513 }
19514
19515 static int
19516 api_policer_add_del (vat_main_t * vam)
19517 {
19518   unformat_input_t *i = vam->input;
19519   vl_api_policer_add_del_t *mp;
19520   u8 is_add = 1;
19521   u8 *name = 0;
19522   u32 cir = 0;
19523   u32 eir = 0;
19524   u64 cb = 0;
19525   u64 eb = 0;
19526   u8 rate_type = 0;
19527   u8 round_type = 0;
19528   u8 type = 0;
19529   u8 color_aware = 0;
19530   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19531   int ret;
19532
19533   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19534   conform_action.dscp = 0;
19535   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19536   exceed_action.dscp = 0;
19537   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19538   violate_action.dscp = 0;
19539
19540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19541     {
19542       if (unformat (i, "del"))
19543         is_add = 0;
19544       else if (unformat (i, "name %s", &name))
19545         vec_add1 (name, 0);
19546       else if (unformat (i, "cir %u", &cir))
19547         ;
19548       else if (unformat (i, "eir %u", &eir))
19549         ;
19550       else if (unformat (i, "cb %u", &cb))
19551         ;
19552       else if (unformat (i, "eb %u", &eb))
19553         ;
19554       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19555                          &rate_type))
19556         ;
19557       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19558                          &round_type))
19559         ;
19560       else if (unformat (i, "type %U", unformat_policer_type, &type))
19561         ;
19562       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19563                          &conform_action))
19564         ;
19565       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19566                          &exceed_action))
19567         ;
19568       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19569                          &violate_action))
19570         ;
19571       else if (unformat (i, "color-aware"))
19572         color_aware = 1;
19573       else
19574         break;
19575     }
19576
19577   if (!vec_len (name))
19578     {
19579       errmsg ("policer name must be specified");
19580       return -99;
19581     }
19582
19583   if (vec_len (name) > 64)
19584     {
19585       errmsg ("policer name too long");
19586       return -99;
19587     }
19588
19589   M (POLICER_ADD_DEL, mp);
19590
19591   clib_memcpy (mp->name, name, vec_len (name));
19592   vec_free (name);
19593   mp->is_add = is_add;
19594   mp->cir = ntohl (cir);
19595   mp->eir = ntohl (eir);
19596   mp->cb = clib_net_to_host_u64 (cb);
19597   mp->eb = clib_net_to_host_u64 (eb);
19598   mp->rate_type = rate_type;
19599   mp->round_type = round_type;
19600   mp->type = type;
19601   mp->conform_action_type = conform_action.action_type;
19602   mp->conform_dscp = conform_action.dscp;
19603   mp->exceed_action_type = exceed_action.action_type;
19604   mp->exceed_dscp = exceed_action.dscp;
19605   mp->violate_action_type = violate_action.action_type;
19606   mp->violate_dscp = violate_action.dscp;
19607   mp->color_aware = color_aware;
19608
19609   S (mp);
19610   W (ret);
19611   return ret;
19612 }
19613
19614 static int
19615 api_policer_dump (vat_main_t * vam)
19616 {
19617   unformat_input_t *i = vam->input;
19618   vl_api_policer_dump_t *mp;
19619   vl_api_control_ping_t *mp_ping;
19620   u8 *match_name = 0;
19621   u8 match_name_valid = 0;
19622   int ret;
19623
19624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19625     {
19626       if (unformat (i, "name %s", &match_name))
19627         {
19628           vec_add1 (match_name, 0);
19629           match_name_valid = 1;
19630         }
19631       else
19632         break;
19633     }
19634
19635   M (POLICER_DUMP, mp);
19636   mp->match_name_valid = match_name_valid;
19637   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19638   vec_free (match_name);
19639   /* send it... */
19640   S (mp);
19641
19642   /* Use a control ping for synchronization */
19643   MPING (CONTROL_PING, mp_ping);
19644   S (mp_ping);
19645
19646   /* Wait for a reply... */
19647   W (ret);
19648   return ret;
19649 }
19650
19651 static int
19652 api_policer_classify_set_interface (vat_main_t * vam)
19653 {
19654   unformat_input_t *i = vam->input;
19655   vl_api_policer_classify_set_interface_t *mp;
19656   u32 sw_if_index;
19657   int sw_if_index_set;
19658   u32 ip4_table_index = ~0;
19659   u32 ip6_table_index = ~0;
19660   u32 l2_table_index = ~0;
19661   u8 is_add = 1;
19662   int ret;
19663
19664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19665     {
19666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19667         sw_if_index_set = 1;
19668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19669         sw_if_index_set = 1;
19670       else if (unformat (i, "del"))
19671         is_add = 0;
19672       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19673         ;
19674       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19675         ;
19676       else if (unformat (i, "l2-table %d", &l2_table_index))
19677         ;
19678       else
19679         {
19680           clib_warning ("parse error '%U'", format_unformat_error, i);
19681           return -99;
19682         }
19683     }
19684
19685   if (sw_if_index_set == 0)
19686     {
19687       errmsg ("missing interface name or sw_if_index");
19688       return -99;
19689     }
19690
19691   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19692
19693   mp->sw_if_index = ntohl (sw_if_index);
19694   mp->ip4_table_index = ntohl (ip4_table_index);
19695   mp->ip6_table_index = ntohl (ip6_table_index);
19696   mp->l2_table_index = ntohl (l2_table_index);
19697   mp->is_add = is_add;
19698
19699   S (mp);
19700   W (ret);
19701   return ret;
19702 }
19703
19704 static int
19705 api_policer_classify_dump (vat_main_t * vam)
19706 {
19707   unformat_input_t *i = vam->input;
19708   vl_api_policer_classify_dump_t *mp;
19709   vl_api_control_ping_t *mp_ping;
19710   u8 type = POLICER_CLASSIFY_N_TABLES;
19711   int ret;
19712
19713   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19714     ;
19715   else
19716     {
19717       errmsg ("classify table type must be specified");
19718       return -99;
19719     }
19720
19721   if (!vam->json_output)
19722     {
19723       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19724     }
19725
19726   M (POLICER_CLASSIFY_DUMP, mp);
19727   mp->type = type;
19728   /* send it... */
19729   S (mp);
19730
19731   /* Use a control ping for synchronization */
19732   MPING (CONTROL_PING, mp_ping);
19733   S (mp_ping);
19734
19735   /* Wait for a reply... */
19736   W (ret);
19737   return ret;
19738 }
19739
19740 static int
19741 api_netmap_create (vat_main_t * vam)
19742 {
19743   unformat_input_t *i = vam->input;
19744   vl_api_netmap_create_t *mp;
19745   u8 *if_name = 0;
19746   u8 hw_addr[6];
19747   u8 random_hw_addr = 1;
19748   u8 is_pipe = 0;
19749   u8 is_master = 0;
19750   int ret;
19751
19752   clib_memset (hw_addr, 0, sizeof (hw_addr));
19753
19754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19755     {
19756       if (unformat (i, "name %s", &if_name))
19757         vec_add1 (if_name, 0);
19758       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19759         random_hw_addr = 0;
19760       else if (unformat (i, "pipe"))
19761         is_pipe = 1;
19762       else if (unformat (i, "master"))
19763         is_master = 1;
19764       else if (unformat (i, "slave"))
19765         is_master = 0;
19766       else
19767         break;
19768     }
19769
19770   if (!vec_len (if_name))
19771     {
19772       errmsg ("interface name must be specified");
19773       return -99;
19774     }
19775
19776   if (vec_len (if_name) > 64)
19777     {
19778       errmsg ("interface name too long");
19779       return -99;
19780     }
19781
19782   M (NETMAP_CREATE, mp);
19783
19784   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19785   clib_memcpy (mp->hw_addr, hw_addr, 6);
19786   mp->use_random_hw_addr = random_hw_addr;
19787   mp->is_pipe = is_pipe;
19788   mp->is_master = is_master;
19789   vec_free (if_name);
19790
19791   S (mp);
19792   W (ret);
19793   return ret;
19794 }
19795
19796 static int
19797 api_netmap_delete (vat_main_t * vam)
19798 {
19799   unformat_input_t *i = vam->input;
19800   vl_api_netmap_delete_t *mp;
19801   u8 *if_name = 0;
19802   int ret;
19803
19804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19805     {
19806       if (unformat (i, "name %s", &if_name))
19807         vec_add1 (if_name, 0);
19808       else
19809         break;
19810     }
19811
19812   if (!vec_len (if_name))
19813     {
19814       errmsg ("interface name must be specified");
19815       return -99;
19816     }
19817
19818   if (vec_len (if_name) > 64)
19819     {
19820       errmsg ("interface name too long");
19821       return -99;
19822     }
19823
19824   M (NETMAP_DELETE, mp);
19825
19826   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19827   vec_free (if_name);
19828
19829   S (mp);
19830   W (ret);
19831   return ret;
19832 }
19833
19834 static void
19835 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19836 {
19837   if (fp->afi == IP46_TYPE_IP6)
19838     print (vam->ofp,
19839            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19840            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19841            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19842            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19843            format_ip6_address, fp->next_hop);
19844   else if (fp->afi == IP46_TYPE_IP4)
19845     print (vam->ofp,
19846            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19847            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19848            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19849            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19850            format_ip4_address, fp->next_hop);
19851 }
19852
19853 static void
19854 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19855                                  vl_api_fib_path_t * fp)
19856 {
19857   struct in_addr ip4;
19858   struct in6_addr ip6;
19859
19860   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19861   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19862   vat_json_object_add_uint (node, "is_local", fp->is_local);
19863   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19864   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19865   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19866   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19867   if (fp->afi == IP46_TYPE_IP4)
19868     {
19869       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19870       vat_json_object_add_ip4 (node, "next_hop", ip4);
19871     }
19872   else if (fp->afi == IP46_TYPE_IP6)
19873     {
19874       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19875       vat_json_object_add_ip6 (node, "next_hop", ip6);
19876     }
19877 }
19878
19879 static void
19880 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19881 {
19882   vat_main_t *vam = &vat_main;
19883   int count = ntohl (mp->mt_count);
19884   vl_api_fib_path_t *fp;
19885   i32 i;
19886
19887   print (vam->ofp, "[%d]: sw_if_index %d via:",
19888          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19889   fp = mp->mt_paths;
19890   for (i = 0; i < count; i++)
19891     {
19892       vl_api_mpls_fib_path_print (vam, fp);
19893       fp++;
19894     }
19895
19896   print (vam->ofp, "");
19897 }
19898
19899 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19900 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19901
19902 static void
19903 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19904 {
19905   vat_main_t *vam = &vat_main;
19906   vat_json_node_t *node = NULL;
19907   int count = ntohl (mp->mt_count);
19908   vl_api_fib_path_t *fp;
19909   i32 i;
19910
19911   if (VAT_JSON_ARRAY != vam->json_tree.type)
19912     {
19913       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19914       vat_json_init_array (&vam->json_tree);
19915     }
19916   node = vat_json_array_add (&vam->json_tree);
19917
19918   vat_json_init_object (node);
19919   vat_json_object_add_uint (node, "tunnel_index",
19920                             ntohl (mp->mt_tunnel_index));
19921   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19922
19923   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19924
19925   fp = mp->mt_paths;
19926   for (i = 0; i < count; i++)
19927     {
19928       vl_api_mpls_fib_path_json_print (node, fp);
19929       fp++;
19930     }
19931 }
19932
19933 static int
19934 api_mpls_tunnel_dump (vat_main_t * vam)
19935 {
19936   vl_api_mpls_tunnel_dump_t *mp;
19937   vl_api_control_ping_t *mp_ping;
19938   u32 sw_if_index = ~0;
19939   int ret;
19940
19941   /* Parse args required to build the message */
19942   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19943     {
19944       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19945         ;
19946     }
19947
19948   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19949
19950   M (MPLS_TUNNEL_DUMP, mp);
19951   mp->sw_if_index = htonl (sw_if_index);
19952   S (mp);
19953
19954   /* Use a control ping for synchronization */
19955   MPING (CONTROL_PING, mp_ping);
19956   S (mp_ping);
19957
19958   W (ret);
19959   return ret;
19960 }
19961
19962 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19963 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19964
19965
19966 static void
19967 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19968 {
19969   vat_main_t *vam = &vat_main;
19970   int count = ntohl (mp->count);
19971   vl_api_fib_path_t *fp;
19972   int i;
19973
19974   print (vam->ofp,
19975          "table-id %d, label %u, ess_bit %u",
19976          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19977   fp = mp->path;
19978   for (i = 0; i < count; i++)
19979     {
19980       vl_api_mpls_fib_path_print (vam, fp);
19981       fp++;
19982     }
19983 }
19984
19985 static void vl_api_mpls_fib_details_t_handler_json
19986   (vl_api_mpls_fib_details_t * mp)
19987 {
19988   vat_main_t *vam = &vat_main;
19989   int count = ntohl (mp->count);
19990   vat_json_node_t *node = NULL;
19991   vl_api_fib_path_t *fp;
19992   int i;
19993
19994   if (VAT_JSON_ARRAY != vam->json_tree.type)
19995     {
19996       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19997       vat_json_init_array (&vam->json_tree);
19998     }
19999   node = vat_json_array_add (&vam->json_tree);
20000
20001   vat_json_init_object (node);
20002   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20003   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20004   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20005   vat_json_object_add_uint (node, "path_count", count);
20006   fp = mp->path;
20007   for (i = 0; i < count; i++)
20008     {
20009       vl_api_mpls_fib_path_json_print (node, fp);
20010       fp++;
20011     }
20012 }
20013
20014 static int
20015 api_mpls_fib_dump (vat_main_t * vam)
20016 {
20017   vl_api_mpls_fib_dump_t *mp;
20018   vl_api_control_ping_t *mp_ping;
20019   int ret;
20020
20021   M (MPLS_FIB_DUMP, mp);
20022   S (mp);
20023
20024   /* Use a control ping for synchronization */
20025   MPING (CONTROL_PING, mp_ping);
20026   S (mp_ping);
20027
20028   W (ret);
20029   return ret;
20030 }
20031
20032 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20033 #define vl_api_ip_fib_details_t_print vl_noop_handler
20034
20035 static void
20036 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20037 {
20038   vat_main_t *vam = &vat_main;
20039   int count = ntohl (mp->count);
20040   vl_api_fib_path_t *fp;
20041   int i;
20042
20043   print (vam->ofp,
20044          "table-id %d, prefix %U/%d stats-index %d",
20045          ntohl (mp->table_id), format_ip4_address, mp->address,
20046          mp->address_length, ntohl (mp->stats_index));
20047   fp = mp->path;
20048   for (i = 0; i < count; i++)
20049     {
20050       if (fp->afi == IP46_TYPE_IP6)
20051         print (vam->ofp,
20052                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20053                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20054                "next_hop_table %d",
20055                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20056                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20057                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20058       else if (fp->afi == IP46_TYPE_IP4)
20059         print (vam->ofp,
20060                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20061                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20062                "next_hop_table %d",
20063                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20064                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20065                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20066       fp++;
20067     }
20068 }
20069
20070 static void vl_api_ip_fib_details_t_handler_json
20071   (vl_api_ip_fib_details_t * mp)
20072 {
20073   vat_main_t *vam = &vat_main;
20074   int count = ntohl (mp->count);
20075   vat_json_node_t *node = NULL;
20076   struct in_addr ip4;
20077   struct in6_addr ip6;
20078   vl_api_fib_path_t *fp;
20079   int i;
20080
20081   if (VAT_JSON_ARRAY != vam->json_tree.type)
20082     {
20083       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20084       vat_json_init_array (&vam->json_tree);
20085     }
20086   node = vat_json_array_add (&vam->json_tree);
20087
20088   vat_json_init_object (node);
20089   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20090   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20091   vat_json_object_add_ip4 (node, "prefix", ip4);
20092   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20093   vat_json_object_add_uint (node, "path_count", count);
20094   fp = mp->path;
20095   for (i = 0; i < count; i++)
20096     {
20097       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20098       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20099       vat_json_object_add_uint (node, "is_local", fp->is_local);
20100       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20101       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20102       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20103       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20104       if (fp->afi == IP46_TYPE_IP4)
20105         {
20106           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20107           vat_json_object_add_ip4 (node, "next_hop", ip4);
20108         }
20109       else if (fp->afi == IP46_TYPE_IP6)
20110         {
20111           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20112           vat_json_object_add_ip6 (node, "next_hop", ip6);
20113         }
20114     }
20115 }
20116
20117 static int
20118 api_ip_fib_dump (vat_main_t * vam)
20119 {
20120   vl_api_ip_fib_dump_t *mp;
20121   vl_api_control_ping_t *mp_ping;
20122   int ret;
20123
20124   M (IP_FIB_DUMP, mp);
20125   S (mp);
20126
20127   /* Use a control ping for synchronization */
20128   MPING (CONTROL_PING, mp_ping);
20129   S (mp_ping);
20130
20131   W (ret);
20132   return ret;
20133 }
20134
20135 static int
20136 api_ip_mfib_dump (vat_main_t * vam)
20137 {
20138   vl_api_ip_mfib_dump_t *mp;
20139   vl_api_control_ping_t *mp_ping;
20140   int ret;
20141
20142   M (IP_MFIB_DUMP, mp);
20143   S (mp);
20144
20145   /* Use a control ping for synchronization */
20146   MPING (CONTROL_PING, mp_ping);
20147   S (mp_ping);
20148
20149   W (ret);
20150   return ret;
20151 }
20152
20153 static void vl_api_ip_neighbor_details_t_handler
20154   (vl_api_ip_neighbor_details_t * mp)
20155 {
20156   vat_main_t *vam = &vat_main;
20157
20158   print (vam->ofp, "%c %U %U",
20159          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
20160          format_vl_api_mac_address, &mp->neighbor.mac_address,
20161          format_vl_api_address, &mp->neighbor.ip_address);
20162 }
20163
20164 static void vl_api_ip_neighbor_details_t_handler_json
20165   (vl_api_ip_neighbor_details_t * mp)
20166 {
20167
20168   vat_main_t *vam = &vat_main;
20169   vat_json_node_t *node;
20170   struct in_addr ip4;
20171   struct in6_addr ip6;
20172
20173   if (VAT_JSON_ARRAY != vam->json_tree.type)
20174     {
20175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20176       vat_json_init_array (&vam->json_tree);
20177     }
20178   node = vat_json_array_add (&vam->json_tree);
20179
20180   vat_json_init_object (node);
20181   vat_json_object_add_string_copy
20182     (node, "flag",
20183      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
20184       (u8 *) "static" : (u8 *) "dynamic"));
20185
20186   vat_json_object_add_string_copy (node, "link_layer",
20187                                    format (0, "%U", format_vl_api_mac_address,
20188                                            &mp->neighbor.mac_address));
20189
20190   if (ADDRESS_IP6 == mp->neighbor.ip_address.af)
20191     {
20192       clib_memcpy (&ip6, &mp->neighbor.ip_address.un.ip6, sizeof (ip6));
20193       vat_json_object_add_ip6 (node, "ip_address", ip6);
20194     }
20195   else
20196     {
20197       clib_memcpy (&ip4, &mp->neighbor.ip_address.un.ip4, sizeof (ip4));
20198       vat_json_object_add_ip4 (node, "ip_address", ip4);
20199     }
20200 }
20201
20202 static int
20203 api_ip_neighbor_dump (vat_main_t * vam)
20204 {
20205   unformat_input_t *i = vam->input;
20206   vl_api_ip_neighbor_dump_t *mp;
20207   vl_api_control_ping_t *mp_ping;
20208   u8 is_ipv6 = 0;
20209   u32 sw_if_index = ~0;
20210   int ret;
20211
20212   /* Parse args required to build the message */
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         ;
20217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20218         ;
20219       else if (unformat (i, "ip6"))
20220         is_ipv6 = 1;
20221       else
20222         break;
20223     }
20224
20225   if (sw_if_index == ~0)
20226     {
20227       errmsg ("missing interface name or sw_if_index");
20228       return -99;
20229     }
20230
20231   M (IP_NEIGHBOR_DUMP, mp);
20232   mp->is_ipv6 = (u8) is_ipv6;
20233   mp->sw_if_index = ntohl (sw_if_index);
20234   S (mp);
20235
20236   /* Use a control ping for synchronization */
20237   MPING (CONTROL_PING, mp_ping);
20238   S (mp_ping);
20239
20240   W (ret);
20241   return ret;
20242 }
20243
20244 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20245 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20246
20247 static void
20248 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20249 {
20250   vat_main_t *vam = &vat_main;
20251   int count = ntohl (mp->count);
20252   vl_api_fib_path_t *fp;
20253   int i;
20254
20255   print (vam->ofp,
20256          "table-id %d, prefix %U/%d stats-index %d",
20257          ntohl (mp->table_id), format_ip6_address, mp->address,
20258          mp->address_length, ntohl (mp->stats_index));
20259   fp = mp->path;
20260   for (i = 0; i < count; i++)
20261     {
20262       if (fp->afi == IP46_TYPE_IP6)
20263         print (vam->ofp,
20264                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20265                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20266                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20267                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20268                format_ip6_address, fp->next_hop);
20269       else if (fp->afi == IP46_TYPE_IP4)
20270         print (vam->ofp,
20271                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20272                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20273                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20274                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20275                format_ip4_address, fp->next_hop);
20276       fp++;
20277     }
20278 }
20279
20280 static void vl_api_ip6_fib_details_t_handler_json
20281   (vl_api_ip6_fib_details_t * mp)
20282 {
20283   vat_main_t *vam = &vat_main;
20284   int count = ntohl (mp->count);
20285   vat_json_node_t *node = NULL;
20286   struct in_addr ip4;
20287   struct in6_addr ip6;
20288   vl_api_fib_path_t *fp;
20289   int i;
20290
20291   if (VAT_JSON_ARRAY != vam->json_tree.type)
20292     {
20293       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20294       vat_json_init_array (&vam->json_tree);
20295     }
20296   node = vat_json_array_add (&vam->json_tree);
20297
20298   vat_json_init_object (node);
20299   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20300   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20301   vat_json_object_add_ip6 (node, "prefix", ip6);
20302   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20303   vat_json_object_add_uint (node, "path_count", count);
20304   fp = mp->path;
20305   for (i = 0; i < count; i++)
20306     {
20307       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20308       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20309       vat_json_object_add_uint (node, "is_local", fp->is_local);
20310       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20311       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20312       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20313       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20314       if (fp->afi == IP46_TYPE_IP4)
20315         {
20316           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20317           vat_json_object_add_ip4 (node, "next_hop", ip4);
20318         }
20319       else if (fp->afi == IP46_TYPE_IP6)
20320         {
20321           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20322           vat_json_object_add_ip6 (node, "next_hop", ip6);
20323         }
20324     }
20325 }
20326
20327 static int
20328 api_ip6_fib_dump (vat_main_t * vam)
20329 {
20330   vl_api_ip6_fib_dump_t *mp;
20331   vl_api_control_ping_t *mp_ping;
20332   int ret;
20333
20334   M (IP6_FIB_DUMP, mp);
20335   S (mp);
20336
20337   /* Use a control ping for synchronization */
20338   MPING (CONTROL_PING, mp_ping);
20339   S (mp_ping);
20340
20341   W (ret);
20342   return ret;
20343 }
20344
20345 static int
20346 api_ip6_mfib_dump (vat_main_t * vam)
20347 {
20348   vl_api_ip6_mfib_dump_t *mp;
20349   vl_api_control_ping_t *mp_ping;
20350   int ret;
20351
20352   M (IP6_MFIB_DUMP, mp);
20353   S (mp);
20354
20355   /* Use a control ping for synchronization */
20356   MPING (CONTROL_PING, mp_ping);
20357   S (mp_ping);
20358
20359   W (ret);
20360   return ret;
20361 }
20362
20363 int
20364 api_classify_table_ids (vat_main_t * vam)
20365 {
20366   vl_api_classify_table_ids_t *mp;
20367   int ret;
20368
20369   /* Construct the API message */
20370   M (CLASSIFY_TABLE_IDS, mp);
20371   mp->context = 0;
20372
20373   S (mp);
20374   W (ret);
20375   return ret;
20376 }
20377
20378 int
20379 api_classify_table_by_interface (vat_main_t * vam)
20380 {
20381   unformat_input_t *input = vam->input;
20382   vl_api_classify_table_by_interface_t *mp;
20383
20384   u32 sw_if_index = ~0;
20385   int ret;
20386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20387     {
20388       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20389         ;
20390       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20391         ;
20392       else
20393         break;
20394     }
20395   if (sw_if_index == ~0)
20396     {
20397       errmsg ("missing interface name or sw_if_index");
20398       return -99;
20399     }
20400
20401   /* Construct the API message */
20402   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20403   mp->context = 0;
20404   mp->sw_if_index = ntohl (sw_if_index);
20405
20406   S (mp);
20407   W (ret);
20408   return ret;
20409 }
20410
20411 int
20412 api_classify_table_info (vat_main_t * vam)
20413 {
20414   unformat_input_t *input = vam->input;
20415   vl_api_classify_table_info_t *mp;
20416
20417   u32 table_id = ~0;
20418   int ret;
20419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20420     {
20421       if (unformat (input, "table_id %d", &table_id))
20422         ;
20423       else
20424         break;
20425     }
20426   if (table_id == ~0)
20427     {
20428       errmsg ("missing table id");
20429       return -99;
20430     }
20431
20432   /* Construct the API message */
20433   M (CLASSIFY_TABLE_INFO, mp);
20434   mp->context = 0;
20435   mp->table_id = ntohl (table_id);
20436
20437   S (mp);
20438   W (ret);
20439   return ret;
20440 }
20441
20442 int
20443 api_classify_session_dump (vat_main_t * vam)
20444 {
20445   unformat_input_t *input = vam->input;
20446   vl_api_classify_session_dump_t *mp;
20447   vl_api_control_ping_t *mp_ping;
20448
20449   u32 table_id = ~0;
20450   int ret;
20451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20452     {
20453       if (unformat (input, "table_id %d", &table_id))
20454         ;
20455       else
20456         break;
20457     }
20458   if (table_id == ~0)
20459     {
20460       errmsg ("missing table id");
20461       return -99;
20462     }
20463
20464   /* Construct the API message */
20465   M (CLASSIFY_SESSION_DUMP, mp);
20466   mp->context = 0;
20467   mp->table_id = ntohl (table_id);
20468   S (mp);
20469
20470   /* Use a control ping for synchronization */
20471   MPING (CONTROL_PING, mp_ping);
20472   S (mp_ping);
20473
20474   W (ret);
20475   return ret;
20476 }
20477
20478 static void
20479 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20480 {
20481   vat_main_t *vam = &vat_main;
20482
20483   print (vam->ofp, "collector_address %U, collector_port %d, "
20484          "src_address %U, vrf_id %d, path_mtu %u, "
20485          "template_interval %u, udp_checksum %d",
20486          format_ip4_address, mp->collector_address,
20487          ntohs (mp->collector_port),
20488          format_ip4_address, mp->src_address,
20489          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20490          ntohl (mp->template_interval), mp->udp_checksum);
20491
20492   vam->retval = 0;
20493   vam->result_ready = 1;
20494 }
20495
20496 static void
20497   vl_api_ipfix_exporter_details_t_handler_json
20498   (vl_api_ipfix_exporter_details_t * mp)
20499 {
20500   vat_main_t *vam = &vat_main;
20501   vat_json_node_t node;
20502   struct in_addr collector_address;
20503   struct in_addr src_address;
20504
20505   vat_json_init_object (&node);
20506   clib_memcpy (&collector_address, &mp->collector_address,
20507                sizeof (collector_address));
20508   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20509   vat_json_object_add_uint (&node, "collector_port",
20510                             ntohs (mp->collector_port));
20511   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20512   vat_json_object_add_ip4 (&node, "src_address", src_address);
20513   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20514   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20515   vat_json_object_add_uint (&node, "template_interval",
20516                             ntohl (mp->template_interval));
20517   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20518
20519   vat_json_print (vam->ofp, &node);
20520   vat_json_free (&node);
20521   vam->retval = 0;
20522   vam->result_ready = 1;
20523 }
20524
20525 int
20526 api_ipfix_exporter_dump (vat_main_t * vam)
20527 {
20528   vl_api_ipfix_exporter_dump_t *mp;
20529   int ret;
20530
20531   /* Construct the API message */
20532   M (IPFIX_EXPORTER_DUMP, mp);
20533   mp->context = 0;
20534
20535   S (mp);
20536   W (ret);
20537   return ret;
20538 }
20539
20540 static int
20541 api_ipfix_classify_stream_dump (vat_main_t * vam)
20542 {
20543   vl_api_ipfix_classify_stream_dump_t *mp;
20544   int ret;
20545
20546   /* Construct the API message */
20547   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20548   mp->context = 0;
20549
20550   S (mp);
20551   W (ret);
20552   return ret;
20553   /* NOTREACHED */
20554   return 0;
20555 }
20556
20557 static void
20558   vl_api_ipfix_classify_stream_details_t_handler
20559   (vl_api_ipfix_classify_stream_details_t * mp)
20560 {
20561   vat_main_t *vam = &vat_main;
20562   print (vam->ofp, "domain_id %d, src_port %d",
20563          ntohl (mp->domain_id), ntohs (mp->src_port));
20564   vam->retval = 0;
20565   vam->result_ready = 1;
20566 }
20567
20568 static void
20569   vl_api_ipfix_classify_stream_details_t_handler_json
20570   (vl_api_ipfix_classify_stream_details_t * mp)
20571 {
20572   vat_main_t *vam = &vat_main;
20573   vat_json_node_t node;
20574
20575   vat_json_init_object (&node);
20576   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20577   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20578
20579   vat_json_print (vam->ofp, &node);
20580   vat_json_free (&node);
20581   vam->retval = 0;
20582   vam->result_ready = 1;
20583 }
20584
20585 static int
20586 api_ipfix_classify_table_dump (vat_main_t * vam)
20587 {
20588   vl_api_ipfix_classify_table_dump_t *mp;
20589   vl_api_control_ping_t *mp_ping;
20590   int ret;
20591
20592   if (!vam->json_output)
20593     {
20594       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20595              "transport_protocol");
20596     }
20597
20598   /* Construct the API message */
20599   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20600
20601   /* send it... */
20602   S (mp);
20603
20604   /* Use a control ping for synchronization */
20605   MPING (CONTROL_PING, mp_ping);
20606   S (mp_ping);
20607
20608   W (ret);
20609   return ret;
20610 }
20611
20612 static void
20613   vl_api_ipfix_classify_table_details_t_handler
20614   (vl_api_ipfix_classify_table_details_t * mp)
20615 {
20616   vat_main_t *vam = &vat_main;
20617   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20618          mp->transport_protocol);
20619 }
20620
20621 static void
20622   vl_api_ipfix_classify_table_details_t_handler_json
20623   (vl_api_ipfix_classify_table_details_t * mp)
20624 {
20625   vat_json_node_t *node = NULL;
20626   vat_main_t *vam = &vat_main;
20627
20628   if (VAT_JSON_ARRAY != vam->json_tree.type)
20629     {
20630       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20631       vat_json_init_array (&vam->json_tree);
20632     }
20633
20634   node = vat_json_array_add (&vam->json_tree);
20635   vat_json_init_object (node);
20636
20637   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20638   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20639   vat_json_object_add_uint (node, "transport_protocol",
20640                             mp->transport_protocol);
20641 }
20642
20643 static int
20644 api_sw_interface_span_enable_disable (vat_main_t * vam)
20645 {
20646   unformat_input_t *i = vam->input;
20647   vl_api_sw_interface_span_enable_disable_t *mp;
20648   u32 src_sw_if_index = ~0;
20649   u32 dst_sw_if_index = ~0;
20650   u8 state = 3;
20651   int ret;
20652   u8 is_l2 = 0;
20653
20654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20655     {
20656       if (unformat
20657           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20658         ;
20659       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20660         ;
20661       else
20662         if (unformat
20663             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20664         ;
20665       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20666         ;
20667       else if (unformat (i, "disable"))
20668         state = 0;
20669       else if (unformat (i, "rx"))
20670         state = 1;
20671       else if (unformat (i, "tx"))
20672         state = 2;
20673       else if (unformat (i, "both"))
20674         state = 3;
20675       else if (unformat (i, "l2"))
20676         is_l2 = 1;
20677       else
20678         break;
20679     }
20680
20681   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20682
20683   mp->sw_if_index_from = htonl (src_sw_if_index);
20684   mp->sw_if_index_to = htonl (dst_sw_if_index);
20685   mp->state = state;
20686   mp->is_l2 = is_l2;
20687
20688   S (mp);
20689   W (ret);
20690   return ret;
20691 }
20692
20693 static void
20694 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20695                                             * mp)
20696 {
20697   vat_main_t *vam = &vat_main;
20698   u8 *sw_if_from_name = 0;
20699   u8 *sw_if_to_name = 0;
20700   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20701   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20702   char *states[] = { "none", "rx", "tx", "both" };
20703   hash_pair_t *p;
20704
20705   /* *INDENT-OFF* */
20706   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20707   ({
20708     if ((u32) p->value[0] == sw_if_index_from)
20709       {
20710         sw_if_from_name = (u8 *)(p->key);
20711         if (sw_if_to_name)
20712           break;
20713       }
20714     if ((u32) p->value[0] == sw_if_index_to)
20715       {
20716         sw_if_to_name = (u8 *)(p->key);
20717         if (sw_if_from_name)
20718           break;
20719       }
20720   }));
20721   /* *INDENT-ON* */
20722   print (vam->ofp, "%20s => %20s (%s) %s",
20723          sw_if_from_name, sw_if_to_name, states[mp->state],
20724          mp->is_l2 ? "l2" : "device");
20725 }
20726
20727 static void
20728   vl_api_sw_interface_span_details_t_handler_json
20729   (vl_api_sw_interface_span_details_t * mp)
20730 {
20731   vat_main_t *vam = &vat_main;
20732   vat_json_node_t *node = NULL;
20733   u8 *sw_if_from_name = 0;
20734   u8 *sw_if_to_name = 0;
20735   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20736   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20737   hash_pair_t *p;
20738
20739   /* *INDENT-OFF* */
20740   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20741   ({
20742     if ((u32) p->value[0] == sw_if_index_from)
20743       {
20744         sw_if_from_name = (u8 *)(p->key);
20745         if (sw_if_to_name)
20746           break;
20747       }
20748     if ((u32) p->value[0] == sw_if_index_to)
20749       {
20750         sw_if_to_name = (u8 *)(p->key);
20751         if (sw_if_from_name)
20752           break;
20753       }
20754   }));
20755   /* *INDENT-ON* */
20756
20757   if (VAT_JSON_ARRAY != vam->json_tree.type)
20758     {
20759       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20760       vat_json_init_array (&vam->json_tree);
20761     }
20762   node = vat_json_array_add (&vam->json_tree);
20763
20764   vat_json_init_object (node);
20765   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20766   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20767   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20768   if (0 != sw_if_to_name)
20769     {
20770       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20771     }
20772   vat_json_object_add_uint (node, "state", mp->state);
20773   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20774 }
20775
20776 static int
20777 api_sw_interface_span_dump (vat_main_t * vam)
20778 {
20779   unformat_input_t *input = vam->input;
20780   vl_api_sw_interface_span_dump_t *mp;
20781   vl_api_control_ping_t *mp_ping;
20782   u8 is_l2 = 0;
20783   int ret;
20784
20785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20786     {
20787       if (unformat (input, "l2"))
20788         is_l2 = 1;
20789       else
20790         break;
20791     }
20792
20793   M (SW_INTERFACE_SPAN_DUMP, mp);
20794   mp->is_l2 = is_l2;
20795   S (mp);
20796
20797   /* Use a control ping for synchronization */
20798   MPING (CONTROL_PING, mp_ping);
20799   S (mp_ping);
20800
20801   W (ret);
20802   return ret;
20803 }
20804
20805 int
20806 api_pg_create_interface (vat_main_t * vam)
20807 {
20808   unformat_input_t *input = vam->input;
20809   vl_api_pg_create_interface_t *mp;
20810
20811   u32 if_id = ~0;
20812   int ret;
20813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20814     {
20815       if (unformat (input, "if_id %d", &if_id))
20816         ;
20817       else
20818         break;
20819     }
20820   if (if_id == ~0)
20821     {
20822       errmsg ("missing pg interface index");
20823       return -99;
20824     }
20825
20826   /* Construct the API message */
20827   M (PG_CREATE_INTERFACE, mp);
20828   mp->context = 0;
20829   mp->interface_id = ntohl (if_id);
20830
20831   S (mp);
20832   W (ret);
20833   return ret;
20834 }
20835
20836 int
20837 api_pg_capture (vat_main_t * vam)
20838 {
20839   unformat_input_t *input = vam->input;
20840   vl_api_pg_capture_t *mp;
20841
20842   u32 if_id = ~0;
20843   u8 enable = 1;
20844   u32 count = 1;
20845   u8 pcap_file_set = 0;
20846   u8 *pcap_file = 0;
20847   int ret;
20848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20849     {
20850       if (unformat (input, "if_id %d", &if_id))
20851         ;
20852       else if (unformat (input, "pcap %s", &pcap_file))
20853         pcap_file_set = 1;
20854       else if (unformat (input, "count %d", &count))
20855         ;
20856       else if (unformat (input, "disable"))
20857         enable = 0;
20858       else
20859         break;
20860     }
20861   if (if_id == ~0)
20862     {
20863       errmsg ("missing pg interface index");
20864       return -99;
20865     }
20866   if (pcap_file_set > 0)
20867     {
20868       if (vec_len (pcap_file) > 255)
20869         {
20870           errmsg ("pcap file name is too long");
20871           return -99;
20872         }
20873     }
20874
20875   u32 name_len = vec_len (pcap_file);
20876   /* Construct the API message */
20877   M (PG_CAPTURE, mp);
20878   mp->context = 0;
20879   mp->interface_id = ntohl (if_id);
20880   mp->is_enabled = enable;
20881   mp->count = ntohl (count);
20882   mp->pcap_name_length = ntohl (name_len);
20883   if (pcap_file_set != 0)
20884     {
20885       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20886     }
20887   vec_free (pcap_file);
20888
20889   S (mp);
20890   W (ret);
20891   return ret;
20892 }
20893
20894 int
20895 api_pg_enable_disable (vat_main_t * vam)
20896 {
20897   unformat_input_t *input = vam->input;
20898   vl_api_pg_enable_disable_t *mp;
20899
20900   u8 enable = 1;
20901   u8 stream_name_set = 0;
20902   u8 *stream_name = 0;
20903   int ret;
20904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20905     {
20906       if (unformat (input, "stream %s", &stream_name))
20907         stream_name_set = 1;
20908       else if (unformat (input, "disable"))
20909         enable = 0;
20910       else
20911         break;
20912     }
20913
20914   if (stream_name_set > 0)
20915     {
20916       if (vec_len (stream_name) > 255)
20917         {
20918           errmsg ("stream name too long");
20919           return -99;
20920         }
20921     }
20922
20923   u32 name_len = vec_len (stream_name);
20924   /* Construct the API message */
20925   M (PG_ENABLE_DISABLE, mp);
20926   mp->context = 0;
20927   mp->is_enabled = enable;
20928   if (stream_name_set != 0)
20929     {
20930       mp->stream_name_length = ntohl (name_len);
20931       clib_memcpy (mp->stream_name, stream_name, name_len);
20932     }
20933   vec_free (stream_name);
20934
20935   S (mp);
20936   W (ret);
20937   return ret;
20938 }
20939
20940 int
20941 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20942 {
20943   unformat_input_t *input = vam->input;
20944   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20945
20946   u16 *low_ports = 0;
20947   u16 *high_ports = 0;
20948   u16 this_low;
20949   u16 this_hi;
20950   vl_api_prefix_t prefix;
20951   u32 tmp, tmp2;
20952   u8 prefix_set = 0;
20953   u32 vrf_id = ~0;
20954   u8 is_add = 1;
20955   u8 is_ipv6 = 0;
20956   int ret;
20957
20958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20959     {
20960       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20961         prefix_set = 1;
20962       else if (unformat (input, "vrf %d", &vrf_id))
20963         ;
20964       else if (unformat (input, "del"))
20965         is_add = 0;
20966       else if (unformat (input, "port %d", &tmp))
20967         {
20968           if (tmp == 0 || tmp > 65535)
20969             {
20970               errmsg ("port %d out of range", tmp);
20971               return -99;
20972             }
20973           this_low = tmp;
20974           this_hi = this_low + 1;
20975           vec_add1 (low_ports, this_low);
20976           vec_add1 (high_ports, this_hi);
20977         }
20978       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20979         {
20980           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20981             {
20982               errmsg ("incorrect range parameters");
20983               return -99;
20984             }
20985           this_low = tmp;
20986           /* Note: in debug CLI +1 is added to high before
20987              passing to real fn that does "the work"
20988              (ip_source_and_port_range_check_add_del).
20989              This fn is a wrapper around the binary API fn a
20990              control plane will call, which expects this increment
20991              to have occurred. Hence letting the binary API control
20992              plane fn do the increment for consistency between VAT
20993              and other control planes.
20994            */
20995           this_hi = tmp2;
20996           vec_add1 (low_ports, this_low);
20997           vec_add1 (high_ports, this_hi);
20998         }
20999       else
21000         break;
21001     }
21002
21003   if (prefix_set == 0)
21004     {
21005       errmsg ("<address>/<mask> not specified");
21006       return -99;
21007     }
21008
21009   if (vrf_id == ~0)
21010     {
21011       errmsg ("VRF ID required, not specified");
21012       return -99;
21013     }
21014
21015   if (vrf_id == 0)
21016     {
21017       errmsg
21018         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21019       return -99;
21020     }
21021
21022   if (vec_len (low_ports) == 0)
21023     {
21024       errmsg ("At least one port or port range required");
21025       return -99;
21026     }
21027
21028   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21029
21030   mp->is_add = is_add;
21031
21032   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
21033
21034   mp->number_of_ranges = vec_len (low_ports);
21035
21036   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21037   vec_free (low_ports);
21038
21039   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21040   vec_free (high_ports);
21041
21042   mp->vrf_id = ntohl (vrf_id);
21043
21044   S (mp);
21045   W (ret);
21046   return ret;
21047 }
21048
21049 int
21050 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21051 {
21052   unformat_input_t *input = vam->input;
21053   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21054   u32 sw_if_index = ~0;
21055   int vrf_set = 0;
21056   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21057   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21058   u8 is_add = 1;
21059   int ret;
21060
21061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21062     {
21063       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21064         ;
21065       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21066         ;
21067       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21068         vrf_set = 1;
21069       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21070         vrf_set = 1;
21071       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21072         vrf_set = 1;
21073       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21074         vrf_set = 1;
21075       else if (unformat (input, "del"))
21076         is_add = 0;
21077       else
21078         break;
21079     }
21080
21081   if (sw_if_index == ~0)
21082     {
21083       errmsg ("Interface required but not specified");
21084       return -99;
21085     }
21086
21087   if (vrf_set == 0)
21088     {
21089       errmsg ("VRF ID required but not specified");
21090       return -99;
21091     }
21092
21093   if (tcp_out_vrf_id == 0
21094       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21095     {
21096       errmsg
21097         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21098       return -99;
21099     }
21100
21101   /* Construct the API message */
21102   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21103
21104   mp->sw_if_index = ntohl (sw_if_index);
21105   mp->is_add = is_add;
21106   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21107   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21108   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21109   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21110
21111   /* send it... */
21112   S (mp);
21113
21114   /* Wait for a reply... */
21115   W (ret);
21116   return ret;
21117 }
21118
21119 static int
21120 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21121 {
21122   unformat_input_t *i = vam->input;
21123   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21124   u32 local_sa_id = 0;
21125   u32 remote_sa_id = 0;
21126   ip4_address_t src_address;
21127   ip4_address_t dst_address;
21128   u8 is_add = 1;
21129   int ret;
21130
21131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21132     {
21133       if (unformat (i, "local_sa %d", &local_sa_id))
21134         ;
21135       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21136         ;
21137       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21138         ;
21139       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21140         ;
21141       else if (unformat (i, "del"))
21142         is_add = 0;
21143       else
21144         {
21145           clib_warning ("parse error '%U'", format_unformat_error, i);
21146           return -99;
21147         }
21148     }
21149
21150   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21151
21152   mp->local_sa_id = ntohl (local_sa_id);
21153   mp->remote_sa_id = ntohl (remote_sa_id);
21154   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21155   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21156   mp->is_add = is_add;
21157
21158   S (mp);
21159   W (ret);
21160   return ret;
21161 }
21162
21163 static int
21164 api_set_punt (vat_main_t * vam)
21165 {
21166   unformat_input_t *i = vam->input;
21167   vl_api_set_punt_t *mp;
21168   u32 ipv = ~0;
21169   u32 protocol = ~0;
21170   u32 port = ~0;
21171   int is_add = 1;
21172   int ret;
21173
21174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21175     {
21176       if (unformat (i, "ip %d", &ipv))
21177         ;
21178       else if (unformat (i, "protocol %d", &protocol))
21179         ;
21180       else if (unformat (i, "port %d", &port))
21181         ;
21182       else if (unformat (i, "del"))
21183         is_add = 0;
21184       else
21185         {
21186           clib_warning ("parse error '%U'", format_unformat_error, i);
21187           return -99;
21188         }
21189     }
21190
21191   M (SET_PUNT, mp);
21192
21193   mp->is_add = (u8) is_add;
21194   mp->punt.ipv = (u8) ipv;
21195   mp->punt.l4_protocol = (u8) protocol;
21196   mp->punt.l4_port = htons ((u16) port);
21197
21198   S (mp);
21199   W (ret);
21200   return ret;
21201 }
21202
21203 static void vl_api_ipsec_gre_tunnel_details_t_handler
21204   (vl_api_ipsec_gre_tunnel_details_t * mp)
21205 {
21206   vat_main_t *vam = &vat_main;
21207
21208   print (vam->ofp, "%11d%15U%15U%14d%14d",
21209          ntohl (mp->sw_if_index),
21210          format_ip4_address, &mp->src_address,
21211          format_ip4_address, &mp->dst_address,
21212          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21213 }
21214
21215 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21216   (vl_api_ipsec_gre_tunnel_details_t * mp)
21217 {
21218   vat_main_t *vam = &vat_main;
21219   vat_json_node_t *node = NULL;
21220   struct in_addr ip4;
21221
21222   if (VAT_JSON_ARRAY != vam->json_tree.type)
21223     {
21224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21225       vat_json_init_array (&vam->json_tree);
21226     }
21227   node = vat_json_array_add (&vam->json_tree);
21228
21229   vat_json_init_object (node);
21230   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21231   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21232   vat_json_object_add_ip4 (node, "src_address", ip4);
21233   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21234   vat_json_object_add_ip4 (node, "dst_address", ip4);
21235   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21236   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21237 }
21238
21239 static int
21240 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21241 {
21242   unformat_input_t *i = vam->input;
21243   vl_api_ipsec_gre_tunnel_dump_t *mp;
21244   vl_api_control_ping_t *mp_ping;
21245   u32 sw_if_index;
21246   u8 sw_if_index_set = 0;
21247   int ret;
21248
21249   /* Parse args required to build the message */
21250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21251     {
21252       if (unformat (i, "sw_if_index %d", &sw_if_index))
21253         sw_if_index_set = 1;
21254       else
21255         break;
21256     }
21257
21258   if (sw_if_index_set == 0)
21259     {
21260       sw_if_index = ~0;
21261     }
21262
21263   if (!vam->json_output)
21264     {
21265       print (vam->ofp, "%11s%15s%15s%14s%14s",
21266              "sw_if_index", "src_address", "dst_address",
21267              "local_sa_id", "remote_sa_id");
21268     }
21269
21270   /* Get list of gre-tunnel interfaces */
21271   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21272
21273   mp->sw_if_index = htonl (sw_if_index);
21274
21275   S (mp);
21276
21277   /* Use a control ping for synchronization */
21278   MPING (CONTROL_PING, mp_ping);
21279   S (mp_ping);
21280
21281   W (ret);
21282   return ret;
21283 }
21284
21285 static int
21286 api_delete_subif (vat_main_t * vam)
21287 {
21288   unformat_input_t *i = vam->input;
21289   vl_api_delete_subif_t *mp;
21290   u32 sw_if_index = ~0;
21291   int ret;
21292
21293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21294     {
21295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21296         ;
21297       if (unformat (i, "sw_if_index %d", &sw_if_index))
21298         ;
21299       else
21300         break;
21301     }
21302
21303   if (sw_if_index == ~0)
21304     {
21305       errmsg ("missing sw_if_index");
21306       return -99;
21307     }
21308
21309   /* Construct the API message */
21310   M (DELETE_SUBIF, mp);
21311   mp->sw_if_index = ntohl (sw_if_index);
21312
21313   S (mp);
21314   W (ret);
21315   return ret;
21316 }
21317
21318 #define foreach_pbb_vtr_op      \
21319 _("disable",  L2_VTR_DISABLED)  \
21320 _("pop",  L2_VTR_POP_2)         \
21321 _("push",  L2_VTR_PUSH_2)
21322
21323 static int
21324 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21325 {
21326   unformat_input_t *i = vam->input;
21327   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21328   u32 sw_if_index = ~0, vtr_op = ~0;
21329   u16 outer_tag = ~0;
21330   u8 dmac[6], smac[6];
21331   u8 dmac_set = 0, smac_set = 0;
21332   u16 vlanid = 0;
21333   u32 sid = ~0;
21334   u32 tmp;
21335   int ret;
21336
21337   /* Shut up coverity */
21338   clib_memset (dmac, 0, sizeof (dmac));
21339   clib_memset (smac, 0, sizeof (smac));
21340
21341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21342     {
21343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21344         ;
21345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21346         ;
21347       else if (unformat (i, "vtr_op %d", &vtr_op))
21348         ;
21349 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21350       foreach_pbb_vtr_op
21351 #undef _
21352         else if (unformat (i, "translate_pbb_stag"))
21353         {
21354           if (unformat (i, "%d", &tmp))
21355             {
21356               vtr_op = L2_VTR_TRANSLATE_2_1;
21357               outer_tag = tmp;
21358             }
21359           else
21360             {
21361               errmsg
21362                 ("translate_pbb_stag operation requires outer tag definition");
21363               return -99;
21364             }
21365         }
21366       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21367         dmac_set++;
21368       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21369         smac_set++;
21370       else if (unformat (i, "sid %d", &sid))
21371         ;
21372       else if (unformat (i, "vlanid %d", &tmp))
21373         vlanid = tmp;
21374       else
21375         {
21376           clib_warning ("parse error '%U'", format_unformat_error, i);
21377           return -99;
21378         }
21379     }
21380
21381   if ((sw_if_index == ~0) || (vtr_op == ~0))
21382     {
21383       errmsg ("missing sw_if_index or vtr operation");
21384       return -99;
21385     }
21386   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21387       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21388     {
21389       errmsg
21390         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21391       return -99;
21392     }
21393
21394   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21395   mp->sw_if_index = ntohl (sw_if_index);
21396   mp->vtr_op = ntohl (vtr_op);
21397   mp->outer_tag = ntohs (outer_tag);
21398   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21399   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21400   mp->b_vlanid = ntohs (vlanid);
21401   mp->i_sid = ntohl (sid);
21402
21403   S (mp);
21404   W (ret);
21405   return ret;
21406 }
21407
21408 static int
21409 api_flow_classify_set_interface (vat_main_t * vam)
21410 {
21411   unformat_input_t *i = vam->input;
21412   vl_api_flow_classify_set_interface_t *mp;
21413   u32 sw_if_index;
21414   int sw_if_index_set;
21415   u32 ip4_table_index = ~0;
21416   u32 ip6_table_index = ~0;
21417   u8 is_add = 1;
21418   int ret;
21419
21420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21421     {
21422       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21423         sw_if_index_set = 1;
21424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21425         sw_if_index_set = 1;
21426       else if (unformat (i, "del"))
21427         is_add = 0;
21428       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21429         ;
21430       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21431         ;
21432       else
21433         {
21434           clib_warning ("parse error '%U'", format_unformat_error, i);
21435           return -99;
21436         }
21437     }
21438
21439   if (sw_if_index_set == 0)
21440     {
21441       errmsg ("missing interface name or sw_if_index");
21442       return -99;
21443     }
21444
21445   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21446
21447   mp->sw_if_index = ntohl (sw_if_index);
21448   mp->ip4_table_index = ntohl (ip4_table_index);
21449   mp->ip6_table_index = ntohl (ip6_table_index);
21450   mp->is_add = is_add;
21451
21452   S (mp);
21453   W (ret);
21454   return ret;
21455 }
21456
21457 static int
21458 api_flow_classify_dump (vat_main_t * vam)
21459 {
21460   unformat_input_t *i = vam->input;
21461   vl_api_flow_classify_dump_t *mp;
21462   vl_api_control_ping_t *mp_ping;
21463   u8 type = FLOW_CLASSIFY_N_TABLES;
21464   int ret;
21465
21466   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21467     ;
21468   else
21469     {
21470       errmsg ("classify table type must be specified");
21471       return -99;
21472     }
21473
21474   if (!vam->json_output)
21475     {
21476       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21477     }
21478
21479   M (FLOW_CLASSIFY_DUMP, mp);
21480   mp->type = type;
21481   /* send it... */
21482   S (mp);
21483
21484   /* Use a control ping for synchronization */
21485   MPING (CONTROL_PING, mp_ping);
21486   S (mp_ping);
21487
21488   /* Wait for a reply... */
21489   W (ret);
21490   return ret;
21491 }
21492
21493 static int
21494 api_feature_enable_disable (vat_main_t * vam)
21495 {
21496   unformat_input_t *i = vam->input;
21497   vl_api_feature_enable_disable_t *mp;
21498   u8 *arc_name = 0;
21499   u8 *feature_name = 0;
21500   u32 sw_if_index = ~0;
21501   u8 enable = 1;
21502   int ret;
21503
21504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21505     {
21506       if (unformat (i, "arc_name %s", &arc_name))
21507         ;
21508       else if (unformat (i, "feature_name %s", &feature_name))
21509         ;
21510       else
21511         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21512         ;
21513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21514         ;
21515       else if (unformat (i, "disable"))
21516         enable = 0;
21517       else
21518         break;
21519     }
21520
21521   if (arc_name == 0)
21522     {
21523       errmsg ("missing arc name");
21524       return -99;
21525     }
21526   if (vec_len (arc_name) > 63)
21527     {
21528       errmsg ("arc name too long");
21529     }
21530
21531   if (feature_name == 0)
21532     {
21533       errmsg ("missing feature name");
21534       return -99;
21535     }
21536   if (vec_len (feature_name) > 63)
21537     {
21538       errmsg ("feature name too long");
21539     }
21540
21541   if (sw_if_index == ~0)
21542     {
21543       errmsg ("missing interface name or sw_if_index");
21544       return -99;
21545     }
21546
21547   /* Construct the API message */
21548   M (FEATURE_ENABLE_DISABLE, mp);
21549   mp->sw_if_index = ntohl (sw_if_index);
21550   mp->enable = enable;
21551   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21552   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21553   vec_free (arc_name);
21554   vec_free (feature_name);
21555
21556   S (mp);
21557   W (ret);
21558   return ret;
21559 }
21560
21561 static int
21562 api_sw_interface_tag_add_del (vat_main_t * vam)
21563 {
21564   unformat_input_t *i = vam->input;
21565   vl_api_sw_interface_tag_add_del_t *mp;
21566   u32 sw_if_index = ~0;
21567   u8 *tag = 0;
21568   u8 enable = 1;
21569   int ret;
21570
21571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21572     {
21573       if (unformat (i, "tag %s", &tag))
21574         ;
21575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21576         ;
21577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21578         ;
21579       else if (unformat (i, "del"))
21580         enable = 0;
21581       else
21582         break;
21583     }
21584
21585   if (sw_if_index == ~0)
21586     {
21587       errmsg ("missing interface name or sw_if_index");
21588       return -99;
21589     }
21590
21591   if (enable && (tag == 0))
21592     {
21593       errmsg ("no tag specified");
21594       return -99;
21595     }
21596
21597   /* Construct the API message */
21598   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21599   mp->sw_if_index = ntohl (sw_if_index);
21600   mp->is_add = enable;
21601   if (enable)
21602     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21603   vec_free (tag);
21604
21605   S (mp);
21606   W (ret);
21607   return ret;
21608 }
21609
21610 static void vl_api_l2_xconnect_details_t_handler
21611   (vl_api_l2_xconnect_details_t * mp)
21612 {
21613   vat_main_t *vam = &vat_main;
21614
21615   print (vam->ofp, "%15d%15d",
21616          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21617 }
21618
21619 static void vl_api_l2_xconnect_details_t_handler_json
21620   (vl_api_l2_xconnect_details_t * mp)
21621 {
21622   vat_main_t *vam = &vat_main;
21623   vat_json_node_t *node = NULL;
21624
21625   if (VAT_JSON_ARRAY != vam->json_tree.type)
21626     {
21627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21628       vat_json_init_array (&vam->json_tree);
21629     }
21630   node = vat_json_array_add (&vam->json_tree);
21631
21632   vat_json_init_object (node);
21633   vat_json_object_add_uint (node, "rx_sw_if_index",
21634                             ntohl (mp->rx_sw_if_index));
21635   vat_json_object_add_uint (node, "tx_sw_if_index",
21636                             ntohl (mp->tx_sw_if_index));
21637 }
21638
21639 static int
21640 api_l2_xconnect_dump (vat_main_t * vam)
21641 {
21642   vl_api_l2_xconnect_dump_t *mp;
21643   vl_api_control_ping_t *mp_ping;
21644   int ret;
21645
21646   if (!vam->json_output)
21647     {
21648       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21649     }
21650
21651   M (L2_XCONNECT_DUMP, mp);
21652
21653   S (mp);
21654
21655   /* Use a control ping for synchronization */
21656   MPING (CONTROL_PING, mp_ping);
21657   S (mp_ping);
21658
21659   W (ret);
21660   return ret;
21661 }
21662
21663 static int
21664 api_hw_interface_set_mtu (vat_main_t * vam)
21665 {
21666   unformat_input_t *i = vam->input;
21667   vl_api_hw_interface_set_mtu_t *mp;
21668   u32 sw_if_index = ~0;
21669   u32 mtu = 0;
21670   int ret;
21671
21672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21673     {
21674       if (unformat (i, "mtu %d", &mtu))
21675         ;
21676       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21677         ;
21678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21679         ;
21680       else
21681         break;
21682     }
21683
21684   if (sw_if_index == ~0)
21685     {
21686       errmsg ("missing interface name or sw_if_index");
21687       return -99;
21688     }
21689
21690   if (mtu == 0)
21691     {
21692       errmsg ("no mtu specified");
21693       return -99;
21694     }
21695
21696   /* Construct the API message */
21697   M (HW_INTERFACE_SET_MTU, mp);
21698   mp->sw_if_index = ntohl (sw_if_index);
21699   mp->mtu = ntohs ((u16) mtu);
21700
21701   S (mp);
21702   W (ret);
21703   return ret;
21704 }
21705
21706 static int
21707 api_p2p_ethernet_add (vat_main_t * vam)
21708 {
21709   unformat_input_t *i = vam->input;
21710   vl_api_p2p_ethernet_add_t *mp;
21711   u32 parent_if_index = ~0;
21712   u32 sub_id = ~0;
21713   u8 remote_mac[6];
21714   u8 mac_set = 0;
21715   int ret;
21716
21717   clib_memset (remote_mac, 0, sizeof (remote_mac));
21718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21719     {
21720       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21721         ;
21722       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21723         ;
21724       else
21725         if (unformat
21726             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21727         mac_set++;
21728       else if (unformat (i, "sub_id %d", &sub_id))
21729         ;
21730       else
21731         {
21732           clib_warning ("parse error '%U'", format_unformat_error, i);
21733           return -99;
21734         }
21735     }
21736
21737   if (parent_if_index == ~0)
21738     {
21739       errmsg ("missing interface name or sw_if_index");
21740       return -99;
21741     }
21742   if (mac_set == 0)
21743     {
21744       errmsg ("missing remote mac address");
21745       return -99;
21746     }
21747   if (sub_id == ~0)
21748     {
21749       errmsg ("missing sub-interface id");
21750       return -99;
21751     }
21752
21753   M (P2P_ETHERNET_ADD, mp);
21754   mp->parent_if_index = ntohl (parent_if_index);
21755   mp->subif_id = ntohl (sub_id);
21756   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21757
21758   S (mp);
21759   W (ret);
21760   return ret;
21761 }
21762
21763 static int
21764 api_p2p_ethernet_del (vat_main_t * vam)
21765 {
21766   unformat_input_t *i = vam->input;
21767   vl_api_p2p_ethernet_del_t *mp;
21768   u32 parent_if_index = ~0;
21769   u8 remote_mac[6];
21770   u8 mac_set = 0;
21771   int ret;
21772
21773   clib_memset (remote_mac, 0, sizeof (remote_mac));
21774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21775     {
21776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21777         ;
21778       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21779         ;
21780       else
21781         if (unformat
21782             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21783         mac_set++;
21784       else
21785         {
21786           clib_warning ("parse error '%U'", format_unformat_error, i);
21787           return -99;
21788         }
21789     }
21790
21791   if (parent_if_index == ~0)
21792     {
21793       errmsg ("missing interface name or sw_if_index");
21794       return -99;
21795     }
21796   if (mac_set == 0)
21797     {
21798       errmsg ("missing remote mac address");
21799       return -99;
21800     }
21801
21802   M (P2P_ETHERNET_DEL, mp);
21803   mp->parent_if_index = ntohl (parent_if_index);
21804   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21805
21806   S (mp);
21807   W (ret);
21808   return ret;
21809 }
21810
21811 static int
21812 api_lldp_config (vat_main_t * vam)
21813 {
21814   unformat_input_t *i = vam->input;
21815   vl_api_lldp_config_t *mp;
21816   int tx_hold = 0;
21817   int tx_interval = 0;
21818   u8 *sys_name = NULL;
21819   int ret;
21820
21821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21822     {
21823       if (unformat (i, "system-name %s", &sys_name))
21824         ;
21825       else if (unformat (i, "tx-hold %d", &tx_hold))
21826         ;
21827       else if (unformat (i, "tx-interval %d", &tx_interval))
21828         ;
21829       else
21830         {
21831           clib_warning ("parse error '%U'", format_unformat_error, i);
21832           return -99;
21833         }
21834     }
21835
21836   vec_add1 (sys_name, 0);
21837
21838   M (LLDP_CONFIG, mp);
21839   mp->tx_hold = htonl (tx_hold);
21840   mp->tx_interval = htonl (tx_interval);
21841   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21842   vec_free (sys_name);
21843
21844   S (mp);
21845   W (ret);
21846   return ret;
21847 }
21848
21849 static int
21850 api_sw_interface_set_lldp (vat_main_t * vam)
21851 {
21852   unformat_input_t *i = vam->input;
21853   vl_api_sw_interface_set_lldp_t *mp;
21854   u32 sw_if_index = ~0;
21855   u32 enable = 1;
21856   u8 *port_desc = NULL, *mgmt_oid = NULL;
21857   ip4_address_t ip4_addr;
21858   ip6_address_t ip6_addr;
21859   int ret;
21860
21861   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21862   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21863
21864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21865     {
21866       if (unformat (i, "disable"))
21867         enable = 0;
21868       else
21869         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21870         ;
21871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21872         ;
21873       else if (unformat (i, "port-desc %s", &port_desc))
21874         ;
21875       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21876         ;
21877       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21878         ;
21879       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21880         ;
21881       else
21882         break;
21883     }
21884
21885   if (sw_if_index == ~0)
21886     {
21887       errmsg ("missing interface name or sw_if_index");
21888       return -99;
21889     }
21890
21891   /* Construct the API message */
21892   vec_add1 (port_desc, 0);
21893   vec_add1 (mgmt_oid, 0);
21894   M (SW_INTERFACE_SET_LLDP, mp);
21895   mp->sw_if_index = ntohl (sw_if_index);
21896   mp->enable = enable;
21897   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21898   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21899   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21900   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21901   vec_free (port_desc);
21902   vec_free (mgmt_oid);
21903
21904   S (mp);
21905   W (ret);
21906   return ret;
21907 }
21908
21909 static int
21910 api_tcp_configure_src_addresses (vat_main_t * vam)
21911 {
21912   vl_api_tcp_configure_src_addresses_t *mp;
21913   unformat_input_t *i = vam->input;
21914   ip4_address_t v4first, v4last;
21915   ip6_address_t v6first, v6last;
21916   u8 range_set = 0;
21917   u32 vrf_id = 0;
21918   int ret;
21919
21920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21921     {
21922       if (unformat (i, "%U - %U",
21923                     unformat_ip4_address, &v4first,
21924                     unformat_ip4_address, &v4last))
21925         {
21926           if (range_set)
21927             {
21928               errmsg ("one range per message (range already set)");
21929               return -99;
21930             }
21931           range_set = 1;
21932         }
21933       else if (unformat (i, "%U - %U",
21934                          unformat_ip6_address, &v6first,
21935                          unformat_ip6_address, &v6last))
21936         {
21937           if (range_set)
21938             {
21939               errmsg ("one range per message (range already set)");
21940               return -99;
21941             }
21942           range_set = 2;
21943         }
21944       else if (unformat (i, "vrf %d", &vrf_id))
21945         ;
21946       else
21947         break;
21948     }
21949
21950   if (range_set == 0)
21951     {
21952       errmsg ("address range not set");
21953       return -99;
21954     }
21955
21956   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21957   mp->vrf_id = ntohl (vrf_id);
21958   /* ipv6? */
21959   if (range_set == 2)
21960     {
21961       mp->is_ipv6 = 1;
21962       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21963       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21964     }
21965   else
21966     {
21967       mp->is_ipv6 = 0;
21968       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21969       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21970     }
21971   S (mp);
21972   W (ret);
21973   return ret;
21974 }
21975
21976 static void vl_api_app_namespace_add_del_reply_t_handler
21977   (vl_api_app_namespace_add_del_reply_t * mp)
21978 {
21979   vat_main_t *vam = &vat_main;
21980   i32 retval = ntohl (mp->retval);
21981   if (vam->async_mode)
21982     {
21983       vam->async_errors += (retval < 0);
21984     }
21985   else
21986     {
21987       vam->retval = retval;
21988       if (retval == 0)
21989         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21990       vam->result_ready = 1;
21991     }
21992 }
21993
21994 static void vl_api_app_namespace_add_del_reply_t_handler_json
21995   (vl_api_app_namespace_add_del_reply_t * mp)
21996 {
21997   vat_main_t *vam = &vat_main;
21998   vat_json_node_t node;
21999
22000   vat_json_init_object (&node);
22001   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22002   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22003
22004   vat_json_print (vam->ofp, &node);
22005   vat_json_free (&node);
22006
22007   vam->retval = ntohl (mp->retval);
22008   vam->result_ready = 1;
22009 }
22010
22011 static int
22012 api_app_namespace_add_del (vat_main_t * vam)
22013 {
22014   vl_api_app_namespace_add_del_t *mp;
22015   unformat_input_t *i = vam->input;
22016   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22017   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22018   u64 secret;
22019   int ret;
22020
22021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22022     {
22023       if (unformat (i, "id %_%v%_", &ns_id))
22024         ;
22025       else if (unformat (i, "secret %lu", &secret))
22026         secret_set = 1;
22027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22028         sw_if_index_set = 1;
22029       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22030         ;
22031       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22032         ;
22033       else
22034         break;
22035     }
22036   if (!ns_id || !secret_set || !sw_if_index_set)
22037     {
22038       errmsg ("namespace id, secret and sw_if_index must be set");
22039       return -99;
22040     }
22041   if (vec_len (ns_id) > 64)
22042     {
22043       errmsg ("namespace id too long");
22044       return -99;
22045     }
22046   M (APP_NAMESPACE_ADD_DEL, mp);
22047
22048   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22049   mp->namespace_id_len = vec_len (ns_id);
22050   mp->secret = clib_host_to_net_u64 (secret);
22051   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22052   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22053   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22054   vec_free (ns_id);
22055   S (mp);
22056   W (ret);
22057   return ret;
22058 }
22059
22060 static int
22061 api_sock_init_shm (vat_main_t * vam)
22062 {
22063 #if VPP_API_TEST_BUILTIN == 0
22064   unformat_input_t *i = vam->input;
22065   vl_api_shm_elem_config_t *config = 0;
22066   u64 size = 64 << 20;
22067   int rv;
22068
22069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22070     {
22071       if (unformat (i, "size %U", unformat_memory_size, &size))
22072         ;
22073       else
22074         break;
22075     }
22076
22077   /*
22078    * Canned custom ring allocator config.
22079    * Should probably parse all of this
22080    */
22081   vec_validate (config, 6);
22082   config[0].type = VL_API_VLIB_RING;
22083   config[0].size = 256;
22084   config[0].count = 32;
22085
22086   config[1].type = VL_API_VLIB_RING;
22087   config[1].size = 1024;
22088   config[1].count = 16;
22089
22090   config[2].type = VL_API_VLIB_RING;
22091   config[2].size = 4096;
22092   config[2].count = 2;
22093
22094   config[3].type = VL_API_CLIENT_RING;
22095   config[3].size = 256;
22096   config[3].count = 32;
22097
22098   config[4].type = VL_API_CLIENT_RING;
22099   config[4].size = 1024;
22100   config[4].count = 16;
22101
22102   config[5].type = VL_API_CLIENT_RING;
22103   config[5].size = 4096;
22104   config[5].count = 2;
22105
22106   config[6].type = VL_API_QUEUE;
22107   config[6].count = 128;
22108   config[6].size = sizeof (uword);
22109
22110   rv = vl_socket_client_init_shm (config);
22111   if (!rv)
22112     vam->client_index_invalid = 1;
22113   return rv;
22114 #else
22115   return -99;
22116 #endif
22117 }
22118
22119 static int
22120 api_dns_enable_disable (vat_main_t * vam)
22121 {
22122   unformat_input_t *line_input = vam->input;
22123   vl_api_dns_enable_disable_t *mp;
22124   u8 enable_disable = 1;
22125   int ret;
22126
22127   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22128     {
22129       if (unformat (line_input, "disable"))
22130         enable_disable = 0;
22131       if (unformat (line_input, "enable"))
22132         enable_disable = 1;
22133       else
22134         break;
22135     }
22136
22137   /* Construct the API message */
22138   M (DNS_ENABLE_DISABLE, mp);
22139   mp->enable = enable_disable;
22140
22141   /* send it... */
22142   S (mp);
22143   /* Wait for the reply */
22144   W (ret);
22145   return ret;
22146 }
22147
22148 static int
22149 api_dns_resolve_name (vat_main_t * vam)
22150 {
22151   unformat_input_t *line_input = vam->input;
22152   vl_api_dns_resolve_name_t *mp;
22153   u8 *name = 0;
22154   int ret;
22155
22156   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22157     {
22158       if (unformat (line_input, "%s", &name))
22159         ;
22160       else
22161         break;
22162     }
22163
22164   if (vec_len (name) > 127)
22165     {
22166       errmsg ("name too long");
22167       return -99;
22168     }
22169
22170   /* Construct the API message */
22171   M (DNS_RESOLVE_NAME, mp);
22172   memcpy (mp->name, name, vec_len (name));
22173   vec_free (name);
22174
22175   /* send it... */
22176   S (mp);
22177   /* Wait for the reply */
22178   W (ret);
22179   return ret;
22180 }
22181
22182 static int
22183 api_dns_resolve_ip (vat_main_t * vam)
22184 {
22185   unformat_input_t *line_input = vam->input;
22186   vl_api_dns_resolve_ip_t *mp;
22187   int is_ip6 = -1;
22188   ip4_address_t addr4;
22189   ip6_address_t addr6;
22190   int ret;
22191
22192   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22193     {
22194       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22195         is_ip6 = 1;
22196       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22197         is_ip6 = 0;
22198       else
22199         break;
22200     }
22201
22202   if (is_ip6 == -1)
22203     {
22204       errmsg ("missing address");
22205       return -99;
22206     }
22207
22208   /* Construct the API message */
22209   M (DNS_RESOLVE_IP, mp);
22210   mp->is_ip6 = is_ip6;
22211   if (is_ip6)
22212     memcpy (mp->address, &addr6, sizeof (addr6));
22213   else
22214     memcpy (mp->address, &addr4, sizeof (addr4));
22215
22216   /* send it... */
22217   S (mp);
22218   /* Wait for the reply */
22219   W (ret);
22220   return ret;
22221 }
22222
22223 static int
22224 api_dns_name_server_add_del (vat_main_t * vam)
22225 {
22226   unformat_input_t *i = vam->input;
22227   vl_api_dns_name_server_add_del_t *mp;
22228   u8 is_add = 1;
22229   ip6_address_t ip6_server;
22230   ip4_address_t ip4_server;
22231   int ip6_set = 0;
22232   int ip4_set = 0;
22233   int ret = 0;
22234
22235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22236     {
22237       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22238         ip6_set = 1;
22239       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22240         ip4_set = 1;
22241       else if (unformat (i, "del"))
22242         is_add = 0;
22243       else
22244         {
22245           clib_warning ("parse error '%U'", format_unformat_error, i);
22246           return -99;
22247         }
22248     }
22249
22250   if (ip4_set && ip6_set)
22251     {
22252       errmsg ("Only one server address allowed per message");
22253       return -99;
22254     }
22255   if ((ip4_set + ip6_set) == 0)
22256     {
22257       errmsg ("Server address required");
22258       return -99;
22259     }
22260
22261   /* Construct the API message */
22262   M (DNS_NAME_SERVER_ADD_DEL, mp);
22263
22264   if (ip6_set)
22265     {
22266       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22267       mp->is_ip6 = 1;
22268     }
22269   else
22270     {
22271       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22272       mp->is_ip6 = 0;
22273     }
22274
22275   mp->is_add = is_add;
22276
22277   /* send it... */
22278   S (mp);
22279
22280   /* Wait for a reply, return good/bad news  */
22281   W (ret);
22282   return ret;
22283 }
22284
22285 static void
22286 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22287 {
22288   vat_main_t *vam = &vat_main;
22289
22290   if (mp->is_ip4)
22291     {
22292       print (vam->ofp,
22293              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22294              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22295              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22296              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22297              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22298              clib_net_to_host_u32 (mp->action_index), mp->tag);
22299     }
22300   else
22301     {
22302       print (vam->ofp,
22303              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22304              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22305              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22306              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22307              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22308              clib_net_to_host_u32 (mp->action_index), mp->tag);
22309     }
22310 }
22311
22312 static void
22313 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22314                                              mp)
22315 {
22316   vat_main_t *vam = &vat_main;
22317   vat_json_node_t *node = NULL;
22318   struct in6_addr ip6;
22319   struct in_addr ip4;
22320
22321   if (VAT_JSON_ARRAY != vam->json_tree.type)
22322     {
22323       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22324       vat_json_init_array (&vam->json_tree);
22325     }
22326   node = vat_json_array_add (&vam->json_tree);
22327   vat_json_init_object (node);
22328
22329   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22330   vat_json_object_add_uint (node, "appns_index",
22331                             clib_net_to_host_u32 (mp->appns_index));
22332   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22333   vat_json_object_add_uint (node, "scope", mp->scope);
22334   vat_json_object_add_uint (node, "action_index",
22335                             clib_net_to_host_u32 (mp->action_index));
22336   vat_json_object_add_uint (node, "lcl_port",
22337                             clib_net_to_host_u16 (mp->lcl_port));
22338   vat_json_object_add_uint (node, "rmt_port",
22339                             clib_net_to_host_u16 (mp->rmt_port));
22340   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22341   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22342   vat_json_object_add_string_copy (node, "tag", mp->tag);
22343   if (mp->is_ip4)
22344     {
22345       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22346       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22347       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22348       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22349     }
22350   else
22351     {
22352       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22353       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22354       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22355       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22356     }
22357 }
22358
22359 static int
22360 api_session_rule_add_del (vat_main_t * vam)
22361 {
22362   vl_api_session_rule_add_del_t *mp;
22363   unformat_input_t *i = vam->input;
22364   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22365   u32 appns_index = 0, scope = 0;
22366   ip4_address_t lcl_ip4, rmt_ip4;
22367   ip6_address_t lcl_ip6, rmt_ip6;
22368   u8 is_ip4 = 1, conn_set = 0;
22369   u8 is_add = 1, *tag = 0;
22370   int ret;
22371
22372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22373     {
22374       if (unformat (i, "del"))
22375         is_add = 0;
22376       else if (unformat (i, "add"))
22377         ;
22378       else if (unformat (i, "proto tcp"))
22379         proto = 0;
22380       else if (unformat (i, "proto udp"))
22381         proto = 1;
22382       else if (unformat (i, "appns %d", &appns_index))
22383         ;
22384       else if (unformat (i, "scope %d", &scope))
22385         ;
22386       else if (unformat (i, "tag %_%v%_", &tag))
22387         ;
22388       else
22389         if (unformat
22390             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22391              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22392              &rmt_port))
22393         {
22394           is_ip4 = 1;
22395           conn_set = 1;
22396         }
22397       else
22398         if (unformat
22399             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22400              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22401              &rmt_port))
22402         {
22403           is_ip4 = 0;
22404           conn_set = 1;
22405         }
22406       else if (unformat (i, "action %d", &action))
22407         ;
22408       else
22409         break;
22410     }
22411   if (proto == ~0 || !conn_set || action == ~0)
22412     {
22413       errmsg ("transport proto, connection and action must be set");
22414       return -99;
22415     }
22416
22417   if (scope > 3)
22418     {
22419       errmsg ("scope should be 0-3");
22420       return -99;
22421     }
22422
22423   M (SESSION_RULE_ADD_DEL, mp);
22424
22425   mp->is_ip4 = is_ip4;
22426   mp->transport_proto = proto;
22427   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22428   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22429   mp->lcl_plen = lcl_plen;
22430   mp->rmt_plen = rmt_plen;
22431   mp->action_index = clib_host_to_net_u32 (action);
22432   mp->appns_index = clib_host_to_net_u32 (appns_index);
22433   mp->scope = scope;
22434   mp->is_add = is_add;
22435   if (is_ip4)
22436     {
22437       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22438       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22439     }
22440   else
22441     {
22442       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22443       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22444     }
22445   if (tag)
22446     {
22447       clib_memcpy (mp->tag, tag, vec_len (tag));
22448       vec_free (tag);
22449     }
22450
22451   S (mp);
22452   W (ret);
22453   return ret;
22454 }
22455
22456 static int
22457 api_session_rules_dump (vat_main_t * vam)
22458 {
22459   vl_api_session_rules_dump_t *mp;
22460   vl_api_control_ping_t *mp_ping;
22461   int ret;
22462
22463   if (!vam->json_output)
22464     {
22465       print (vam->ofp, "%=20s", "Session Rules");
22466     }
22467
22468   M (SESSION_RULES_DUMP, mp);
22469   /* send it... */
22470   S (mp);
22471
22472   /* Use a control ping for synchronization */
22473   MPING (CONTROL_PING, mp_ping);
22474   S (mp_ping);
22475
22476   /* Wait for a reply... */
22477   W (ret);
22478   return ret;
22479 }
22480
22481 static int
22482 api_ip_container_proxy_add_del (vat_main_t * vam)
22483 {
22484   vl_api_ip_container_proxy_add_del_t *mp;
22485   unformat_input_t *i = vam->input;
22486   u32 sw_if_index = ~0;
22487   vl_api_prefix_t pfx = { };
22488   u8 is_add = 1;
22489   int ret;
22490
22491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22492     {
22493       if (unformat (i, "del"))
22494         is_add = 0;
22495       else if (unformat (i, "add"))
22496         ;
22497       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
22498         ;
22499       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22500         ;
22501       else
22502         break;
22503     }
22504   if (sw_if_index == ~0 || pfx.address_length == 0)
22505     {
22506       errmsg ("address and sw_if_index must be set");
22507       return -99;
22508     }
22509
22510   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22511
22512   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22513   mp->is_add = is_add;
22514   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
22515
22516   S (mp);
22517   W (ret);
22518   return ret;
22519 }
22520
22521 static int
22522 api_qos_record_enable_disable (vat_main_t * vam)
22523 {
22524   unformat_input_t *i = vam->input;
22525   vl_api_qos_record_enable_disable_t *mp;
22526   u32 sw_if_index, qs = 0xff;
22527   u8 sw_if_index_set = 0;
22528   u8 enable = 1;
22529   int ret;
22530
22531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22532     {
22533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22534         sw_if_index_set = 1;
22535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22536         sw_if_index_set = 1;
22537       else if (unformat (i, "%U", unformat_qos_source, &qs))
22538         ;
22539       else if (unformat (i, "disable"))
22540         enable = 0;
22541       else
22542         {
22543           clib_warning ("parse error '%U'", format_unformat_error, i);
22544           return -99;
22545         }
22546     }
22547
22548   if (sw_if_index_set == 0)
22549     {
22550       errmsg ("missing interface name or sw_if_index");
22551       return -99;
22552     }
22553   if (qs == 0xff)
22554     {
22555       errmsg ("input location must be specified");
22556       return -99;
22557     }
22558
22559   M (QOS_RECORD_ENABLE_DISABLE, mp);
22560
22561   mp->sw_if_index = ntohl (sw_if_index);
22562   mp->input_source = qs;
22563   mp->enable = enable;
22564
22565   S (mp);
22566   W (ret);
22567   return ret;
22568 }
22569
22570
22571 static int
22572 q_or_quit (vat_main_t * vam)
22573 {
22574 #if VPP_API_TEST_BUILTIN == 0
22575   longjmp (vam->jump_buf, 1);
22576 #endif
22577   return 0;                     /* not so much */
22578 }
22579
22580 static int
22581 q (vat_main_t * vam)
22582 {
22583   return q_or_quit (vam);
22584 }
22585
22586 static int
22587 quit (vat_main_t * vam)
22588 {
22589   return q_or_quit (vam);
22590 }
22591
22592 static int
22593 comment (vat_main_t * vam)
22594 {
22595   return 0;
22596 }
22597
22598 static int
22599 statseg (vat_main_t * vam)
22600 {
22601   ssvm_private_t *ssvmp = &vam->stat_segment;
22602   ssvm_shared_header_t *shared_header = ssvmp->sh;
22603   vlib_counter_t **counters;
22604   u64 thread0_index1_packets;
22605   u64 thread0_index1_bytes;
22606   f64 vector_rate, input_rate;
22607   uword *p;
22608
22609   uword *counter_vector_by_name;
22610   if (vam->stat_segment_lockp == 0)
22611     {
22612       errmsg ("Stat segment not mapped...");
22613       return -99;
22614     }
22615
22616   /* look up "/if/rx for sw_if_index 1 as a test */
22617
22618   clib_spinlock_lock (vam->stat_segment_lockp);
22619
22620   counter_vector_by_name = (uword *) shared_header->opaque[1];
22621
22622   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22623   if (p == 0)
22624     {
22625       clib_spinlock_unlock (vam->stat_segment_lockp);
22626       errmsg ("/if/tx not found?");
22627       return -99;
22628     }
22629
22630   /* Fish per-thread vector of combined counters from shared memory */
22631   counters = (vlib_counter_t **) p[0];
22632
22633   if (vec_len (counters[0]) < 2)
22634     {
22635       clib_spinlock_unlock (vam->stat_segment_lockp);
22636       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22637       return -99;
22638     }
22639
22640   /* Read thread 0 sw_if_index 1 counter */
22641   thread0_index1_packets = counters[0][1].packets;
22642   thread0_index1_bytes = counters[0][1].bytes;
22643
22644   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22645   if (p == 0)
22646     {
22647       clib_spinlock_unlock (vam->stat_segment_lockp);
22648       errmsg ("vector_rate not found?");
22649       return -99;
22650     }
22651
22652   vector_rate = *(f64 *) (p[0]);
22653   p = hash_get_mem (counter_vector_by_name, "input_rate");
22654   if (p == 0)
22655     {
22656       clib_spinlock_unlock (vam->stat_segment_lockp);
22657       errmsg ("input_rate not found?");
22658       return -99;
22659     }
22660   input_rate = *(f64 *) (p[0]);
22661
22662   clib_spinlock_unlock (vam->stat_segment_lockp);
22663
22664   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22665          vector_rate, input_rate);
22666   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22667          thread0_index1_packets, thread0_index1_bytes);
22668
22669   return 0;
22670 }
22671
22672 static int
22673 cmd_cmp (void *a1, void *a2)
22674 {
22675   u8 **c1 = a1;
22676   u8 **c2 = a2;
22677
22678   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22679 }
22680
22681 static int
22682 help (vat_main_t * vam)
22683 {
22684   u8 **cmds = 0;
22685   u8 *name = 0;
22686   hash_pair_t *p;
22687   unformat_input_t *i = vam->input;
22688   int j;
22689
22690   if (unformat (i, "%s", &name))
22691     {
22692       uword *hs;
22693
22694       vec_add1 (name, 0);
22695
22696       hs = hash_get_mem (vam->help_by_name, name);
22697       if (hs)
22698         print (vam->ofp, "usage: %s %s", name, hs[0]);
22699       else
22700         print (vam->ofp, "No such msg / command '%s'", name);
22701       vec_free (name);
22702       return 0;
22703     }
22704
22705   print (vam->ofp, "Help is available for the following:");
22706
22707     /* *INDENT-OFF* */
22708     hash_foreach_pair (p, vam->function_by_name,
22709     ({
22710       vec_add1 (cmds, (u8 *)(p->key));
22711     }));
22712     /* *INDENT-ON* */
22713
22714   vec_sort_with_function (cmds, cmd_cmp);
22715
22716   for (j = 0; j < vec_len (cmds); j++)
22717     print (vam->ofp, "%s", cmds[j]);
22718
22719   vec_free (cmds);
22720   return 0;
22721 }
22722
22723 static int
22724 set (vat_main_t * vam)
22725 {
22726   u8 *name = 0, *value = 0;
22727   unformat_input_t *i = vam->input;
22728
22729   if (unformat (i, "%s", &name))
22730     {
22731       /* The input buffer is a vector, not a string. */
22732       value = vec_dup (i->buffer);
22733       vec_delete (value, i->index, 0);
22734       /* Almost certainly has a trailing newline */
22735       if (value[vec_len (value) - 1] == '\n')
22736         value[vec_len (value) - 1] = 0;
22737       /* Make sure it's a proper string, one way or the other */
22738       vec_add1 (value, 0);
22739       (void) clib_macro_set_value (&vam->macro_main,
22740                                    (char *) name, (char *) value);
22741     }
22742   else
22743     errmsg ("usage: set <name> <value>");
22744
22745   vec_free (name);
22746   vec_free (value);
22747   return 0;
22748 }
22749
22750 static int
22751 unset (vat_main_t * vam)
22752 {
22753   u8 *name = 0;
22754
22755   if (unformat (vam->input, "%s", &name))
22756     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22757       errmsg ("unset: %s wasn't set", name);
22758   vec_free (name);
22759   return 0;
22760 }
22761
22762 typedef struct
22763 {
22764   u8 *name;
22765   u8 *value;
22766 } macro_sort_t;
22767
22768
22769 static int
22770 macro_sort_cmp (void *a1, void *a2)
22771 {
22772   macro_sort_t *s1 = a1;
22773   macro_sort_t *s2 = a2;
22774
22775   return strcmp ((char *) (s1->name), (char *) (s2->name));
22776 }
22777
22778 static int
22779 dump_macro_table (vat_main_t * vam)
22780 {
22781   macro_sort_t *sort_me = 0, *sm;
22782   int i;
22783   hash_pair_t *p;
22784
22785     /* *INDENT-OFF* */
22786     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22787     ({
22788       vec_add2 (sort_me, sm, 1);
22789       sm->name = (u8 *)(p->key);
22790       sm->value = (u8 *) (p->value[0]);
22791     }));
22792     /* *INDENT-ON* */
22793
22794   vec_sort_with_function (sort_me, macro_sort_cmp);
22795
22796   if (vec_len (sort_me))
22797     print (vam->ofp, "%-15s%s", "Name", "Value");
22798   else
22799     print (vam->ofp, "The macro table is empty...");
22800
22801   for (i = 0; i < vec_len (sort_me); i++)
22802     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22803   return 0;
22804 }
22805
22806 static int
22807 dump_node_table (vat_main_t * vam)
22808 {
22809   int i, j;
22810   vlib_node_t *node, *next_node;
22811
22812   if (vec_len (vam->graph_nodes) == 0)
22813     {
22814       print (vam->ofp, "Node table empty, issue get_node_graph...");
22815       return 0;
22816     }
22817
22818   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22819     {
22820       node = vam->graph_nodes[0][i];
22821       print (vam->ofp, "[%d] %s", i, node->name);
22822       for (j = 0; j < vec_len (node->next_nodes); j++)
22823         {
22824           if (node->next_nodes[j] != ~0)
22825             {
22826               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22827               print (vam->ofp, "  [%d] %s", j, next_node->name);
22828             }
22829         }
22830     }
22831   return 0;
22832 }
22833
22834 static int
22835 value_sort_cmp (void *a1, void *a2)
22836 {
22837   name_sort_t *n1 = a1;
22838   name_sort_t *n2 = a2;
22839
22840   if (n1->value < n2->value)
22841     return -1;
22842   if (n1->value > n2->value)
22843     return 1;
22844   return 0;
22845 }
22846
22847
22848 static int
22849 dump_msg_api_table (vat_main_t * vam)
22850 {
22851   api_main_t *am = &api_main;
22852   name_sort_t *nses = 0, *ns;
22853   hash_pair_t *hp;
22854   int i;
22855
22856   /* *INDENT-OFF* */
22857   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22858   ({
22859     vec_add2 (nses, ns, 1);
22860     ns->name = (u8 *)(hp->key);
22861     ns->value = (u32) hp->value[0];
22862   }));
22863   /* *INDENT-ON* */
22864
22865   vec_sort_with_function (nses, value_sort_cmp);
22866
22867   for (i = 0; i < vec_len (nses); i++)
22868     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22869   vec_free (nses);
22870   return 0;
22871 }
22872
22873 static int
22874 get_msg_id (vat_main_t * vam)
22875 {
22876   u8 *name_and_crc;
22877   u32 message_index;
22878
22879   if (unformat (vam->input, "%s", &name_and_crc))
22880     {
22881       message_index = vl_msg_api_get_msg_index (name_and_crc);
22882       if (message_index == ~0)
22883         {
22884           print (vam->ofp, " '%s' not found", name_and_crc);
22885           return 0;
22886         }
22887       print (vam->ofp, " '%s' has message index %d",
22888              name_and_crc, message_index);
22889       return 0;
22890     }
22891   errmsg ("name_and_crc required...");
22892   return 0;
22893 }
22894
22895 static int
22896 search_node_table (vat_main_t * vam)
22897 {
22898   unformat_input_t *line_input = vam->input;
22899   u8 *node_to_find;
22900   int j;
22901   vlib_node_t *node, *next_node;
22902   uword *p;
22903
22904   if (vam->graph_node_index_by_name == 0)
22905     {
22906       print (vam->ofp, "Node table empty, issue get_node_graph...");
22907       return 0;
22908     }
22909
22910   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22911     {
22912       if (unformat (line_input, "%s", &node_to_find))
22913         {
22914           vec_add1 (node_to_find, 0);
22915           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22916           if (p == 0)
22917             {
22918               print (vam->ofp, "%s not found...", node_to_find);
22919               goto out;
22920             }
22921           node = vam->graph_nodes[0][p[0]];
22922           print (vam->ofp, "[%d] %s", p[0], node->name);
22923           for (j = 0; j < vec_len (node->next_nodes); j++)
22924             {
22925               if (node->next_nodes[j] != ~0)
22926                 {
22927                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22928                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22929                 }
22930             }
22931         }
22932
22933       else
22934         {
22935           clib_warning ("parse error '%U'", format_unformat_error,
22936                         line_input);
22937           return -99;
22938         }
22939
22940     out:
22941       vec_free (node_to_find);
22942
22943     }
22944
22945   return 0;
22946 }
22947
22948
22949 static int
22950 script (vat_main_t * vam)
22951 {
22952 #if (VPP_API_TEST_BUILTIN==0)
22953   u8 *s = 0;
22954   char *save_current_file;
22955   unformat_input_t save_input;
22956   jmp_buf save_jump_buf;
22957   u32 save_line_number;
22958
22959   FILE *new_fp, *save_ifp;
22960
22961   if (unformat (vam->input, "%s", &s))
22962     {
22963       new_fp = fopen ((char *) s, "r");
22964       if (new_fp == 0)
22965         {
22966           errmsg ("Couldn't open script file %s", s);
22967           vec_free (s);
22968           return -99;
22969         }
22970     }
22971   else
22972     {
22973       errmsg ("Missing script name");
22974       return -99;
22975     }
22976
22977   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22978   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22979   save_ifp = vam->ifp;
22980   save_line_number = vam->input_line_number;
22981   save_current_file = (char *) vam->current_file;
22982
22983   vam->input_line_number = 0;
22984   vam->ifp = new_fp;
22985   vam->current_file = s;
22986   do_one_file (vam);
22987
22988   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22989   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22990   vam->ifp = save_ifp;
22991   vam->input_line_number = save_line_number;
22992   vam->current_file = (u8 *) save_current_file;
22993   vec_free (s);
22994
22995   return 0;
22996 #else
22997   clib_warning ("use the exec command...");
22998   return -99;
22999 #endif
23000 }
23001
23002 static int
23003 echo (vat_main_t * vam)
23004 {
23005   print (vam->ofp, "%v", vam->input->buffer);
23006   return 0;
23007 }
23008
23009 /* List of API message constructors, CLI names map to api_xxx */
23010 #define foreach_vpe_api_msg                                             \
23011 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23012 _(sw_interface_dump,"")                                                 \
23013 _(sw_interface_set_flags,                                               \
23014   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23015 _(sw_interface_add_del_address,                                         \
23016   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23017 _(sw_interface_set_rx_mode,                                             \
23018   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23019 _(sw_interface_set_rx_placement,                                        \
23020   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23021 _(sw_interface_rx_placement_dump,                                       \
23022   "[<intfc> | sw_if_index <id>]")                                         \
23023 _(sw_interface_set_table,                                               \
23024   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23025 _(sw_interface_set_mpls_enable,                                         \
23026   "<intfc> | sw_if_index [disable | dis]")                              \
23027 _(sw_interface_set_vpath,                                               \
23028   "<intfc> | sw_if_index <id> enable | disable")                        \
23029 _(sw_interface_set_vxlan_bypass,                                        \
23030   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23031 _(sw_interface_set_geneve_bypass,                                       \
23032   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23033 _(sw_interface_set_l2_xconnect,                                         \
23034   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23035   "enable | disable")                                                   \
23036 _(sw_interface_set_l2_bridge,                                           \
23037   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23038   "[shg <split-horizon-group>] [bvi]\n"                                 \
23039   "enable | disable")                                                   \
23040 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23041 _(bridge_domain_add_del,                                                \
23042   "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") \
23043 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23044 _(l2fib_add_del,                                                        \
23045   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23046 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23047 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23048 _(l2_flags,                                                             \
23049   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23050 _(bridge_flags,                                                         \
23051   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23052 _(tap_create_v2,                                                        \
23053   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23054 _(tap_delete_v2,                                                        \
23055   "<vpp-if-name> | sw_if_index <id>")                                   \
23056 _(sw_interface_tap_v2_dump, "")                                         \
23057 _(virtio_pci_create,                                                    \
23058   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
23059 _(virtio_pci_delete,                                                    \
23060   "<vpp-if-name> | sw_if_index <id>")                                   \
23061 _(sw_interface_virtio_pci_dump, "")                                     \
23062 _(bond_create,                                                          \
23063   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23064   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
23065   "[id <if-id>]")                                                       \
23066 _(bond_delete,                                                          \
23067   "<vpp-if-name> | sw_if_index <id>")                                   \
23068 _(bond_enslave,                                                         \
23069   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23070 _(bond_detach_slave,                                                    \
23071   "sw_if_index <n>")                                                    \
23072 _(sw_interface_bond_dump, "")                                           \
23073 _(sw_interface_slave_dump,                                              \
23074   "<vpp-if-name> | sw_if_index <id>")                                   \
23075 _(ip_table_add_del,                                                     \
23076   "table <n> [ipv6] [add | del]\n")                                     \
23077 _(ip_add_del_route,                                                     \
23078   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23079   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23080   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23081   "[multipath] [count <n>] [del]")                                      \
23082 _(ip_mroute_add_del,                                                    \
23083   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23084   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23085 _(mpls_table_add_del,                                                   \
23086   "table <n> [add | del]\n")                                            \
23087 _(mpls_route_add_del,                                                   \
23088   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23089   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23090   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23091   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23092   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23093   "[count <n>] [del]")                                                  \
23094 _(mpls_ip_bind_unbind,                                                  \
23095   "<label> <addr/len>")                                                 \
23096 _(mpls_tunnel_add_del,                                                  \
23097   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23098   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23099   "[l2-only]  [out-label <n>]")                                         \
23100 _(sr_mpls_policy_add,                                                   \
23101   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23102 _(sr_mpls_policy_del,                                                   \
23103   "bsid <id>")                                                          \
23104 _(bier_table_add_del,                                                   \
23105   "<label> <sub-domain> <set> <bsl> [del]")                             \
23106 _(bier_route_add_del,                                                   \
23107   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23108   "[<intfc> | sw_if_index <id>]"                                        \
23109   "[weight <n>] [del] [multipath]")                                     \
23110 _(proxy_arp_add_del,                                                    \
23111   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23112 _(proxy_arp_intfc_enable_disable,                                       \
23113   "<intfc> | sw_if_index <id> enable | disable")                        \
23114 _(sw_interface_set_unnumbered,                                          \
23115   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23116 _(ip_neighbor_add_del,                                                  \
23117   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23118   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23119 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23120 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23121   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23122   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23123   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23124 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23125 _(reset_fib, "vrf <n> [ipv6]")                                          \
23126 _(dhcp_proxy_config,                                                    \
23127   "svr <v46-address> src <v46-address>\n"                               \
23128    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23129 _(dhcp_proxy_set_vss,                                                   \
23130   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23131 _(dhcp_proxy_dump, "ip6")                                               \
23132 _(dhcp_client_config,                                                   \
23133   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23134 _(set_ip_flow_hash,                                                     \
23135   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23136 _(sw_interface_ip6_enable_disable,                                      \
23137   "<intfc> | sw_if_index <id> enable | disable")                        \
23138 _(ip6nd_proxy_add_del,                                                  \
23139   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23140 _(ip6nd_proxy_dump, "")                                                 \
23141 _(sw_interface_ip6nd_ra_prefix,                                         \
23142   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23143   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23144   "[nolink] [isno]")                                                    \
23145 _(sw_interface_ip6nd_ra_config,                                         \
23146   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23147   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23148   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23149 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23150 _(l2_patch_add_del,                                                     \
23151   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23152   "enable | disable")                                                   \
23153 _(sr_localsid_add_del,                                                  \
23154   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23155   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23156 _(classify_add_del_table,                                               \
23157   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23158   " [del] [del-chain] mask <mask-value>\n"                              \
23159   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23160   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23161 _(classify_add_del_session,                                             \
23162   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23163   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23164   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23165   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23166 _(classify_set_interface_ip_table,                                      \
23167   "<intfc> | sw_if_index <nn> table <nn>")                              \
23168 _(classify_set_interface_l2_tables,                                     \
23169   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23170   "  [other-table <nn>]")                                               \
23171 _(get_node_index, "node <node-name")                                    \
23172 _(add_node_next, "node <node-name> next <next-node-name>")              \
23173 _(l2tpv3_create_tunnel,                                                 \
23174   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23175   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23176   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23177 _(l2tpv3_set_tunnel_cookies,                                            \
23178   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23179   "[new_remote_cookie <nn>]\n")                                         \
23180 _(l2tpv3_interface_enable_disable,                                      \
23181   "<intfc> | sw_if_index <nn> enable | disable")                        \
23182 _(l2tpv3_set_lookup_key,                                                \
23183   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23184 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23185 _(vxlan_offload_rx,                                                     \
23186   "hw { <interface name> | hw_if_index <nn>} "                          \
23187   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23188 _(vxlan_add_del_tunnel,                                                 \
23189   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23190   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23191   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23192 _(geneve_add_del_tunnel,                                                \
23193   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23194   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23195   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23196 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23197 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23198 _(gre_add_del_tunnel,                                                   \
23199   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23200   "[teb | erspan <session-id>] [del]")                                  \
23201 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23202 _(l2_fib_clear_table, "")                                               \
23203 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23204 _(l2_interface_vlan_tag_rewrite,                                        \
23205   "<intfc> | sw_if_index <nn> \n"                                       \
23206   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23207   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23208 _(create_vhost_user_if,                                                 \
23209         "socket <filename> [server] [renumber <dev_instance>] "         \
23210         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23211         "[mac <mac_address>]")                                          \
23212 _(modify_vhost_user_if,                                                 \
23213         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23214         "[server] [renumber <dev_instance>]")                           \
23215 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23216 _(sw_interface_vhost_user_dump, "")                                     \
23217 _(show_version, "")                                                     \
23218 _(show_threads, "")                                                     \
23219 _(vxlan_gpe_add_del_tunnel,                                             \
23220   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23221   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23222   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23223   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23224 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23225 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23226 _(interface_name_renumber,                                              \
23227   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23228 _(input_acl_set_interface,                                              \
23229   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23230   "  [l2-table <nn>] [del]")                                            \
23231 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23232 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23233   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23234 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23235 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23236 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23237 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23238 _(ip_dump, "ipv4 | ipv6")                                               \
23239 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23240 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23241   "  spid_id <n> ")                                                     \
23242 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23243   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23244   "  integ_alg <alg> integ_key <hex>")                                  \
23245 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23246   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23247   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23248   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23249 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23250 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23251   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23252   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23253   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23254   "  [instance <n>]")     \
23255 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23256 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23257   "  <alg> <hex>\n")                                                    \
23258 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23259 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23260 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23261   "(auth_data 0x<data> | auth_data <data>)")                            \
23262 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23263   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23264 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23265   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23266   "(local|remote)")                                                     \
23267 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23268 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23269 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23270 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23271 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23272 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23273 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23274 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23275 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23276 _(delete_loopback,"sw_if_index <nn>")                                   \
23277 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23278 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
23279 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
23280 _(want_interface_events,  "enable|disable")                             \
23281 _(get_first_msg_id, "client <name>")                                    \
23282 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23283 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23284   "fib-id <nn> [ip4][ip6][default]")                                    \
23285 _(get_node_graph, " ")                                                  \
23286 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23287 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23288 _(ioam_disable, "")                                                     \
23289 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23290                             " sw_if_index <sw_if_index> p <priority> "  \
23291                             "w <weight>] [del]")                        \
23292 _(one_add_del_locator, "locator-set <locator_name> "                    \
23293                         "iface <intf> | sw_if_index <sw_if_index> "     \
23294                         "p <priority> w <weight> [del]")                \
23295 _(one_add_del_local_eid,"vni <vni> eid "                                \
23296                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23297                          "locator-set <locator_name> [del]"             \
23298                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23299 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23300 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23301 _(one_enable_disable, "enable|disable")                                 \
23302 _(one_map_register_enable_disable, "enable|disable")                    \
23303 _(one_map_register_fallback_threshold, "<value>")                       \
23304 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23305 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23306                                "[seid <seid>] "                         \
23307                                "rloc <locator> p <prio> "               \
23308                                "w <weight> [rloc <loc> ... ] "          \
23309                                "action <action> [del-all]")             \
23310 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23311                           "<local-eid>")                                \
23312 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23313 _(one_use_petr, "ip-address> | disable")                                \
23314 _(one_map_request_mode, "src-dst|dst-only")                             \
23315 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23316 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23317 _(one_locator_set_dump, "[local | remote]")                             \
23318 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23319 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23320                        "[local] | [remote]")                            \
23321 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23322 _(one_ndp_bd_get, "")                                                   \
23323 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23324 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23325 _(one_l2_arp_bd_get, "")                                                \
23326 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23327 _(one_stats_enable_disable, "enable|disable")                           \
23328 _(show_one_stats_enable_disable, "")                                    \
23329 _(one_eid_table_vni_dump, "")                                           \
23330 _(one_eid_table_map_dump, "l2|l3")                                      \
23331 _(one_map_resolver_dump, "")                                            \
23332 _(one_map_server_dump, "")                                              \
23333 _(one_adjacencies_get, "vni <vni>")                                     \
23334 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23335 _(show_one_rloc_probe_state, "")                                        \
23336 _(show_one_map_register_state, "")                                      \
23337 _(show_one_status, "")                                                  \
23338 _(one_stats_dump, "")                                                   \
23339 _(one_stats_flush, "")                                                  \
23340 _(one_get_map_request_itr_rlocs, "")                                    \
23341 _(one_map_register_set_ttl, "<ttl>")                                    \
23342 _(one_set_transport_protocol, "udp|api")                                \
23343 _(one_get_transport_protocol, "")                                       \
23344 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23345 _(one_show_xtr_mode, "")                                                \
23346 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23347 _(one_show_pitr_mode, "")                                               \
23348 _(one_enable_disable_petr_mode, "enable|disable")                       \
23349 _(one_show_petr_mode, "")                                               \
23350 _(show_one_nsh_mapping, "")                                             \
23351 _(show_one_pitr, "")                                                    \
23352 _(show_one_use_petr, "")                                                \
23353 _(show_one_map_request_mode, "")                                        \
23354 _(show_one_map_register_ttl, "")                                        \
23355 _(show_one_map_register_fallback_threshold, "")                         \
23356 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23357                             " sw_if_index <sw_if_index> p <priority> "  \
23358                             "w <weight>] [del]")                        \
23359 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23360                         "iface <intf> | sw_if_index <sw_if_index> "     \
23361                         "p <priority> w <weight> [del]")                \
23362 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23363                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23364                          "locator-set <locator_name> [del]"             \
23365                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23366 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23367 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23368 _(lisp_enable_disable, "enable|disable")                                \
23369 _(lisp_map_register_enable_disable, "enable|disable")                   \
23370 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23371 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23372                                "[seid <seid>] "                         \
23373                                "rloc <locator> p <prio> "               \
23374                                "w <weight> [rloc <loc> ... ] "          \
23375                                "action <action> [del-all]")             \
23376 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23377                           "<local-eid>")                                \
23378 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23379 _(lisp_use_petr, "<ip-address> | disable")                              \
23380 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23381 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23382 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23383 _(lisp_locator_set_dump, "[local | remote]")                            \
23384 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23385 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23386                        "[local] | [remote]")                            \
23387 _(lisp_eid_table_vni_dump, "")                                          \
23388 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23389 _(lisp_map_resolver_dump, "")                                           \
23390 _(lisp_map_server_dump, "")                                             \
23391 _(lisp_adjacencies_get, "vni <vni>")                                    \
23392 _(gpe_fwd_entry_vnis_get, "")                                           \
23393 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23394 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23395                                 "[table <table-id>]")                   \
23396 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23397 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23398 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23399 _(gpe_get_encap_mode, "")                                               \
23400 _(lisp_gpe_add_del_iface, "up|down")                                    \
23401 _(lisp_gpe_enable_disable, "enable|disable")                            \
23402 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23403   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23404 _(show_lisp_rloc_probe_state, "")                                       \
23405 _(show_lisp_map_register_state, "")                                     \
23406 _(show_lisp_status, "")                                                 \
23407 _(lisp_get_map_request_itr_rlocs, "")                                   \
23408 _(show_lisp_pitr, "")                                                   \
23409 _(show_lisp_use_petr, "")                                               \
23410 _(show_lisp_map_request_mode, "")                                       \
23411 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23412 _(af_packet_delete, "name <host interface name>")                       \
23413 _(af_packet_dump, "")                                                   \
23414 _(policer_add_del, "name <policer name> <params> [del]")                \
23415 _(policer_dump, "[name <policer name>]")                                \
23416 _(policer_classify_set_interface,                                       \
23417   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23418   "  [l2-table <nn>] [del]")                                            \
23419 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23420 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23421     "[master|slave]")                                                   \
23422 _(netmap_delete, "name <interface name>")                               \
23423 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23424 _(mpls_fib_dump, "")                                                    \
23425 _(classify_table_ids, "")                                               \
23426 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23427 _(classify_table_info, "table_id <nn>")                                 \
23428 _(classify_session_dump, "table_id <nn>")                               \
23429 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23430     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23431     "[template_interval <nn>] [udp_checksum]")                          \
23432 _(ipfix_exporter_dump, "")                                              \
23433 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23434 _(ipfix_classify_stream_dump, "")                                       \
23435 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23436 _(ipfix_classify_table_dump, "")                                        \
23437 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23438 _(sw_interface_span_dump, "[l2]")                                           \
23439 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23440 _(pg_create_interface, "if_id <nn>")                                    \
23441 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23442 _(pg_enable_disable, "[stream <id>] disable")                           \
23443 _(ip_source_and_port_range_check_add_del,                               \
23444   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23445 _(ip_source_and_port_range_check_interface_add_del,                     \
23446   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23447   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23448 _(ipsec_gre_add_del_tunnel,                                             \
23449   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23450 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23451 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23452 _(l2_interface_pbb_tag_rewrite,                                         \
23453   "<intfc> | sw_if_index <nn> \n"                                       \
23454   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23455   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23456 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23457 _(flow_classify_set_interface,                                          \
23458   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23459 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23460 _(ip_fib_dump, "")                                                      \
23461 _(ip_mfib_dump, "")                                                     \
23462 _(ip6_fib_dump, "")                                                     \
23463 _(ip6_mfib_dump, "")                                                    \
23464 _(feature_enable_disable, "arc_name <arc_name> "                        \
23465   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23466 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23467 "[disable]")                                                            \
23468 _(l2_xconnect_dump, "")                                                 \
23469 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23470 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23471 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23472 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23473 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23474 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23475 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23476   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23477 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23478 _(sock_init_shm, "size <nnn>")                                          \
23479 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23480 _(dns_enable_disable, "[enable][disable]")                              \
23481 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23482 _(dns_resolve_name, "<hostname>")                                       \
23483 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23484 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23485 _(dns_resolve_name, "<hostname>")                                       \
23486 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23487   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23488 _(session_rules_dump, "")                                               \
23489 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23490 _(output_acl_set_interface,                                             \
23491   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23492   "  [l2-table <nn>] [del]")                                            \
23493 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23494
23495 /* List of command functions, CLI names map directly to functions */
23496 #define foreach_cli_function                                    \
23497 _(comment, "usage: comment <ignore-rest-of-line>")              \
23498 _(dump_interface_table, "usage: dump_interface_table")          \
23499 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23500 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23501 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23502 _(dump_macro_table, "usage: dump_macro_table ")                 \
23503 _(dump_node_table, "usage: dump_node_table")                    \
23504 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23505 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23506 _(echo, "usage: echo <message>")                                \
23507 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23508 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23509 _(help, "usage: help")                                          \
23510 _(q, "usage: quit")                                             \
23511 _(quit, "usage: quit")                                          \
23512 _(search_node_table, "usage: search_node_table <name>...")      \
23513 _(set, "usage: set <variable-name> <value>")                    \
23514 _(script, "usage: script <file-name>")                          \
23515 _(statseg, "usage: statseg");                                   \
23516 _(unset, "usage: unset <variable-name>")
23517
23518 #define _(N,n)                                  \
23519     static void vl_api_##n##_t_handler_uni      \
23520     (vl_api_##n##_t * mp)                       \
23521     {                                           \
23522         vat_main_t * vam = &vat_main;           \
23523         if (vam->json_output) {                 \
23524             vl_api_##n##_t_handler_json(mp);    \
23525         } else {                                \
23526             vl_api_##n##_t_handler(mp);         \
23527         }                                       \
23528     }
23529 foreach_vpe_api_reply_msg;
23530 #if VPP_API_TEST_BUILTIN == 0
23531 foreach_standalone_reply_msg;
23532 #endif
23533 #undef _
23534
23535 void
23536 vat_api_hookup (vat_main_t * vam)
23537 {
23538 #define _(N,n)                                                  \
23539     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23540                            vl_api_##n##_t_handler_uni,          \
23541                            vl_noop_handler,                     \
23542                            vl_api_##n##_t_endian,               \
23543                            vl_api_##n##_t_print,                \
23544                            sizeof(vl_api_##n##_t), 1);
23545   foreach_vpe_api_reply_msg;
23546 #if VPP_API_TEST_BUILTIN == 0
23547   foreach_standalone_reply_msg;
23548 #endif
23549 #undef _
23550
23551 #if (VPP_API_TEST_BUILTIN==0)
23552   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23553
23554   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23555
23556   vam->function_by_name = hash_create_string (0, sizeof (uword));
23557
23558   vam->help_by_name = hash_create_string (0, sizeof (uword));
23559 #endif
23560
23561   /* API messages we can send */
23562 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23563   foreach_vpe_api_msg;
23564 #undef _
23565
23566   /* Help strings */
23567 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23568   foreach_vpe_api_msg;
23569 #undef _
23570
23571   /* CLI functions */
23572 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23573   foreach_cli_function;
23574 #undef _
23575
23576   /* Help strings */
23577 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23578   foreach_cli_function;
23579 #undef _
23580 }
23581
23582 #if VPP_API_TEST_BUILTIN
23583 static clib_error_t *
23584 vat_api_hookup_shim (vlib_main_t * vm)
23585 {
23586   vat_api_hookup (&vat_main);
23587   return 0;
23588 }
23589
23590 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23591 #endif
23592
23593 /*
23594  * fd.io coding-style-patch-verification: ON
23595  *
23596  * Local Variables:
23597  * eval: (c-set-style "gnu")
23598  * End:
23599  */