sock api: allow to start client with no rx_thread
[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 u8 *
365 format_ipsec_crypto_alg (u8 * s, va_list * args)
366 {
367   u32 i = va_arg (*args, u32);
368   u8 *t = 0;
369
370   switch (i)
371     {
372 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
373       foreach_ipsec_crypto_alg
374 #undef _
375     default:
376       return format (s, "unknown");
377     }
378   return format (s, "%s", t);
379 }
380
381 u8 *
382 format_ipsec_integ_alg (u8 * s, va_list * args)
383 {
384   u32 i = va_arg (*args, u32);
385   u8 *t = 0;
386
387   switch (i)
388     {
389 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
390       foreach_ipsec_integ_alg
391 #undef _
392     default:
393       return format (s, "unknown");
394     }
395   return format (s, "%s", t);
396 }
397
398 uword
399 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
400 {
401   u32 *r = va_arg (*args, u32 *);
402
403   if (0);
404 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
405   foreach_ikev2_auth_method
406 #undef _
407     else
408     return 0;
409   return 1;
410 }
411
412 uword
413 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
414 {
415   u32 *r = va_arg (*args, u32 *);
416
417   if (0);
418 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
419   foreach_ikev2_id_type
420 #undef _
421     else
422     return 0;
423   return 1;
424 }
425 #else /* VPP_API_TEST_BUILTIN == 1 */
426 static uword
427 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
428 {
429   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
430   vnet_main_t *vnm = vnet_get_main ();
431   u32 *result = va_arg (*args, u32 *);
432
433   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
434 }
435
436 static uword
437 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
438 {
439   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
440   vnet_main_t *vnm = vnet_get_main ();
441   u32 *result = va_arg (*args, u32 *);
442
443   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
444 }
445
446 #endif /* VPP_API_TEST_BUILTIN */
447
448 uword
449 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
450 {
451   u32 *r = va_arg (*args, u32 *);
452
453   if (0);
454 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
455   foreach_ipsec_crypto_alg
456 #undef _
457     else
458     return 0;
459   return 1;
460 }
461
462 uword
463 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
464 {
465   u32 *r = va_arg (*args, u32 *);
466
467   if (0);
468 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
469   foreach_ipsec_integ_alg
470 #undef _
471     else
472     return 0;
473   return 1;
474 }
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_entry_add_del_reply)                        \
5212 _(ipsec_sad_entry_add_del_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_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5467 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_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_entry_add_del (vat_main_t * vam)
14833 {
14834   unformat_input_t *i = vam->input;
14835   vl_api_ipsec_spd_entry_add_del_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   vl_api_address_t laddr_start = { }, laddr_stop =
14842   {
14843   }, raddr_start =
14844   {
14845   }, raddr_stop =
14846   {
14847   };
14848   int ret;
14849
14850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14851     {
14852       if (unformat (i, "del"))
14853         is_add = 0;
14854       if (unformat (i, "outbound"))
14855         is_outbound = 1;
14856       if (unformat (i, "inbound"))
14857         is_outbound = 0;
14858       else if (unformat (i, "spd_id %d", &spd_id))
14859         ;
14860       else if (unformat (i, "sa_id %d", &sa_id))
14861         ;
14862       else if (unformat (i, "priority %d", &priority))
14863         ;
14864       else if (unformat (i, "protocol %d", &protocol))
14865         ;
14866       else if (unformat (i, "lport_start %d", &lport_start))
14867         ;
14868       else if (unformat (i, "lport_stop %d", &lport_stop))
14869         ;
14870       else if (unformat (i, "rport_start %d", &rport_start))
14871         ;
14872       else if (unformat (i, "rport_stop %d", &rport_stop))
14873         ;
14874       else if (unformat (i, "laddr_start %U",
14875                          unformat_vl_api_address, &laddr_start))
14876         is_ip_any = 0;
14877       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14878                          &laddr_stop))
14879         is_ip_any = 0;
14880       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14881                          &raddr_start))
14882         is_ip_any = 0;
14883       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14884                          &raddr_stop))
14885         is_ip_any = 0;
14886       else
14887         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14888         {
14889           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14890             {
14891               clib_warning ("unsupported action: 'resolve'");
14892               return -99;
14893             }
14894         }
14895       else
14896         {
14897           clib_warning ("parse error '%U'", format_unformat_error, i);
14898           return -99;
14899         }
14900
14901     }
14902
14903   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14904
14905   mp->is_add = is_add;
14906
14907   mp->entry.spd_id = ntohl (spd_id);
14908   mp->entry.priority = ntohl (priority);
14909   mp->entry.is_outbound = is_outbound;
14910
14911   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14912                sizeof (vl_api_address_t));
14913   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14914                sizeof (vl_api_address_t));
14915   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14916                sizeof (vl_api_address_t));
14917   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14918                sizeof (vl_api_address_t));
14919
14920   mp->entry.protocol = (u8) protocol;
14921   mp->entry.local_port_start = ntohs ((u16) lport_start);
14922   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14923   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14924   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14925   mp->entry.policy = (u8) policy;
14926   mp->entry.sa_id = ntohl (sa_id);
14927
14928   S (mp);
14929   W (ret);
14930   return ret;
14931 }
14932
14933 static int
14934 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14935 {
14936   unformat_input_t *i = vam->input;
14937   vl_api_ipsec_sad_entry_add_del_t *mp;
14938   u32 sad_id = 0, spi = 0;
14939   u8 *ck = 0, *ik = 0;
14940   u8 is_add = 1;
14941
14942   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14943   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14944   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14945   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14946   vl_api_address_t tun_src, tun_dst;
14947   int ret;
14948
14949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14950     {
14951       if (unformat (i, "del"))
14952         is_add = 0;
14953       else if (unformat (i, "sad_id %d", &sad_id))
14954         ;
14955       else if (unformat (i, "spi %d", &spi))
14956         ;
14957       else if (unformat (i, "esp"))
14958         protocol = IPSEC_API_PROTO_ESP;
14959       else
14960         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14961         {
14962           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14963           if (ADDRESS_IP6 == tun_src.af)
14964             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14965         }
14966       else
14967         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14968         {
14969           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14970           if (ADDRESS_IP6 == tun_src.af)
14971             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14972         }
14973       else
14974         if (unformat (i, "crypto_alg %U",
14975                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14976         ;
14977       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14978         ;
14979       else if (unformat (i, "integ_alg %U",
14980                          unformat_ipsec_api_integ_alg, &integ_alg))
14981         ;
14982       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14983         ;
14984       else
14985         {
14986           clib_warning ("parse error '%U'", format_unformat_error, i);
14987           return -99;
14988         }
14989
14990     }
14991
14992   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14993
14994   mp->is_add = is_add;
14995   mp->entry.sad_id = ntohl (sad_id);
14996   mp->entry.protocol = protocol;
14997   mp->entry.spi = ntohl (spi);
14998   mp->entry.flags = flags;
14999
15000   mp->entry.crypto_algorithm = crypto_alg;
15001   mp->entry.integrity_algorithm = integ_alg;
15002   mp->entry.crypto_key.length = vec_len (ck);
15003   mp->entry.integrity_key.length = vec_len (ik);
15004
15005   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
15006     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
15007
15008   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
15009     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
15010
15011   if (ck)
15012     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
15013   if (ik)
15014     clib_memcpy (mp->entry.integrity_key.data, ik,
15015                  mp->entry.integrity_key.length);
15016
15017   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
15018     {
15019       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
15020                    sizeof (mp->entry.tunnel_src));
15021       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
15022                    sizeof (mp->entry.tunnel_dst));
15023     }
15024
15025   S (mp);
15026   W (ret);
15027   return ret;
15028 }
15029
15030 static int
15031 api_ipsec_sa_set_key (vat_main_t * vam)
15032 {
15033   unformat_input_t *i = vam->input;
15034   vl_api_ipsec_sa_set_key_t *mp;
15035   u32 sa_id;
15036   u8 *ck = 0, *ik = 0;
15037   int ret;
15038
15039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15040     {
15041       if (unformat (i, "sa_id %d", &sa_id))
15042         ;
15043       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15044         ;
15045       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15046         ;
15047       else
15048         {
15049           clib_warning ("parse error '%U'", format_unformat_error, i);
15050           return -99;
15051         }
15052     }
15053
15054   M (IPSEC_SA_SET_KEY, mp);
15055
15056   mp->sa_id = ntohl (sa_id);
15057   mp->crypto_key.length = vec_len (ck);
15058   mp->integrity_key.length = vec_len (ik);
15059
15060   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15061     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15062
15063   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15064     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15065
15066   if (ck)
15067     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15068   if (ik)
15069     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15070
15071   S (mp);
15072   W (ret);
15073   return ret;
15074 }
15075
15076 static int
15077 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15078 {
15079   unformat_input_t *i = vam->input;
15080   vl_api_ipsec_tunnel_if_add_del_t *mp;
15081   u32 local_spi = 0, remote_spi = 0;
15082   u32 crypto_alg = 0, integ_alg = 0;
15083   u8 *lck = NULL, *rck = NULL;
15084   u8 *lik = NULL, *rik = NULL;
15085   ip4_address_t local_ip = { {0} };
15086   ip4_address_t remote_ip = { {0} };
15087   u8 is_add = 1;
15088   u8 esn = 0;
15089   u8 anti_replay = 0;
15090   u8 renumber = 0;
15091   u32 instance = ~0;
15092   int ret;
15093
15094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15095     {
15096       if (unformat (i, "del"))
15097         is_add = 0;
15098       else if (unformat (i, "esn"))
15099         esn = 1;
15100       else if (unformat (i, "anti_replay"))
15101         anti_replay = 1;
15102       else if (unformat (i, "local_spi %d", &local_spi))
15103         ;
15104       else if (unformat (i, "remote_spi %d", &remote_spi))
15105         ;
15106       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15107         ;
15108       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15109         ;
15110       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15111         ;
15112       else
15113         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15114         ;
15115       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15116         ;
15117       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15118         ;
15119       else
15120         if (unformat
15121             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15122         {
15123           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15124             {
15125               errmsg ("unsupported crypto-alg: '%U'\n",
15126                       format_ipsec_crypto_alg, crypto_alg);
15127               return -99;
15128             }
15129         }
15130       else
15131         if (unformat
15132             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15133         {
15134           if (integ_alg >= IPSEC_INTEG_N_ALG)
15135             {
15136               errmsg ("unsupported integ-alg: '%U'\n",
15137                       format_ipsec_integ_alg, integ_alg);
15138               return -99;
15139             }
15140         }
15141       else if (unformat (i, "instance %u", &instance))
15142         renumber = 1;
15143       else
15144         {
15145           errmsg ("parse error '%U'\n", format_unformat_error, i);
15146           return -99;
15147         }
15148     }
15149
15150   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15151
15152   mp->is_add = is_add;
15153   mp->esn = esn;
15154   mp->anti_replay = anti_replay;
15155
15156   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15157   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15158
15159   mp->local_spi = htonl (local_spi);
15160   mp->remote_spi = htonl (remote_spi);
15161   mp->crypto_alg = (u8) crypto_alg;
15162
15163   mp->local_crypto_key_len = 0;
15164   if (lck)
15165     {
15166       mp->local_crypto_key_len = vec_len (lck);
15167       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15168         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15169       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15170     }
15171
15172   mp->remote_crypto_key_len = 0;
15173   if (rck)
15174     {
15175       mp->remote_crypto_key_len = vec_len (rck);
15176       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15177         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15178       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15179     }
15180
15181   mp->integ_alg = (u8) integ_alg;
15182
15183   mp->local_integ_key_len = 0;
15184   if (lik)
15185     {
15186       mp->local_integ_key_len = vec_len (lik);
15187       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15188         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15189       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15190     }
15191
15192   mp->remote_integ_key_len = 0;
15193   if (rik)
15194     {
15195       mp->remote_integ_key_len = vec_len (rik);
15196       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15197         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15198       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15199     }
15200
15201   if (renumber)
15202     {
15203       mp->renumber = renumber;
15204       mp->show_instance = ntohl (instance);
15205     }
15206
15207   S (mp);
15208   W (ret);
15209   return ret;
15210 }
15211
15212 static void
15213 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15214 {
15215   vat_main_t *vam = &vat_main;
15216
15217   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15218          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15219          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15220          "tunnel_src_addr %U tunnel_dst_addr %U "
15221          "salt %u seq_outbound %lu last_seq_inbound %lu "
15222          "replay_window %lu total_data_size %lu\n",
15223          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15224          mp->protocol,
15225          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15226          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15227          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15228          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15229          mp->tunnel_src_addr,
15230          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15231          mp->tunnel_dst_addr,
15232          ntohl (mp->salt),
15233          clib_net_to_host_u64 (mp->seq_outbound),
15234          clib_net_to_host_u64 (mp->last_seq_inbound),
15235          clib_net_to_host_u64 (mp->replay_window),
15236          clib_net_to_host_u64 (mp->total_data_size));
15237 }
15238
15239 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15240 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15241
15242 static void vl_api_ipsec_sa_details_t_handler_json
15243   (vl_api_ipsec_sa_details_t * mp)
15244 {
15245   vat_main_t *vam = &vat_main;
15246   vat_json_node_t *node = NULL;
15247   struct in_addr src_ip4, dst_ip4;
15248   struct in6_addr src_ip6, dst_ip6;
15249
15250   if (VAT_JSON_ARRAY != vam->json_tree.type)
15251     {
15252       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15253       vat_json_init_array (&vam->json_tree);
15254     }
15255   node = vat_json_array_add (&vam->json_tree);
15256
15257   vat_json_init_object (node);
15258   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15259   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15260   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15261   vat_json_object_add_uint (node, "proto", mp->protocol);
15262   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15263   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15264   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15265   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15266   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15267   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15268   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15269                              mp->crypto_key_len);
15270   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15271                              mp->integ_key_len);
15272   if (mp->is_tunnel_ip6)
15273     {
15274       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15275       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15276       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15277       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15278     }
15279   else
15280     {
15281       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15282       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15283       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15284       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15285     }
15286   vat_json_object_add_uint (node, "replay_window",
15287                             clib_net_to_host_u64 (mp->replay_window));
15288   vat_json_object_add_uint (node, "total_data_size",
15289                             clib_net_to_host_u64 (mp->total_data_size));
15290
15291 }
15292
15293 static int
15294 api_ipsec_sa_dump (vat_main_t * vam)
15295 {
15296   unformat_input_t *i = vam->input;
15297   vl_api_ipsec_sa_dump_t *mp;
15298   vl_api_control_ping_t *mp_ping;
15299   u32 sa_id = ~0;
15300   int ret;
15301
15302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15303     {
15304       if (unformat (i, "sa_id %d", &sa_id))
15305         ;
15306       else
15307         {
15308           clib_warning ("parse error '%U'", format_unformat_error, i);
15309           return -99;
15310         }
15311     }
15312
15313   M (IPSEC_SA_DUMP, mp);
15314
15315   mp->sa_id = ntohl (sa_id);
15316
15317   S (mp);
15318
15319   /* Use a control ping for synchronization */
15320   M (CONTROL_PING, mp_ping);
15321   S (mp_ping);
15322
15323   W (ret);
15324   return ret;
15325 }
15326
15327 static int
15328 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15329 {
15330   unformat_input_t *i = vam->input;
15331   vl_api_ipsec_tunnel_if_set_key_t *mp;
15332   u32 sw_if_index = ~0;
15333   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15334   u8 *key = 0;
15335   u32 alg = ~0;
15336   int ret;
15337
15338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15339     {
15340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15341         ;
15342       else
15343         if (unformat
15344             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15345         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15346       else
15347         if (unformat
15348             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15349         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15350       else
15351         if (unformat
15352             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15353         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15354       else
15355         if (unformat
15356             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15357         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15358       else if (unformat (i, "%U", unformat_hex_string, &key))
15359         ;
15360       else
15361         {
15362           clib_warning ("parse error '%U'", format_unformat_error, i);
15363           return -99;
15364         }
15365     }
15366
15367   if (sw_if_index == ~0)
15368     {
15369       errmsg ("interface must be specified");
15370       return -99;
15371     }
15372
15373   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15374     {
15375       errmsg ("key type must be specified");
15376       return -99;
15377     }
15378
15379   if (alg == ~0)
15380     {
15381       errmsg ("algorithm must be specified");
15382       return -99;
15383     }
15384
15385   if (vec_len (key) == 0)
15386     {
15387       errmsg ("key must be specified");
15388       return -99;
15389     }
15390
15391   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15392
15393   mp->sw_if_index = htonl (sw_if_index);
15394   mp->alg = alg;
15395   mp->key_type = key_type;
15396   mp->key_len = vec_len (key);
15397   clib_memcpy (mp->key, key, vec_len (key));
15398
15399   S (mp);
15400   W (ret);
15401
15402   return ret;
15403 }
15404
15405 static int
15406 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15407 {
15408   unformat_input_t *i = vam->input;
15409   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15410   u32 sw_if_index = ~0;
15411   u32 sa_id = ~0;
15412   u8 is_outbound = (u8) ~ 0;
15413   int ret;
15414
15415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15416     {
15417       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15418         ;
15419       else if (unformat (i, "sa_id %d", &sa_id))
15420         ;
15421       else if (unformat (i, "outbound"))
15422         is_outbound = 1;
15423       else if (unformat (i, "inbound"))
15424         is_outbound = 0;
15425       else
15426         {
15427           clib_warning ("parse error '%U'", format_unformat_error, i);
15428           return -99;
15429         }
15430     }
15431
15432   if (sw_if_index == ~0)
15433     {
15434       errmsg ("interface must be specified");
15435       return -99;
15436     }
15437
15438   if (sa_id == ~0)
15439     {
15440       errmsg ("SA ID must be specified");
15441       return -99;
15442     }
15443
15444   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15445
15446   mp->sw_if_index = htonl (sw_if_index);
15447   mp->sa_id = htonl (sa_id);
15448   mp->is_outbound = is_outbound;
15449
15450   S (mp);
15451   W (ret);
15452
15453   return ret;
15454 }
15455
15456 static int
15457 api_ikev2_profile_add_del (vat_main_t * vam)
15458 {
15459   unformat_input_t *i = vam->input;
15460   vl_api_ikev2_profile_add_del_t *mp;
15461   u8 is_add = 1;
15462   u8 *name = 0;
15463   int ret;
15464
15465   const char *valid_chars = "a-zA-Z0-9_";
15466
15467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15468     {
15469       if (unformat (i, "del"))
15470         is_add = 0;
15471       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15472         vec_add1 (name, 0);
15473       else
15474         {
15475           errmsg ("parse error '%U'", format_unformat_error, i);
15476           return -99;
15477         }
15478     }
15479
15480   if (!vec_len (name))
15481     {
15482       errmsg ("profile name must be specified");
15483       return -99;
15484     }
15485
15486   if (vec_len (name) > 64)
15487     {
15488       errmsg ("profile name too long");
15489       return -99;
15490     }
15491
15492   M (IKEV2_PROFILE_ADD_DEL, mp);
15493
15494   clib_memcpy (mp->name, name, vec_len (name));
15495   mp->is_add = is_add;
15496   vec_free (name);
15497
15498   S (mp);
15499   W (ret);
15500   return ret;
15501 }
15502
15503 static int
15504 api_ikev2_profile_set_auth (vat_main_t * vam)
15505 {
15506   unformat_input_t *i = vam->input;
15507   vl_api_ikev2_profile_set_auth_t *mp;
15508   u8 *name = 0;
15509   u8 *data = 0;
15510   u32 auth_method = 0;
15511   u8 is_hex = 0;
15512   int ret;
15513
15514   const char *valid_chars = "a-zA-Z0-9_";
15515
15516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15517     {
15518       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15519         vec_add1 (name, 0);
15520       else if (unformat (i, "auth_method %U",
15521                          unformat_ikev2_auth_method, &auth_method))
15522         ;
15523       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15524         is_hex = 1;
15525       else if (unformat (i, "auth_data %v", &data))
15526         ;
15527       else
15528         {
15529           errmsg ("parse error '%U'", format_unformat_error, i);
15530           return -99;
15531         }
15532     }
15533
15534   if (!vec_len (name))
15535     {
15536       errmsg ("profile name must be specified");
15537       return -99;
15538     }
15539
15540   if (vec_len (name) > 64)
15541     {
15542       errmsg ("profile name too long");
15543       return -99;
15544     }
15545
15546   if (!vec_len (data))
15547     {
15548       errmsg ("auth_data must be specified");
15549       return -99;
15550     }
15551
15552   if (!auth_method)
15553     {
15554       errmsg ("auth_method must be specified");
15555       return -99;
15556     }
15557
15558   M (IKEV2_PROFILE_SET_AUTH, mp);
15559
15560   mp->is_hex = is_hex;
15561   mp->auth_method = (u8) auth_method;
15562   mp->data_len = vec_len (data);
15563   clib_memcpy (mp->name, name, vec_len (name));
15564   clib_memcpy (mp->data, data, vec_len (data));
15565   vec_free (name);
15566   vec_free (data);
15567
15568   S (mp);
15569   W (ret);
15570   return ret;
15571 }
15572
15573 static int
15574 api_ikev2_profile_set_id (vat_main_t * vam)
15575 {
15576   unformat_input_t *i = vam->input;
15577   vl_api_ikev2_profile_set_id_t *mp;
15578   u8 *name = 0;
15579   u8 *data = 0;
15580   u8 is_local = 0;
15581   u32 id_type = 0;
15582   ip4_address_t ip4;
15583   int ret;
15584
15585   const char *valid_chars = "a-zA-Z0-9_";
15586
15587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15588     {
15589       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15590         vec_add1 (name, 0);
15591       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15592         ;
15593       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15594         {
15595           data = vec_new (u8, 4);
15596           clib_memcpy (data, ip4.as_u8, 4);
15597         }
15598       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15599         ;
15600       else if (unformat (i, "id_data %v", &data))
15601         ;
15602       else if (unformat (i, "local"))
15603         is_local = 1;
15604       else if (unformat (i, "remote"))
15605         is_local = 0;
15606       else
15607         {
15608           errmsg ("parse error '%U'", format_unformat_error, i);
15609           return -99;
15610         }
15611     }
15612
15613   if (!vec_len (name))
15614     {
15615       errmsg ("profile name must be specified");
15616       return -99;
15617     }
15618
15619   if (vec_len (name) > 64)
15620     {
15621       errmsg ("profile name too long");
15622       return -99;
15623     }
15624
15625   if (!vec_len (data))
15626     {
15627       errmsg ("id_data must be specified");
15628       return -99;
15629     }
15630
15631   if (!id_type)
15632     {
15633       errmsg ("id_type must be specified");
15634       return -99;
15635     }
15636
15637   M (IKEV2_PROFILE_SET_ID, mp);
15638
15639   mp->is_local = is_local;
15640   mp->id_type = (u8) id_type;
15641   mp->data_len = vec_len (data);
15642   clib_memcpy (mp->name, name, vec_len (name));
15643   clib_memcpy (mp->data, data, vec_len (data));
15644   vec_free (name);
15645   vec_free (data);
15646
15647   S (mp);
15648   W (ret);
15649   return ret;
15650 }
15651
15652 static int
15653 api_ikev2_profile_set_ts (vat_main_t * vam)
15654 {
15655   unformat_input_t *i = vam->input;
15656   vl_api_ikev2_profile_set_ts_t *mp;
15657   u8 *name = 0;
15658   u8 is_local = 0;
15659   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15660   ip4_address_t start_addr, end_addr;
15661
15662   const char *valid_chars = "a-zA-Z0-9_";
15663   int ret;
15664
15665   start_addr.as_u32 = 0;
15666   end_addr.as_u32 = (u32) ~ 0;
15667
15668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15669     {
15670       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15671         vec_add1 (name, 0);
15672       else if (unformat (i, "protocol %d", &proto))
15673         ;
15674       else if (unformat (i, "start_port %d", &start_port))
15675         ;
15676       else if (unformat (i, "end_port %d", &end_port))
15677         ;
15678       else
15679         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15680         ;
15681       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15682         ;
15683       else if (unformat (i, "local"))
15684         is_local = 1;
15685       else if (unformat (i, "remote"))
15686         is_local = 0;
15687       else
15688         {
15689           errmsg ("parse error '%U'", format_unformat_error, i);
15690           return -99;
15691         }
15692     }
15693
15694   if (!vec_len (name))
15695     {
15696       errmsg ("profile name must be specified");
15697       return -99;
15698     }
15699
15700   if (vec_len (name) > 64)
15701     {
15702       errmsg ("profile name too long");
15703       return -99;
15704     }
15705
15706   M (IKEV2_PROFILE_SET_TS, mp);
15707
15708   mp->is_local = is_local;
15709   mp->proto = (u8) proto;
15710   mp->start_port = (u16) start_port;
15711   mp->end_port = (u16) end_port;
15712   mp->start_addr = start_addr.as_u32;
15713   mp->end_addr = end_addr.as_u32;
15714   clib_memcpy (mp->name, name, vec_len (name));
15715   vec_free (name);
15716
15717   S (mp);
15718   W (ret);
15719   return ret;
15720 }
15721
15722 static int
15723 api_ikev2_set_local_key (vat_main_t * vam)
15724 {
15725   unformat_input_t *i = vam->input;
15726   vl_api_ikev2_set_local_key_t *mp;
15727   u8 *file = 0;
15728   int ret;
15729
15730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15731     {
15732       if (unformat (i, "file %v", &file))
15733         vec_add1 (file, 0);
15734       else
15735         {
15736           errmsg ("parse error '%U'", format_unformat_error, i);
15737           return -99;
15738         }
15739     }
15740
15741   if (!vec_len (file))
15742     {
15743       errmsg ("RSA key file must be specified");
15744       return -99;
15745     }
15746
15747   if (vec_len (file) > 256)
15748     {
15749       errmsg ("file name too long");
15750       return -99;
15751     }
15752
15753   M (IKEV2_SET_LOCAL_KEY, mp);
15754
15755   clib_memcpy (mp->key_file, file, vec_len (file));
15756   vec_free (file);
15757
15758   S (mp);
15759   W (ret);
15760   return ret;
15761 }
15762
15763 static int
15764 api_ikev2_set_responder (vat_main_t * vam)
15765 {
15766   unformat_input_t *i = vam->input;
15767   vl_api_ikev2_set_responder_t *mp;
15768   int ret;
15769   u8 *name = 0;
15770   u32 sw_if_index = ~0;
15771   ip4_address_t address;
15772
15773   const char *valid_chars = "a-zA-Z0-9_";
15774
15775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15776     {
15777       if (unformat
15778           (i, "%U interface %d address %U", unformat_token, valid_chars,
15779            &name, &sw_if_index, unformat_ip4_address, &address))
15780         vec_add1 (name, 0);
15781       else
15782         {
15783           errmsg ("parse error '%U'", format_unformat_error, i);
15784           return -99;
15785         }
15786     }
15787
15788   if (!vec_len (name))
15789     {
15790       errmsg ("profile name must be specified");
15791       return -99;
15792     }
15793
15794   if (vec_len (name) > 64)
15795     {
15796       errmsg ("profile name too long");
15797       return -99;
15798     }
15799
15800   M (IKEV2_SET_RESPONDER, mp);
15801
15802   clib_memcpy (mp->name, name, vec_len (name));
15803   vec_free (name);
15804
15805   mp->sw_if_index = sw_if_index;
15806   clib_memcpy (mp->address, &address, sizeof (address));
15807
15808   S (mp);
15809   W (ret);
15810   return ret;
15811 }
15812
15813 static int
15814 api_ikev2_set_ike_transforms (vat_main_t * vam)
15815 {
15816   unformat_input_t *i = vam->input;
15817   vl_api_ikev2_set_ike_transforms_t *mp;
15818   int ret;
15819   u8 *name = 0;
15820   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15821
15822   const char *valid_chars = "a-zA-Z0-9_";
15823
15824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15825     {
15826       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15827                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15828         vec_add1 (name, 0);
15829       else
15830         {
15831           errmsg ("parse error '%U'", format_unformat_error, i);
15832           return -99;
15833         }
15834     }
15835
15836   if (!vec_len (name))
15837     {
15838       errmsg ("profile name must be specified");
15839       return -99;
15840     }
15841
15842   if (vec_len (name) > 64)
15843     {
15844       errmsg ("profile name too long");
15845       return -99;
15846     }
15847
15848   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15849
15850   clib_memcpy (mp->name, name, vec_len (name));
15851   vec_free (name);
15852   mp->crypto_alg = crypto_alg;
15853   mp->crypto_key_size = crypto_key_size;
15854   mp->integ_alg = integ_alg;
15855   mp->dh_group = dh_group;
15856
15857   S (mp);
15858   W (ret);
15859   return ret;
15860 }
15861
15862
15863 static int
15864 api_ikev2_set_esp_transforms (vat_main_t * vam)
15865 {
15866   unformat_input_t *i = vam->input;
15867   vl_api_ikev2_set_esp_transforms_t *mp;
15868   int ret;
15869   u8 *name = 0;
15870   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15871
15872   const char *valid_chars = "a-zA-Z0-9_";
15873
15874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15875     {
15876       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15877                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15878         vec_add1 (name, 0);
15879       else
15880         {
15881           errmsg ("parse error '%U'", format_unformat_error, i);
15882           return -99;
15883         }
15884     }
15885
15886   if (!vec_len (name))
15887     {
15888       errmsg ("profile name must be specified");
15889       return -99;
15890     }
15891
15892   if (vec_len (name) > 64)
15893     {
15894       errmsg ("profile name too long");
15895       return -99;
15896     }
15897
15898   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15899
15900   clib_memcpy (mp->name, name, vec_len (name));
15901   vec_free (name);
15902   mp->crypto_alg = crypto_alg;
15903   mp->crypto_key_size = crypto_key_size;
15904   mp->integ_alg = integ_alg;
15905   mp->dh_group = dh_group;
15906
15907   S (mp);
15908   W (ret);
15909   return ret;
15910 }
15911
15912 static int
15913 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15914 {
15915   unformat_input_t *i = vam->input;
15916   vl_api_ikev2_set_sa_lifetime_t *mp;
15917   int ret;
15918   u8 *name = 0;
15919   u64 lifetime, lifetime_maxdata;
15920   u32 lifetime_jitter, handover;
15921
15922   const char *valid_chars = "a-zA-Z0-9_";
15923
15924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15925     {
15926       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15927                     &lifetime, &lifetime_jitter, &handover,
15928                     &lifetime_maxdata))
15929         vec_add1 (name, 0);
15930       else
15931         {
15932           errmsg ("parse error '%U'", format_unformat_error, i);
15933           return -99;
15934         }
15935     }
15936
15937   if (!vec_len (name))
15938     {
15939       errmsg ("profile name must be specified");
15940       return -99;
15941     }
15942
15943   if (vec_len (name) > 64)
15944     {
15945       errmsg ("profile name too long");
15946       return -99;
15947     }
15948
15949   M (IKEV2_SET_SA_LIFETIME, mp);
15950
15951   clib_memcpy (mp->name, name, vec_len (name));
15952   vec_free (name);
15953   mp->lifetime = lifetime;
15954   mp->lifetime_jitter = lifetime_jitter;
15955   mp->handover = handover;
15956   mp->lifetime_maxdata = lifetime_maxdata;
15957
15958   S (mp);
15959   W (ret);
15960   return ret;
15961 }
15962
15963 static int
15964 api_ikev2_initiate_sa_init (vat_main_t * vam)
15965 {
15966   unformat_input_t *i = vam->input;
15967   vl_api_ikev2_initiate_sa_init_t *mp;
15968   int ret;
15969   u8 *name = 0;
15970
15971   const char *valid_chars = "a-zA-Z0-9_";
15972
15973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15974     {
15975       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15976         vec_add1 (name, 0);
15977       else
15978         {
15979           errmsg ("parse error '%U'", format_unformat_error, i);
15980           return -99;
15981         }
15982     }
15983
15984   if (!vec_len (name))
15985     {
15986       errmsg ("profile name must be specified");
15987       return -99;
15988     }
15989
15990   if (vec_len (name) > 64)
15991     {
15992       errmsg ("profile name too long");
15993       return -99;
15994     }
15995
15996   M (IKEV2_INITIATE_SA_INIT, mp);
15997
15998   clib_memcpy (mp->name, name, vec_len (name));
15999   vec_free (name);
16000
16001   S (mp);
16002   W (ret);
16003   return ret;
16004 }
16005
16006 static int
16007 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16008 {
16009   unformat_input_t *i = vam->input;
16010   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16011   int ret;
16012   u64 ispi;
16013
16014
16015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16016     {
16017       if (unformat (i, "%lx", &ispi))
16018         ;
16019       else
16020         {
16021           errmsg ("parse error '%U'", format_unformat_error, i);
16022           return -99;
16023         }
16024     }
16025
16026   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16027
16028   mp->ispi = ispi;
16029
16030   S (mp);
16031   W (ret);
16032   return ret;
16033 }
16034
16035 static int
16036 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16037 {
16038   unformat_input_t *i = vam->input;
16039   vl_api_ikev2_initiate_del_child_sa_t *mp;
16040   int ret;
16041   u32 ispi;
16042
16043
16044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16045     {
16046       if (unformat (i, "%x", &ispi))
16047         ;
16048       else
16049         {
16050           errmsg ("parse error '%U'", format_unformat_error, i);
16051           return -99;
16052         }
16053     }
16054
16055   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16056
16057   mp->ispi = ispi;
16058
16059   S (mp);
16060   W (ret);
16061   return ret;
16062 }
16063
16064 static int
16065 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16066 {
16067   unformat_input_t *i = vam->input;
16068   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16069   int ret;
16070   u32 ispi;
16071
16072
16073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16074     {
16075       if (unformat (i, "%x", &ispi))
16076         ;
16077       else
16078         {
16079           errmsg ("parse error '%U'", format_unformat_error, i);
16080           return -99;
16081         }
16082     }
16083
16084   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16085
16086   mp->ispi = ispi;
16087
16088   S (mp);
16089   W (ret);
16090   return ret;
16091 }
16092
16093 static int
16094 api_get_first_msg_id (vat_main_t * vam)
16095 {
16096   vl_api_get_first_msg_id_t *mp;
16097   unformat_input_t *i = vam->input;
16098   u8 *name;
16099   u8 name_set = 0;
16100   int ret;
16101
16102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16103     {
16104       if (unformat (i, "client %s", &name))
16105         name_set = 1;
16106       else
16107         break;
16108     }
16109
16110   if (name_set == 0)
16111     {
16112       errmsg ("missing client name");
16113       return -99;
16114     }
16115   vec_add1 (name, 0);
16116
16117   if (vec_len (name) > 63)
16118     {
16119       errmsg ("client name too long");
16120       return -99;
16121     }
16122
16123   M (GET_FIRST_MSG_ID, mp);
16124   clib_memcpy (mp->name, name, vec_len (name));
16125   S (mp);
16126   W (ret);
16127   return ret;
16128 }
16129
16130 static int
16131 api_cop_interface_enable_disable (vat_main_t * vam)
16132 {
16133   unformat_input_t *line_input = vam->input;
16134   vl_api_cop_interface_enable_disable_t *mp;
16135   u32 sw_if_index = ~0;
16136   u8 enable_disable = 1;
16137   int ret;
16138
16139   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16140     {
16141       if (unformat (line_input, "disable"))
16142         enable_disable = 0;
16143       if (unformat (line_input, "enable"))
16144         enable_disable = 1;
16145       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16146                          vam, &sw_if_index))
16147         ;
16148       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16149         ;
16150       else
16151         break;
16152     }
16153
16154   if (sw_if_index == ~0)
16155     {
16156       errmsg ("missing interface name or sw_if_index");
16157       return -99;
16158     }
16159
16160   /* Construct the API message */
16161   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16162   mp->sw_if_index = ntohl (sw_if_index);
16163   mp->enable_disable = enable_disable;
16164
16165   /* send it... */
16166   S (mp);
16167   /* Wait for the reply */
16168   W (ret);
16169   return ret;
16170 }
16171
16172 static int
16173 api_cop_whitelist_enable_disable (vat_main_t * vam)
16174 {
16175   unformat_input_t *line_input = vam->input;
16176   vl_api_cop_whitelist_enable_disable_t *mp;
16177   u32 sw_if_index = ~0;
16178   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16179   u32 fib_id = 0;
16180   int ret;
16181
16182   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16183     {
16184       if (unformat (line_input, "ip4"))
16185         ip4 = 1;
16186       else if (unformat (line_input, "ip6"))
16187         ip6 = 1;
16188       else if (unformat (line_input, "default"))
16189         default_cop = 1;
16190       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16191                          vam, &sw_if_index))
16192         ;
16193       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16194         ;
16195       else if (unformat (line_input, "fib-id %d", &fib_id))
16196         ;
16197       else
16198         break;
16199     }
16200
16201   if (sw_if_index == ~0)
16202     {
16203       errmsg ("missing interface name or sw_if_index");
16204       return -99;
16205     }
16206
16207   /* Construct the API message */
16208   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16209   mp->sw_if_index = ntohl (sw_if_index);
16210   mp->fib_id = ntohl (fib_id);
16211   mp->ip4 = ip4;
16212   mp->ip6 = ip6;
16213   mp->default_cop = default_cop;
16214
16215   /* send it... */
16216   S (mp);
16217   /* Wait for the reply */
16218   W (ret);
16219   return ret;
16220 }
16221
16222 static int
16223 api_get_node_graph (vat_main_t * vam)
16224 {
16225   vl_api_get_node_graph_t *mp;
16226   int ret;
16227
16228   M (GET_NODE_GRAPH, mp);
16229
16230   /* send it... */
16231   S (mp);
16232   /* Wait for the reply */
16233   W (ret);
16234   return ret;
16235 }
16236
16237 /* *INDENT-OFF* */
16238 /** Used for parsing LISP eids */
16239 typedef CLIB_PACKED(struct{
16240   u8 addr[16];   /**< eid address */
16241   u32 len;       /**< prefix length if IP */
16242   u8 type;      /**< type of eid */
16243 }) lisp_eid_vat_t;
16244 /* *INDENT-ON* */
16245
16246 static uword
16247 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16248 {
16249   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16250
16251   clib_memset (a, 0, sizeof (a[0]));
16252
16253   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16254     {
16255       a->type = 0;              /* ipv4 type */
16256     }
16257   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16258     {
16259       a->type = 1;              /* ipv6 type */
16260     }
16261   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16262     {
16263       a->type = 2;              /* mac type */
16264     }
16265   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16266     {
16267       a->type = 3;              /* NSH type */
16268       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16269       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16270     }
16271   else
16272     {
16273       return 0;
16274     }
16275
16276   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16277     {
16278       return 0;
16279     }
16280
16281   return 1;
16282 }
16283
16284 static int
16285 lisp_eid_size_vat (u8 type)
16286 {
16287   switch (type)
16288     {
16289     case 0:
16290       return 4;
16291     case 1:
16292       return 16;
16293     case 2:
16294       return 6;
16295     case 3:
16296       return 5;
16297     }
16298   return 0;
16299 }
16300
16301 static void
16302 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16303 {
16304   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16305 }
16306
16307 static int
16308 api_one_add_del_locator_set (vat_main_t * vam)
16309 {
16310   unformat_input_t *input = vam->input;
16311   vl_api_one_add_del_locator_set_t *mp;
16312   u8 is_add = 1;
16313   u8 *locator_set_name = NULL;
16314   u8 locator_set_name_set = 0;
16315   vl_api_local_locator_t locator, *locators = 0;
16316   u32 sw_if_index, priority, weight;
16317   u32 data_len = 0;
16318
16319   int ret;
16320   /* Parse args required to build the message */
16321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16322     {
16323       if (unformat (input, "del"))
16324         {
16325           is_add = 0;
16326         }
16327       else if (unformat (input, "locator-set %s", &locator_set_name))
16328         {
16329           locator_set_name_set = 1;
16330         }
16331       else if (unformat (input, "sw_if_index %u p %u w %u",
16332                          &sw_if_index, &priority, &weight))
16333         {
16334           locator.sw_if_index = htonl (sw_if_index);
16335           locator.priority = priority;
16336           locator.weight = weight;
16337           vec_add1 (locators, locator);
16338         }
16339       else
16340         if (unformat
16341             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16342              &sw_if_index, &priority, &weight))
16343         {
16344           locator.sw_if_index = htonl (sw_if_index);
16345           locator.priority = priority;
16346           locator.weight = weight;
16347           vec_add1 (locators, locator);
16348         }
16349       else
16350         break;
16351     }
16352
16353   if (locator_set_name_set == 0)
16354     {
16355       errmsg ("missing locator-set name");
16356       vec_free (locators);
16357       return -99;
16358     }
16359
16360   if (vec_len (locator_set_name) > 64)
16361     {
16362       errmsg ("locator-set name too long");
16363       vec_free (locator_set_name);
16364       vec_free (locators);
16365       return -99;
16366     }
16367   vec_add1 (locator_set_name, 0);
16368
16369   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16370
16371   /* Construct the API message */
16372   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16373
16374   mp->is_add = is_add;
16375   clib_memcpy (mp->locator_set_name, locator_set_name,
16376                vec_len (locator_set_name));
16377   vec_free (locator_set_name);
16378
16379   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16380   if (locators)
16381     clib_memcpy (mp->locators, locators, data_len);
16382   vec_free (locators);
16383
16384   /* send it... */
16385   S (mp);
16386
16387   /* Wait for a reply... */
16388   W (ret);
16389   return ret;
16390 }
16391
16392 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16393
16394 static int
16395 api_one_add_del_locator (vat_main_t * vam)
16396 {
16397   unformat_input_t *input = vam->input;
16398   vl_api_one_add_del_locator_t *mp;
16399   u32 tmp_if_index = ~0;
16400   u32 sw_if_index = ~0;
16401   u8 sw_if_index_set = 0;
16402   u8 sw_if_index_if_name_set = 0;
16403   u32 priority = ~0;
16404   u8 priority_set = 0;
16405   u32 weight = ~0;
16406   u8 weight_set = 0;
16407   u8 is_add = 1;
16408   u8 *locator_set_name = NULL;
16409   u8 locator_set_name_set = 0;
16410   int ret;
16411
16412   /* Parse args required to build the message */
16413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16414     {
16415       if (unformat (input, "del"))
16416         {
16417           is_add = 0;
16418         }
16419       else if (unformat (input, "locator-set %s", &locator_set_name))
16420         {
16421           locator_set_name_set = 1;
16422         }
16423       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16424                          &tmp_if_index))
16425         {
16426           sw_if_index_if_name_set = 1;
16427           sw_if_index = tmp_if_index;
16428         }
16429       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16430         {
16431           sw_if_index_set = 1;
16432           sw_if_index = tmp_if_index;
16433         }
16434       else if (unformat (input, "p %d", &priority))
16435         {
16436           priority_set = 1;
16437         }
16438       else if (unformat (input, "w %d", &weight))
16439         {
16440           weight_set = 1;
16441         }
16442       else
16443         break;
16444     }
16445
16446   if (locator_set_name_set == 0)
16447     {
16448       errmsg ("missing locator-set name");
16449       return -99;
16450     }
16451
16452   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16453     {
16454       errmsg ("missing sw_if_index");
16455       vec_free (locator_set_name);
16456       return -99;
16457     }
16458
16459   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16460     {
16461       errmsg ("cannot use both params interface name and sw_if_index");
16462       vec_free (locator_set_name);
16463       return -99;
16464     }
16465
16466   if (priority_set == 0)
16467     {
16468       errmsg ("missing locator-set priority");
16469       vec_free (locator_set_name);
16470       return -99;
16471     }
16472
16473   if (weight_set == 0)
16474     {
16475       errmsg ("missing locator-set weight");
16476       vec_free (locator_set_name);
16477       return -99;
16478     }
16479
16480   if (vec_len (locator_set_name) > 64)
16481     {
16482       errmsg ("locator-set name too long");
16483       vec_free (locator_set_name);
16484       return -99;
16485     }
16486   vec_add1 (locator_set_name, 0);
16487
16488   /* Construct the API message */
16489   M (ONE_ADD_DEL_LOCATOR, mp);
16490
16491   mp->is_add = is_add;
16492   mp->sw_if_index = ntohl (sw_if_index);
16493   mp->priority = priority;
16494   mp->weight = weight;
16495   clib_memcpy (mp->locator_set_name, locator_set_name,
16496                vec_len (locator_set_name));
16497   vec_free (locator_set_name);
16498
16499   /* send it... */
16500   S (mp);
16501
16502   /* Wait for a reply... */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 #define api_lisp_add_del_locator api_one_add_del_locator
16508
16509 uword
16510 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16511 {
16512   u32 *key_id = va_arg (*args, u32 *);
16513   u8 *s = 0;
16514
16515   if (unformat (input, "%s", &s))
16516     {
16517       if (!strcmp ((char *) s, "sha1"))
16518         key_id[0] = HMAC_SHA_1_96;
16519       else if (!strcmp ((char *) s, "sha256"))
16520         key_id[0] = HMAC_SHA_256_128;
16521       else
16522         {
16523           clib_warning ("invalid key_id: '%s'", s);
16524           key_id[0] = HMAC_NO_KEY;
16525         }
16526     }
16527   else
16528     return 0;
16529
16530   vec_free (s);
16531   return 1;
16532 }
16533
16534 static int
16535 api_one_add_del_local_eid (vat_main_t * vam)
16536 {
16537   unformat_input_t *input = vam->input;
16538   vl_api_one_add_del_local_eid_t *mp;
16539   u8 is_add = 1;
16540   u8 eid_set = 0;
16541   lisp_eid_vat_t _eid, *eid = &_eid;
16542   u8 *locator_set_name = 0;
16543   u8 locator_set_name_set = 0;
16544   u32 vni = 0;
16545   u16 key_id = 0;
16546   u8 *key = 0;
16547   int ret;
16548
16549   /* Parse args required to build the message */
16550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16551     {
16552       if (unformat (input, "del"))
16553         {
16554           is_add = 0;
16555         }
16556       else if (unformat (input, "vni %d", &vni))
16557         {
16558           ;
16559         }
16560       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16561         {
16562           eid_set = 1;
16563         }
16564       else if (unformat (input, "locator-set %s", &locator_set_name))
16565         {
16566           locator_set_name_set = 1;
16567         }
16568       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16569         ;
16570       else if (unformat (input, "secret-key %_%v%_", &key))
16571         ;
16572       else
16573         break;
16574     }
16575
16576   if (locator_set_name_set == 0)
16577     {
16578       errmsg ("missing locator-set name");
16579       return -99;
16580     }
16581
16582   if (0 == eid_set)
16583     {
16584       errmsg ("EID address not set!");
16585       vec_free (locator_set_name);
16586       return -99;
16587     }
16588
16589   if (key && (0 == key_id))
16590     {
16591       errmsg ("invalid key_id!");
16592       return -99;
16593     }
16594
16595   if (vec_len (key) > 64)
16596     {
16597       errmsg ("key too long");
16598       vec_free (key);
16599       return -99;
16600     }
16601
16602   if (vec_len (locator_set_name) > 64)
16603     {
16604       errmsg ("locator-set name too long");
16605       vec_free (locator_set_name);
16606       return -99;
16607     }
16608   vec_add1 (locator_set_name, 0);
16609
16610   /* Construct the API message */
16611   M (ONE_ADD_DEL_LOCAL_EID, mp);
16612
16613   mp->is_add = is_add;
16614   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16615   mp->eid_type = eid->type;
16616   mp->prefix_len = eid->len;
16617   mp->vni = clib_host_to_net_u32 (vni);
16618   mp->key_id = clib_host_to_net_u16 (key_id);
16619   clib_memcpy (mp->locator_set_name, locator_set_name,
16620                vec_len (locator_set_name));
16621   clib_memcpy (mp->key, key, vec_len (key));
16622
16623   vec_free (locator_set_name);
16624   vec_free (key);
16625
16626   /* send it... */
16627   S (mp);
16628
16629   /* Wait for a reply... */
16630   W (ret);
16631   return ret;
16632 }
16633
16634 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16635
16636 static int
16637 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16638 {
16639   u32 dp_table = 0, vni = 0;;
16640   unformat_input_t *input = vam->input;
16641   vl_api_gpe_add_del_fwd_entry_t *mp;
16642   u8 is_add = 1;
16643   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16644   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16645   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16646   u32 action = ~0, w;
16647   ip4_address_t rmt_rloc4, lcl_rloc4;
16648   ip6_address_t rmt_rloc6, lcl_rloc6;
16649   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16650   int ret;
16651
16652   clib_memset (&rloc, 0, sizeof (rloc));
16653
16654   /* Parse args required to build the message */
16655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16656     {
16657       if (unformat (input, "del"))
16658         is_add = 0;
16659       else if (unformat (input, "add"))
16660         is_add = 1;
16661       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16662         {
16663           rmt_eid_set = 1;
16664         }
16665       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16666         {
16667           lcl_eid_set = 1;
16668         }
16669       else if (unformat (input, "vrf %d", &dp_table))
16670         ;
16671       else if (unformat (input, "bd %d", &dp_table))
16672         ;
16673       else if (unformat (input, "vni %d", &vni))
16674         ;
16675       else if (unformat (input, "w %d", &w))
16676         {
16677           if (!curr_rloc)
16678             {
16679               errmsg ("No RLOC configured for setting priority/weight!");
16680               return -99;
16681             }
16682           curr_rloc->weight = w;
16683         }
16684       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16685                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16686         {
16687           rloc.is_ip4 = 1;
16688
16689           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16690           rloc.weight = 0;
16691           vec_add1 (lcl_locs, rloc);
16692
16693           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16694           vec_add1 (rmt_locs, rloc);
16695           /* weight saved in rmt loc */
16696           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16697         }
16698       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16699                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16700         {
16701           rloc.is_ip4 = 0;
16702           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16703           rloc.weight = 0;
16704           vec_add1 (lcl_locs, rloc);
16705
16706           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16707           vec_add1 (rmt_locs, rloc);
16708           /* weight saved in rmt loc */
16709           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16710         }
16711       else if (unformat (input, "action %d", &action))
16712         {
16713           ;
16714         }
16715       else
16716         {
16717           clib_warning ("parse error '%U'", format_unformat_error, input);
16718           return -99;
16719         }
16720     }
16721
16722   if (!rmt_eid_set)
16723     {
16724       errmsg ("remote eid addresses not set");
16725       return -99;
16726     }
16727
16728   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16729     {
16730       errmsg ("eid types don't match");
16731       return -99;
16732     }
16733
16734   if (0 == rmt_locs && (u32) ~ 0 == action)
16735     {
16736       errmsg ("action not set for negative mapping");
16737       return -99;
16738     }
16739
16740   /* Construct the API message */
16741   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16742       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16743
16744   mp->is_add = is_add;
16745   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16746   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16747   mp->eid_type = rmt_eid->type;
16748   mp->dp_table = clib_host_to_net_u32 (dp_table);
16749   mp->vni = clib_host_to_net_u32 (vni);
16750   mp->rmt_len = rmt_eid->len;
16751   mp->lcl_len = lcl_eid->len;
16752   mp->action = action;
16753
16754   if (0 != rmt_locs && 0 != lcl_locs)
16755     {
16756       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16757       clib_memcpy (mp->locs, lcl_locs,
16758                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16759
16760       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16761       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16762                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16763     }
16764   vec_free (lcl_locs);
16765   vec_free (rmt_locs);
16766
16767   /* send it... */
16768   S (mp);
16769
16770   /* Wait for a reply... */
16771   W (ret);
16772   return ret;
16773 }
16774
16775 static int
16776 api_one_add_del_map_server (vat_main_t * vam)
16777 {
16778   unformat_input_t *input = vam->input;
16779   vl_api_one_add_del_map_server_t *mp;
16780   u8 is_add = 1;
16781   u8 ipv4_set = 0;
16782   u8 ipv6_set = 0;
16783   ip4_address_t ipv4;
16784   ip6_address_t ipv6;
16785   int ret;
16786
16787   /* Parse args required to build the message */
16788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16789     {
16790       if (unformat (input, "del"))
16791         {
16792           is_add = 0;
16793         }
16794       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16795         {
16796           ipv4_set = 1;
16797         }
16798       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16799         {
16800           ipv6_set = 1;
16801         }
16802       else
16803         break;
16804     }
16805
16806   if (ipv4_set && ipv6_set)
16807     {
16808       errmsg ("both eid v4 and v6 addresses set");
16809       return -99;
16810     }
16811
16812   if (!ipv4_set && !ipv6_set)
16813     {
16814       errmsg ("eid addresses not set");
16815       return -99;
16816     }
16817
16818   /* Construct the API message */
16819   M (ONE_ADD_DEL_MAP_SERVER, mp);
16820
16821   mp->is_add = is_add;
16822   if (ipv6_set)
16823     {
16824       mp->is_ipv6 = 1;
16825       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16826     }
16827   else
16828     {
16829       mp->is_ipv6 = 0;
16830       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16831     }
16832
16833   /* send it... */
16834   S (mp);
16835
16836   /* Wait for a reply... */
16837   W (ret);
16838   return ret;
16839 }
16840
16841 #define api_lisp_add_del_map_server api_one_add_del_map_server
16842
16843 static int
16844 api_one_add_del_map_resolver (vat_main_t * vam)
16845 {
16846   unformat_input_t *input = vam->input;
16847   vl_api_one_add_del_map_resolver_t *mp;
16848   u8 is_add = 1;
16849   u8 ipv4_set = 0;
16850   u8 ipv6_set = 0;
16851   ip4_address_t ipv4;
16852   ip6_address_t ipv6;
16853   int ret;
16854
16855   /* Parse args required to build the message */
16856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16857     {
16858       if (unformat (input, "del"))
16859         {
16860           is_add = 0;
16861         }
16862       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16863         {
16864           ipv4_set = 1;
16865         }
16866       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16867         {
16868           ipv6_set = 1;
16869         }
16870       else
16871         break;
16872     }
16873
16874   if (ipv4_set && ipv6_set)
16875     {
16876       errmsg ("both eid v4 and v6 addresses set");
16877       return -99;
16878     }
16879
16880   if (!ipv4_set && !ipv6_set)
16881     {
16882       errmsg ("eid addresses not set");
16883       return -99;
16884     }
16885
16886   /* Construct the API message */
16887   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16888
16889   mp->is_add = is_add;
16890   if (ipv6_set)
16891     {
16892       mp->is_ipv6 = 1;
16893       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16894     }
16895   else
16896     {
16897       mp->is_ipv6 = 0;
16898       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16899     }
16900
16901   /* send it... */
16902   S (mp);
16903
16904   /* Wait for a reply... */
16905   W (ret);
16906   return ret;
16907 }
16908
16909 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16910
16911 static int
16912 api_lisp_gpe_enable_disable (vat_main_t * vam)
16913 {
16914   unformat_input_t *input = vam->input;
16915   vl_api_gpe_enable_disable_t *mp;
16916   u8 is_set = 0;
16917   u8 is_en = 1;
16918   int ret;
16919
16920   /* Parse args required to build the message */
16921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16922     {
16923       if (unformat (input, "enable"))
16924         {
16925           is_set = 1;
16926           is_en = 1;
16927         }
16928       else if (unformat (input, "disable"))
16929         {
16930           is_set = 1;
16931           is_en = 0;
16932         }
16933       else
16934         break;
16935     }
16936
16937   if (is_set == 0)
16938     {
16939       errmsg ("Value not set");
16940       return -99;
16941     }
16942
16943   /* Construct the API message */
16944   M (GPE_ENABLE_DISABLE, mp);
16945
16946   mp->is_en = is_en;
16947
16948   /* send it... */
16949   S (mp);
16950
16951   /* Wait for a reply... */
16952   W (ret);
16953   return ret;
16954 }
16955
16956 static int
16957 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16958 {
16959   unformat_input_t *input = vam->input;
16960   vl_api_one_rloc_probe_enable_disable_t *mp;
16961   u8 is_set = 0;
16962   u8 is_en = 0;
16963   int ret;
16964
16965   /* Parse args required to build the message */
16966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16967     {
16968       if (unformat (input, "enable"))
16969         {
16970           is_set = 1;
16971           is_en = 1;
16972         }
16973       else if (unformat (input, "disable"))
16974         is_set = 1;
16975       else
16976         break;
16977     }
16978
16979   if (!is_set)
16980     {
16981       errmsg ("Value not set");
16982       return -99;
16983     }
16984
16985   /* Construct the API message */
16986   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16987
16988   mp->is_enabled = is_en;
16989
16990   /* send it... */
16991   S (mp);
16992
16993   /* Wait for a reply... */
16994   W (ret);
16995   return ret;
16996 }
16997
16998 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16999
17000 static int
17001 api_one_map_register_enable_disable (vat_main_t * vam)
17002 {
17003   unformat_input_t *input = vam->input;
17004   vl_api_one_map_register_enable_disable_t *mp;
17005   u8 is_set = 0;
17006   u8 is_en = 0;
17007   int ret;
17008
17009   /* Parse args required to build the message */
17010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17011     {
17012       if (unformat (input, "enable"))
17013         {
17014           is_set = 1;
17015           is_en = 1;
17016         }
17017       else if (unformat (input, "disable"))
17018         is_set = 1;
17019       else
17020         break;
17021     }
17022
17023   if (!is_set)
17024     {
17025       errmsg ("Value not set");
17026       return -99;
17027     }
17028
17029   /* Construct the API message */
17030   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17031
17032   mp->is_enabled = is_en;
17033
17034   /* send it... */
17035   S (mp);
17036
17037   /* Wait for a reply... */
17038   W (ret);
17039   return ret;
17040 }
17041
17042 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17043
17044 static int
17045 api_one_enable_disable (vat_main_t * vam)
17046 {
17047   unformat_input_t *input = vam->input;
17048   vl_api_one_enable_disable_t *mp;
17049   u8 is_set = 0;
17050   u8 is_en = 0;
17051   int ret;
17052
17053   /* Parse args required to build the message */
17054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17055     {
17056       if (unformat (input, "enable"))
17057         {
17058           is_set = 1;
17059           is_en = 1;
17060         }
17061       else if (unformat (input, "disable"))
17062         {
17063           is_set = 1;
17064         }
17065       else
17066         break;
17067     }
17068
17069   if (!is_set)
17070     {
17071       errmsg ("Value not set");
17072       return -99;
17073     }
17074
17075   /* Construct the API message */
17076   M (ONE_ENABLE_DISABLE, mp);
17077
17078   mp->is_en = is_en;
17079
17080   /* send it... */
17081   S (mp);
17082
17083   /* Wait for a reply... */
17084   W (ret);
17085   return ret;
17086 }
17087
17088 #define api_lisp_enable_disable api_one_enable_disable
17089
17090 static int
17091 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17092 {
17093   unformat_input_t *input = vam->input;
17094   vl_api_one_enable_disable_xtr_mode_t *mp;
17095   u8 is_set = 0;
17096   u8 is_en = 0;
17097   int ret;
17098
17099   /* Parse args required to build the message */
17100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17101     {
17102       if (unformat (input, "enable"))
17103         {
17104           is_set = 1;
17105           is_en = 1;
17106         }
17107       else if (unformat (input, "disable"))
17108         {
17109           is_set = 1;
17110         }
17111       else
17112         break;
17113     }
17114
17115   if (!is_set)
17116     {
17117       errmsg ("Value not set");
17118       return -99;
17119     }
17120
17121   /* Construct the API message */
17122   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17123
17124   mp->is_en = is_en;
17125
17126   /* send it... */
17127   S (mp);
17128
17129   /* Wait for a reply... */
17130   W (ret);
17131   return ret;
17132 }
17133
17134 static int
17135 api_one_show_xtr_mode (vat_main_t * vam)
17136 {
17137   vl_api_one_show_xtr_mode_t *mp;
17138   int ret;
17139
17140   /* Construct the API message */
17141   M (ONE_SHOW_XTR_MODE, mp);
17142
17143   /* send it... */
17144   S (mp);
17145
17146   /* Wait for a reply... */
17147   W (ret);
17148   return ret;
17149 }
17150
17151 static int
17152 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17153 {
17154   unformat_input_t *input = vam->input;
17155   vl_api_one_enable_disable_pitr_mode_t *mp;
17156   u8 is_set = 0;
17157   u8 is_en = 0;
17158   int ret;
17159
17160   /* Parse args required to build the message */
17161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17162     {
17163       if (unformat (input, "enable"))
17164         {
17165           is_set = 1;
17166           is_en = 1;
17167         }
17168       else if (unformat (input, "disable"))
17169         {
17170           is_set = 1;
17171         }
17172       else
17173         break;
17174     }
17175
17176   if (!is_set)
17177     {
17178       errmsg ("Value not set");
17179       return -99;
17180     }
17181
17182   /* Construct the API message */
17183   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17184
17185   mp->is_en = is_en;
17186
17187   /* send it... */
17188   S (mp);
17189
17190   /* Wait for a reply... */
17191   W (ret);
17192   return ret;
17193 }
17194
17195 static int
17196 api_one_show_pitr_mode (vat_main_t * vam)
17197 {
17198   vl_api_one_show_pitr_mode_t *mp;
17199   int ret;
17200
17201   /* Construct the API message */
17202   M (ONE_SHOW_PITR_MODE, mp);
17203
17204   /* send it... */
17205   S (mp);
17206
17207   /* Wait for a reply... */
17208   W (ret);
17209   return ret;
17210 }
17211
17212 static int
17213 api_one_enable_disable_petr_mode (vat_main_t * vam)
17214 {
17215   unformat_input_t *input = vam->input;
17216   vl_api_one_enable_disable_petr_mode_t *mp;
17217   u8 is_set = 0;
17218   u8 is_en = 0;
17219   int ret;
17220
17221   /* Parse args required to build the message */
17222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17223     {
17224       if (unformat (input, "enable"))
17225         {
17226           is_set = 1;
17227           is_en = 1;
17228         }
17229       else if (unformat (input, "disable"))
17230         {
17231           is_set = 1;
17232         }
17233       else
17234         break;
17235     }
17236
17237   if (!is_set)
17238     {
17239       errmsg ("Value not set");
17240       return -99;
17241     }
17242
17243   /* Construct the API message */
17244   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17245
17246   mp->is_en = is_en;
17247
17248   /* send it... */
17249   S (mp);
17250
17251   /* Wait for a reply... */
17252   W (ret);
17253   return ret;
17254 }
17255
17256 static int
17257 api_one_show_petr_mode (vat_main_t * vam)
17258 {
17259   vl_api_one_show_petr_mode_t *mp;
17260   int ret;
17261
17262   /* Construct the API message */
17263   M (ONE_SHOW_PETR_MODE, mp);
17264
17265   /* send it... */
17266   S (mp);
17267
17268   /* Wait for a reply... */
17269   W (ret);
17270   return ret;
17271 }
17272
17273 static int
17274 api_show_one_map_register_state (vat_main_t * vam)
17275 {
17276   vl_api_show_one_map_register_state_t *mp;
17277   int ret;
17278
17279   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17280
17281   /* send */
17282   S (mp);
17283
17284   /* wait for reply */
17285   W (ret);
17286   return ret;
17287 }
17288
17289 #define api_show_lisp_map_register_state api_show_one_map_register_state
17290
17291 static int
17292 api_show_one_rloc_probe_state (vat_main_t * vam)
17293 {
17294   vl_api_show_one_rloc_probe_state_t *mp;
17295   int ret;
17296
17297   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17298
17299   /* send */
17300   S (mp);
17301
17302   /* wait for reply */
17303   W (ret);
17304   return ret;
17305 }
17306
17307 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17308
17309 static int
17310 api_one_add_del_ndp_entry (vat_main_t * vam)
17311 {
17312   vl_api_one_add_del_ndp_entry_t *mp;
17313   unformat_input_t *input = vam->input;
17314   u8 is_add = 1;
17315   u8 mac_set = 0;
17316   u8 bd_set = 0;
17317   u8 ip_set = 0;
17318   u8 mac[6] = { 0, };
17319   u8 ip6[16] = { 0, };
17320   u32 bd = ~0;
17321   int ret;
17322
17323   /* Parse args required to build the message */
17324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17325     {
17326       if (unformat (input, "del"))
17327         is_add = 0;
17328       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17329         mac_set = 1;
17330       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17331         ip_set = 1;
17332       else if (unformat (input, "bd %d", &bd))
17333         bd_set = 1;
17334       else
17335         {
17336           errmsg ("parse error '%U'", format_unformat_error, input);
17337           return -99;
17338         }
17339     }
17340
17341   if (!bd_set || !ip_set || (!mac_set && is_add))
17342     {
17343       errmsg ("Missing BD, IP or MAC!");
17344       return -99;
17345     }
17346
17347   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17348   mp->is_add = is_add;
17349   clib_memcpy (mp->mac, mac, 6);
17350   mp->bd = clib_host_to_net_u32 (bd);
17351   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17352
17353   /* send */
17354   S (mp);
17355
17356   /* wait for reply */
17357   W (ret);
17358   return ret;
17359 }
17360
17361 static int
17362 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17363 {
17364   vl_api_one_add_del_l2_arp_entry_t *mp;
17365   unformat_input_t *input = vam->input;
17366   u8 is_add = 1;
17367   u8 mac_set = 0;
17368   u8 bd_set = 0;
17369   u8 ip_set = 0;
17370   u8 mac[6] = { 0, };
17371   u32 ip4 = 0, bd = ~0;
17372   int ret;
17373
17374   /* Parse args required to build the message */
17375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17376     {
17377       if (unformat (input, "del"))
17378         is_add = 0;
17379       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17380         mac_set = 1;
17381       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17382         ip_set = 1;
17383       else if (unformat (input, "bd %d", &bd))
17384         bd_set = 1;
17385       else
17386         {
17387           errmsg ("parse error '%U'", format_unformat_error, input);
17388           return -99;
17389         }
17390     }
17391
17392   if (!bd_set || !ip_set || (!mac_set && is_add))
17393     {
17394       errmsg ("Missing BD, IP or MAC!");
17395       return -99;
17396     }
17397
17398   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17399   mp->is_add = is_add;
17400   clib_memcpy (mp->mac, mac, 6);
17401   mp->bd = clib_host_to_net_u32 (bd);
17402   mp->ip4 = ip4;
17403
17404   /* send */
17405   S (mp);
17406
17407   /* wait for reply */
17408   W (ret);
17409   return ret;
17410 }
17411
17412 static int
17413 api_one_ndp_bd_get (vat_main_t * vam)
17414 {
17415   vl_api_one_ndp_bd_get_t *mp;
17416   int ret;
17417
17418   M (ONE_NDP_BD_GET, mp);
17419
17420   /* send */
17421   S (mp);
17422
17423   /* wait for reply */
17424   W (ret);
17425   return ret;
17426 }
17427
17428 static int
17429 api_one_ndp_entries_get (vat_main_t * vam)
17430 {
17431   vl_api_one_ndp_entries_get_t *mp;
17432   unformat_input_t *input = vam->input;
17433   u8 bd_set = 0;
17434   u32 bd = ~0;
17435   int ret;
17436
17437   /* Parse args required to build the message */
17438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17439     {
17440       if (unformat (input, "bd %d", &bd))
17441         bd_set = 1;
17442       else
17443         {
17444           errmsg ("parse error '%U'", format_unformat_error, input);
17445           return -99;
17446         }
17447     }
17448
17449   if (!bd_set)
17450     {
17451       errmsg ("Expected bridge domain!");
17452       return -99;
17453     }
17454
17455   M (ONE_NDP_ENTRIES_GET, mp);
17456   mp->bd = clib_host_to_net_u32 (bd);
17457
17458   /* send */
17459   S (mp);
17460
17461   /* wait for reply */
17462   W (ret);
17463   return ret;
17464 }
17465
17466 static int
17467 api_one_l2_arp_bd_get (vat_main_t * vam)
17468 {
17469   vl_api_one_l2_arp_bd_get_t *mp;
17470   int ret;
17471
17472   M (ONE_L2_ARP_BD_GET, mp);
17473
17474   /* send */
17475   S (mp);
17476
17477   /* wait for reply */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 static int
17483 api_one_l2_arp_entries_get (vat_main_t * vam)
17484 {
17485   vl_api_one_l2_arp_entries_get_t *mp;
17486   unformat_input_t *input = vam->input;
17487   u8 bd_set = 0;
17488   u32 bd = ~0;
17489   int ret;
17490
17491   /* Parse args required to build the message */
17492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17493     {
17494       if (unformat (input, "bd %d", &bd))
17495         bd_set = 1;
17496       else
17497         {
17498           errmsg ("parse error '%U'", format_unformat_error, input);
17499           return -99;
17500         }
17501     }
17502
17503   if (!bd_set)
17504     {
17505       errmsg ("Expected bridge domain!");
17506       return -99;
17507     }
17508
17509   M (ONE_L2_ARP_ENTRIES_GET, mp);
17510   mp->bd = clib_host_to_net_u32 (bd);
17511
17512   /* send */
17513   S (mp);
17514
17515   /* wait for reply */
17516   W (ret);
17517   return ret;
17518 }
17519
17520 static int
17521 api_one_stats_enable_disable (vat_main_t * vam)
17522 {
17523   vl_api_one_stats_enable_disable_t *mp;
17524   unformat_input_t *input = vam->input;
17525   u8 is_set = 0;
17526   u8 is_en = 0;
17527   int ret;
17528
17529   /* Parse args required to build the message */
17530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17531     {
17532       if (unformat (input, "enable"))
17533         {
17534           is_set = 1;
17535           is_en = 1;
17536         }
17537       else if (unformat (input, "disable"))
17538         {
17539           is_set = 1;
17540         }
17541       else
17542         break;
17543     }
17544
17545   if (!is_set)
17546     {
17547       errmsg ("Value not set");
17548       return -99;
17549     }
17550
17551   M (ONE_STATS_ENABLE_DISABLE, mp);
17552   mp->is_en = is_en;
17553
17554   /* send */
17555   S (mp);
17556
17557   /* wait for reply */
17558   W (ret);
17559   return ret;
17560 }
17561
17562 static int
17563 api_show_one_stats_enable_disable (vat_main_t * vam)
17564 {
17565   vl_api_show_one_stats_enable_disable_t *mp;
17566   int ret;
17567
17568   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17569
17570   /* send */
17571   S (mp);
17572
17573   /* wait for reply */
17574   W (ret);
17575   return ret;
17576 }
17577
17578 static int
17579 api_show_one_map_request_mode (vat_main_t * vam)
17580 {
17581   vl_api_show_one_map_request_mode_t *mp;
17582   int ret;
17583
17584   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17585
17586   /* send */
17587   S (mp);
17588
17589   /* wait for reply */
17590   W (ret);
17591   return ret;
17592 }
17593
17594 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17595
17596 static int
17597 api_one_map_request_mode (vat_main_t * vam)
17598 {
17599   unformat_input_t *input = vam->input;
17600   vl_api_one_map_request_mode_t *mp;
17601   u8 mode = 0;
17602   int ret;
17603
17604   /* Parse args required to build the message */
17605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17606     {
17607       if (unformat (input, "dst-only"))
17608         mode = 0;
17609       else if (unformat (input, "src-dst"))
17610         mode = 1;
17611       else
17612         {
17613           errmsg ("parse error '%U'", format_unformat_error, input);
17614           return -99;
17615         }
17616     }
17617
17618   M (ONE_MAP_REQUEST_MODE, mp);
17619
17620   mp->mode = mode;
17621
17622   /* send */
17623   S (mp);
17624
17625   /* wait for reply */
17626   W (ret);
17627   return ret;
17628 }
17629
17630 #define api_lisp_map_request_mode api_one_map_request_mode
17631
17632 /**
17633  * Enable/disable ONE proxy ITR.
17634  *
17635  * @param vam vpp API test context
17636  * @return return code
17637  */
17638 static int
17639 api_one_pitr_set_locator_set (vat_main_t * vam)
17640 {
17641   u8 ls_name_set = 0;
17642   unformat_input_t *input = vam->input;
17643   vl_api_one_pitr_set_locator_set_t *mp;
17644   u8 is_add = 1;
17645   u8 *ls_name = 0;
17646   int ret;
17647
17648   /* Parse args required to build the message */
17649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17650     {
17651       if (unformat (input, "del"))
17652         is_add = 0;
17653       else if (unformat (input, "locator-set %s", &ls_name))
17654         ls_name_set = 1;
17655       else
17656         {
17657           errmsg ("parse error '%U'", format_unformat_error, input);
17658           return -99;
17659         }
17660     }
17661
17662   if (!ls_name_set)
17663     {
17664       errmsg ("locator-set name not set!");
17665       return -99;
17666     }
17667
17668   M (ONE_PITR_SET_LOCATOR_SET, mp);
17669
17670   mp->is_add = is_add;
17671   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17672   vec_free (ls_name);
17673
17674   /* send */
17675   S (mp);
17676
17677   /* wait for reply */
17678   W (ret);
17679   return ret;
17680 }
17681
17682 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17683
17684 static int
17685 api_one_nsh_set_locator_set (vat_main_t * vam)
17686 {
17687   u8 ls_name_set = 0;
17688   unformat_input_t *input = vam->input;
17689   vl_api_one_nsh_set_locator_set_t *mp;
17690   u8 is_add = 1;
17691   u8 *ls_name = 0;
17692   int ret;
17693
17694   /* Parse args required to build the message */
17695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17696     {
17697       if (unformat (input, "del"))
17698         is_add = 0;
17699       else if (unformat (input, "ls %s", &ls_name))
17700         ls_name_set = 1;
17701       else
17702         {
17703           errmsg ("parse error '%U'", format_unformat_error, input);
17704           return -99;
17705         }
17706     }
17707
17708   if (!ls_name_set && is_add)
17709     {
17710       errmsg ("locator-set name not set!");
17711       return -99;
17712     }
17713
17714   M (ONE_NSH_SET_LOCATOR_SET, mp);
17715
17716   mp->is_add = is_add;
17717   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17718   vec_free (ls_name);
17719
17720   /* send */
17721   S (mp);
17722
17723   /* wait for reply */
17724   W (ret);
17725   return ret;
17726 }
17727
17728 static int
17729 api_show_one_pitr (vat_main_t * vam)
17730 {
17731   vl_api_show_one_pitr_t *mp;
17732   int ret;
17733
17734   if (!vam->json_output)
17735     {
17736       print (vam->ofp, "%=20s", "lisp status:");
17737     }
17738
17739   M (SHOW_ONE_PITR, mp);
17740   /* send it... */
17741   S (mp);
17742
17743   /* Wait for a reply... */
17744   W (ret);
17745   return ret;
17746 }
17747
17748 #define api_show_lisp_pitr api_show_one_pitr
17749
17750 static int
17751 api_one_use_petr (vat_main_t * vam)
17752 {
17753   unformat_input_t *input = vam->input;
17754   vl_api_one_use_petr_t *mp;
17755   u8 is_add = 0;
17756   ip_address_t ip;
17757   int ret;
17758
17759   clib_memset (&ip, 0, sizeof (ip));
17760
17761   /* Parse args required to build the message */
17762   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17763     {
17764       if (unformat (input, "disable"))
17765         is_add = 0;
17766       else
17767         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17768         {
17769           is_add = 1;
17770           ip_addr_version (&ip) = IP4;
17771         }
17772       else
17773         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17774         {
17775           is_add = 1;
17776           ip_addr_version (&ip) = IP6;
17777         }
17778       else
17779         {
17780           errmsg ("parse error '%U'", format_unformat_error, input);
17781           return -99;
17782         }
17783     }
17784
17785   M (ONE_USE_PETR, mp);
17786
17787   mp->is_add = is_add;
17788   if (is_add)
17789     {
17790       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17791       if (mp->is_ip4)
17792         clib_memcpy (mp->address, &ip, 4);
17793       else
17794         clib_memcpy (mp->address, &ip, 16);
17795     }
17796
17797   /* send */
17798   S (mp);
17799
17800   /* wait for reply */
17801   W (ret);
17802   return ret;
17803 }
17804
17805 #define api_lisp_use_petr api_one_use_petr
17806
17807 static int
17808 api_show_one_nsh_mapping (vat_main_t * vam)
17809 {
17810   vl_api_show_one_use_petr_t *mp;
17811   int ret;
17812
17813   if (!vam->json_output)
17814     {
17815       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17816     }
17817
17818   M (SHOW_ONE_NSH_MAPPING, mp);
17819   /* send it... */
17820   S (mp);
17821
17822   /* Wait for a reply... */
17823   W (ret);
17824   return ret;
17825 }
17826
17827 static int
17828 api_show_one_use_petr (vat_main_t * vam)
17829 {
17830   vl_api_show_one_use_petr_t *mp;
17831   int ret;
17832
17833   if (!vam->json_output)
17834     {
17835       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17836     }
17837
17838   M (SHOW_ONE_USE_PETR, mp);
17839   /* send it... */
17840   S (mp);
17841
17842   /* Wait for a reply... */
17843   W (ret);
17844   return ret;
17845 }
17846
17847 #define api_show_lisp_use_petr api_show_one_use_petr
17848
17849 /**
17850  * Add/delete mapping between vni and vrf
17851  */
17852 static int
17853 api_one_eid_table_add_del_map (vat_main_t * vam)
17854 {
17855   unformat_input_t *input = vam->input;
17856   vl_api_one_eid_table_add_del_map_t *mp;
17857   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17858   u32 vni, vrf, bd_index;
17859   int ret;
17860
17861   /* Parse args required to build the message */
17862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17863     {
17864       if (unformat (input, "del"))
17865         is_add = 0;
17866       else if (unformat (input, "vrf %d", &vrf))
17867         vrf_set = 1;
17868       else if (unformat (input, "bd_index %d", &bd_index))
17869         bd_index_set = 1;
17870       else if (unformat (input, "vni %d", &vni))
17871         vni_set = 1;
17872       else
17873         break;
17874     }
17875
17876   if (!vni_set || (!vrf_set && !bd_index_set))
17877     {
17878       errmsg ("missing arguments!");
17879       return -99;
17880     }
17881
17882   if (vrf_set && bd_index_set)
17883     {
17884       errmsg ("error: both vrf and bd entered!");
17885       return -99;
17886     }
17887
17888   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17889
17890   mp->is_add = is_add;
17891   mp->vni = htonl (vni);
17892   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17893   mp->is_l2 = bd_index_set;
17894
17895   /* send */
17896   S (mp);
17897
17898   /* wait for reply */
17899   W (ret);
17900   return ret;
17901 }
17902
17903 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17904
17905 uword
17906 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17907 {
17908   u32 *action = va_arg (*args, u32 *);
17909   u8 *s = 0;
17910
17911   if (unformat (input, "%s", &s))
17912     {
17913       if (!strcmp ((char *) s, "no-action"))
17914         action[0] = 0;
17915       else if (!strcmp ((char *) s, "natively-forward"))
17916         action[0] = 1;
17917       else if (!strcmp ((char *) s, "send-map-request"))
17918         action[0] = 2;
17919       else if (!strcmp ((char *) s, "drop"))
17920         action[0] = 3;
17921       else
17922         {
17923           clib_warning ("invalid action: '%s'", s);
17924           action[0] = 3;
17925         }
17926     }
17927   else
17928     return 0;
17929
17930   vec_free (s);
17931   return 1;
17932 }
17933
17934 /**
17935  * Add/del remote mapping to/from ONE control plane
17936  *
17937  * @param vam vpp API test context
17938  * @return return code
17939  */
17940 static int
17941 api_one_add_del_remote_mapping (vat_main_t * vam)
17942 {
17943   unformat_input_t *input = vam->input;
17944   vl_api_one_add_del_remote_mapping_t *mp;
17945   u32 vni = 0;
17946   lisp_eid_vat_t _eid, *eid = &_eid;
17947   lisp_eid_vat_t _seid, *seid = &_seid;
17948   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17949   u32 action = ~0, p, w, data_len;
17950   ip4_address_t rloc4;
17951   ip6_address_t rloc6;
17952   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17953   int ret;
17954
17955   clib_memset (&rloc, 0, sizeof (rloc));
17956
17957   /* Parse args required to build the message */
17958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17959     {
17960       if (unformat (input, "del-all"))
17961         {
17962           del_all = 1;
17963         }
17964       else if (unformat (input, "del"))
17965         {
17966           is_add = 0;
17967         }
17968       else if (unformat (input, "add"))
17969         {
17970           is_add = 1;
17971         }
17972       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17973         {
17974           eid_set = 1;
17975         }
17976       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17977         {
17978           seid_set = 1;
17979         }
17980       else if (unformat (input, "vni %d", &vni))
17981         {
17982           ;
17983         }
17984       else if (unformat (input, "p %d w %d", &p, &w))
17985         {
17986           if (!curr_rloc)
17987             {
17988               errmsg ("No RLOC configured for setting priority/weight!");
17989               return -99;
17990             }
17991           curr_rloc->priority = p;
17992           curr_rloc->weight = w;
17993         }
17994       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17995         {
17996           rloc.is_ip4 = 1;
17997           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17998           vec_add1 (rlocs, rloc);
17999           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18000         }
18001       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18002         {
18003           rloc.is_ip4 = 0;
18004           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18005           vec_add1 (rlocs, rloc);
18006           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18007         }
18008       else if (unformat (input, "action %U",
18009                          unformat_negative_mapping_action, &action))
18010         {
18011           ;
18012         }
18013       else
18014         {
18015           clib_warning ("parse error '%U'", format_unformat_error, input);
18016           return -99;
18017         }
18018     }
18019
18020   if (0 == eid_set)
18021     {
18022       errmsg ("missing params!");
18023       return -99;
18024     }
18025
18026   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18027     {
18028       errmsg ("no action set for negative map-reply!");
18029       return -99;
18030     }
18031
18032   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18033
18034   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18035   mp->is_add = is_add;
18036   mp->vni = htonl (vni);
18037   mp->action = (u8) action;
18038   mp->is_src_dst = seid_set;
18039   mp->eid_len = eid->len;
18040   mp->seid_len = seid->len;
18041   mp->del_all = del_all;
18042   mp->eid_type = eid->type;
18043   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18044   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18045
18046   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18047   clib_memcpy (mp->rlocs, rlocs, data_len);
18048   vec_free (rlocs);
18049
18050   /* send it... */
18051   S (mp);
18052
18053   /* Wait for a reply... */
18054   W (ret);
18055   return ret;
18056 }
18057
18058 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18059
18060 /**
18061  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18062  * forwarding entries in data-plane accordingly.
18063  *
18064  * @param vam vpp API test context
18065  * @return return code
18066  */
18067 static int
18068 api_one_add_del_adjacency (vat_main_t * vam)
18069 {
18070   unformat_input_t *input = vam->input;
18071   vl_api_one_add_del_adjacency_t *mp;
18072   u32 vni = 0;
18073   ip4_address_t leid4, reid4;
18074   ip6_address_t leid6, reid6;
18075   u8 reid_mac[6] = { 0 };
18076   u8 leid_mac[6] = { 0 };
18077   u8 reid_type, leid_type;
18078   u32 leid_len = 0, reid_len = 0, len;
18079   u8 is_add = 1;
18080   int ret;
18081
18082   leid_type = reid_type = (u8) ~ 0;
18083
18084   /* Parse args required to build the message */
18085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (input, "del"))
18088         {
18089           is_add = 0;
18090         }
18091       else if (unformat (input, "add"))
18092         {
18093           is_add = 1;
18094         }
18095       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18096                          &reid4, &len))
18097         {
18098           reid_type = 0;        /* ipv4 */
18099           reid_len = len;
18100         }
18101       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18102                          &reid6, &len))
18103         {
18104           reid_type = 1;        /* ipv6 */
18105           reid_len = len;
18106         }
18107       else if (unformat (input, "reid %U", unformat_ethernet_address,
18108                          reid_mac))
18109         {
18110           reid_type = 2;        /* mac */
18111         }
18112       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18113                          &leid4, &len))
18114         {
18115           leid_type = 0;        /* ipv4 */
18116           leid_len = len;
18117         }
18118       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18119                          &leid6, &len))
18120         {
18121           leid_type = 1;        /* ipv6 */
18122           leid_len = len;
18123         }
18124       else if (unformat (input, "leid %U", unformat_ethernet_address,
18125                          leid_mac))
18126         {
18127           leid_type = 2;        /* mac */
18128         }
18129       else if (unformat (input, "vni %d", &vni))
18130         {
18131           ;
18132         }
18133       else
18134         {
18135           errmsg ("parse error '%U'", format_unformat_error, input);
18136           return -99;
18137         }
18138     }
18139
18140   if ((u8) ~ 0 == reid_type)
18141     {
18142       errmsg ("missing params!");
18143       return -99;
18144     }
18145
18146   if (leid_type != reid_type)
18147     {
18148       errmsg ("remote and local EIDs are of different types!");
18149       return -99;
18150     }
18151
18152   M (ONE_ADD_DEL_ADJACENCY, mp);
18153   mp->is_add = is_add;
18154   mp->vni = htonl (vni);
18155   mp->leid_len = leid_len;
18156   mp->reid_len = reid_len;
18157   mp->eid_type = reid_type;
18158
18159   switch (mp->eid_type)
18160     {
18161     case 0:
18162       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18163       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18164       break;
18165     case 1:
18166       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18167       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18168       break;
18169     case 2:
18170       clib_memcpy (mp->leid, leid_mac, 6);
18171       clib_memcpy (mp->reid, reid_mac, 6);
18172       break;
18173     default:
18174       errmsg ("unknown EID type %d!", mp->eid_type);
18175       return 0;
18176     }
18177
18178   /* send it... */
18179   S (mp);
18180
18181   /* Wait for a reply... */
18182   W (ret);
18183   return ret;
18184 }
18185
18186 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18187
18188 uword
18189 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18190 {
18191   u32 *mode = va_arg (*args, u32 *);
18192
18193   if (unformat (input, "lisp"))
18194     *mode = 0;
18195   else if (unformat (input, "vxlan"))
18196     *mode = 1;
18197   else
18198     return 0;
18199
18200   return 1;
18201 }
18202
18203 static int
18204 api_gpe_get_encap_mode (vat_main_t * vam)
18205 {
18206   vl_api_gpe_get_encap_mode_t *mp;
18207   int ret;
18208
18209   /* Construct the API message */
18210   M (GPE_GET_ENCAP_MODE, mp);
18211
18212   /* send it... */
18213   S (mp);
18214
18215   /* Wait for a reply... */
18216   W (ret);
18217   return ret;
18218 }
18219
18220 static int
18221 api_gpe_set_encap_mode (vat_main_t * vam)
18222 {
18223   unformat_input_t *input = vam->input;
18224   vl_api_gpe_set_encap_mode_t *mp;
18225   int ret;
18226   u32 mode = 0;
18227
18228   /* Parse args required to build the message */
18229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18230     {
18231       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18232         ;
18233       else
18234         break;
18235     }
18236
18237   /* Construct the API message */
18238   M (GPE_SET_ENCAP_MODE, mp);
18239
18240   mp->mode = mode;
18241
18242   /* send it... */
18243   S (mp);
18244
18245   /* Wait for a reply... */
18246   W (ret);
18247   return ret;
18248 }
18249
18250 static int
18251 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18252 {
18253   unformat_input_t *input = vam->input;
18254   vl_api_gpe_add_del_iface_t *mp;
18255   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18256   u32 dp_table = 0, vni = 0;
18257   int ret;
18258
18259   /* Parse args required to build the message */
18260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18261     {
18262       if (unformat (input, "up"))
18263         {
18264           action_set = 1;
18265           is_add = 1;
18266         }
18267       else if (unformat (input, "down"))
18268         {
18269           action_set = 1;
18270           is_add = 0;
18271         }
18272       else if (unformat (input, "table_id %d", &dp_table))
18273         {
18274           dp_table_set = 1;
18275         }
18276       else if (unformat (input, "bd_id %d", &dp_table))
18277         {
18278           dp_table_set = 1;
18279           is_l2 = 1;
18280         }
18281       else if (unformat (input, "vni %d", &vni))
18282         {
18283           vni_set = 1;
18284         }
18285       else
18286         break;
18287     }
18288
18289   if (action_set == 0)
18290     {
18291       errmsg ("Action not set");
18292       return -99;
18293     }
18294   if (dp_table_set == 0 || vni_set == 0)
18295     {
18296       errmsg ("vni and dp_table must be set");
18297       return -99;
18298     }
18299
18300   /* Construct the API message */
18301   M (GPE_ADD_DEL_IFACE, mp);
18302
18303   mp->is_add = is_add;
18304   mp->dp_table = clib_host_to_net_u32 (dp_table);
18305   mp->is_l2 = is_l2;
18306   mp->vni = clib_host_to_net_u32 (vni);
18307
18308   /* send it... */
18309   S (mp);
18310
18311   /* Wait for a reply... */
18312   W (ret);
18313   return ret;
18314 }
18315
18316 static int
18317 api_one_map_register_fallback_threshold (vat_main_t * vam)
18318 {
18319   unformat_input_t *input = vam->input;
18320   vl_api_one_map_register_fallback_threshold_t *mp;
18321   u32 value = 0;
18322   u8 is_set = 0;
18323   int ret;
18324
18325   /* Parse args required to build the message */
18326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18327     {
18328       if (unformat (input, "%u", &value))
18329         is_set = 1;
18330       else
18331         {
18332           clib_warning ("parse error '%U'", format_unformat_error, input);
18333           return -99;
18334         }
18335     }
18336
18337   if (!is_set)
18338     {
18339       errmsg ("fallback threshold value is missing!");
18340       return -99;
18341     }
18342
18343   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18344   mp->value = clib_host_to_net_u32 (value);
18345
18346   /* send it... */
18347   S (mp);
18348
18349   /* Wait for a reply... */
18350   W (ret);
18351   return ret;
18352 }
18353
18354 static int
18355 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18356 {
18357   vl_api_show_one_map_register_fallback_threshold_t *mp;
18358   int ret;
18359
18360   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18361
18362   /* send it... */
18363   S (mp);
18364
18365   /* Wait for a reply... */
18366   W (ret);
18367   return ret;
18368 }
18369
18370 uword
18371 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18372 {
18373   u32 *proto = va_arg (*args, u32 *);
18374
18375   if (unformat (input, "udp"))
18376     *proto = 1;
18377   else if (unformat (input, "api"))
18378     *proto = 2;
18379   else
18380     return 0;
18381
18382   return 1;
18383 }
18384
18385 static int
18386 api_one_set_transport_protocol (vat_main_t * vam)
18387 {
18388   unformat_input_t *input = vam->input;
18389   vl_api_one_set_transport_protocol_t *mp;
18390   u8 is_set = 0;
18391   u32 protocol = 0;
18392   int ret;
18393
18394   /* Parse args required to build the message */
18395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18396     {
18397       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18398         is_set = 1;
18399       else
18400         {
18401           clib_warning ("parse error '%U'", format_unformat_error, input);
18402           return -99;
18403         }
18404     }
18405
18406   if (!is_set)
18407     {
18408       errmsg ("Transport protocol missing!");
18409       return -99;
18410     }
18411
18412   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18413   mp->protocol = (u8) protocol;
18414
18415   /* send it... */
18416   S (mp);
18417
18418   /* Wait for a reply... */
18419   W (ret);
18420   return ret;
18421 }
18422
18423 static int
18424 api_one_get_transport_protocol (vat_main_t * vam)
18425 {
18426   vl_api_one_get_transport_protocol_t *mp;
18427   int ret;
18428
18429   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18430
18431   /* send it... */
18432   S (mp);
18433
18434   /* Wait for a reply... */
18435   W (ret);
18436   return ret;
18437 }
18438
18439 static int
18440 api_one_map_register_set_ttl (vat_main_t * vam)
18441 {
18442   unformat_input_t *input = vam->input;
18443   vl_api_one_map_register_set_ttl_t *mp;
18444   u32 ttl = 0;
18445   u8 is_set = 0;
18446   int ret;
18447
18448   /* Parse args required to build the message */
18449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18450     {
18451       if (unformat (input, "%u", &ttl))
18452         is_set = 1;
18453       else
18454         {
18455           clib_warning ("parse error '%U'", format_unformat_error, input);
18456           return -99;
18457         }
18458     }
18459
18460   if (!is_set)
18461     {
18462       errmsg ("TTL value missing!");
18463       return -99;
18464     }
18465
18466   M (ONE_MAP_REGISTER_SET_TTL, mp);
18467   mp->ttl = clib_host_to_net_u32 (ttl);
18468
18469   /* send it... */
18470   S (mp);
18471
18472   /* Wait for a reply... */
18473   W (ret);
18474   return ret;
18475 }
18476
18477 static int
18478 api_show_one_map_register_ttl (vat_main_t * vam)
18479 {
18480   vl_api_show_one_map_register_ttl_t *mp;
18481   int ret;
18482
18483   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18484
18485   /* send it... */
18486   S (mp);
18487
18488   /* Wait for a reply... */
18489   W (ret);
18490   return ret;
18491 }
18492
18493 /**
18494  * Add/del map request itr rlocs from ONE control plane and updates
18495  *
18496  * @param vam vpp API test context
18497  * @return return code
18498  */
18499 static int
18500 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18501 {
18502   unformat_input_t *input = vam->input;
18503   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18504   u8 *locator_set_name = 0;
18505   u8 locator_set_name_set = 0;
18506   u8 is_add = 1;
18507   int ret;
18508
18509   /* Parse args required to build the message */
18510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18511     {
18512       if (unformat (input, "del"))
18513         {
18514           is_add = 0;
18515         }
18516       else if (unformat (input, "%_%v%_", &locator_set_name))
18517         {
18518           locator_set_name_set = 1;
18519         }
18520       else
18521         {
18522           clib_warning ("parse error '%U'", format_unformat_error, input);
18523           return -99;
18524         }
18525     }
18526
18527   if (is_add && !locator_set_name_set)
18528     {
18529       errmsg ("itr-rloc is not set!");
18530       return -99;
18531     }
18532
18533   if (is_add && vec_len (locator_set_name) > 64)
18534     {
18535       errmsg ("itr-rloc locator-set name too long");
18536       vec_free (locator_set_name);
18537       return -99;
18538     }
18539
18540   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18541   mp->is_add = is_add;
18542   if (is_add)
18543     {
18544       clib_memcpy (mp->locator_set_name, locator_set_name,
18545                    vec_len (locator_set_name));
18546     }
18547   else
18548     {
18549       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18550     }
18551   vec_free (locator_set_name);
18552
18553   /* send it... */
18554   S (mp);
18555
18556   /* Wait for a reply... */
18557   W (ret);
18558   return ret;
18559 }
18560
18561 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18562
18563 static int
18564 api_one_locator_dump (vat_main_t * vam)
18565 {
18566   unformat_input_t *input = vam->input;
18567   vl_api_one_locator_dump_t *mp;
18568   vl_api_control_ping_t *mp_ping;
18569   u8 is_index_set = 0, is_name_set = 0;
18570   u8 *ls_name = 0;
18571   u32 ls_index = ~0;
18572   int ret;
18573
18574   /* Parse args required to build the message */
18575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18576     {
18577       if (unformat (input, "ls_name %_%v%_", &ls_name))
18578         {
18579           is_name_set = 1;
18580         }
18581       else if (unformat (input, "ls_index %d", &ls_index))
18582         {
18583           is_index_set = 1;
18584         }
18585       else
18586         {
18587           errmsg ("parse error '%U'", format_unformat_error, input);
18588           return -99;
18589         }
18590     }
18591
18592   if (!is_index_set && !is_name_set)
18593     {
18594       errmsg ("error: expected one of index or name!");
18595       return -99;
18596     }
18597
18598   if (is_index_set && is_name_set)
18599     {
18600       errmsg ("error: only one param expected!");
18601       return -99;
18602     }
18603
18604   if (vec_len (ls_name) > 62)
18605     {
18606       errmsg ("error: locator set name too long!");
18607       return -99;
18608     }
18609
18610   if (!vam->json_output)
18611     {
18612       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18613     }
18614
18615   M (ONE_LOCATOR_DUMP, mp);
18616   mp->is_index_set = is_index_set;
18617
18618   if (is_index_set)
18619     mp->ls_index = clib_host_to_net_u32 (ls_index);
18620   else
18621     {
18622       vec_add1 (ls_name, 0);
18623       strncpy ((char *) mp->ls_name, (char *) ls_name,
18624                sizeof (mp->ls_name) - 1);
18625     }
18626
18627   /* send it... */
18628   S (mp);
18629
18630   /* Use a control ping for synchronization */
18631   MPING (CONTROL_PING, mp_ping);
18632   S (mp_ping);
18633
18634   /* Wait for a reply... */
18635   W (ret);
18636   return ret;
18637 }
18638
18639 #define api_lisp_locator_dump api_one_locator_dump
18640
18641 static int
18642 api_one_locator_set_dump (vat_main_t * vam)
18643 {
18644   vl_api_one_locator_set_dump_t *mp;
18645   vl_api_control_ping_t *mp_ping;
18646   unformat_input_t *input = vam->input;
18647   u8 filter = 0;
18648   int ret;
18649
18650   /* Parse args required to build the message */
18651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18652     {
18653       if (unformat (input, "local"))
18654         {
18655           filter = 1;
18656         }
18657       else if (unformat (input, "remote"))
18658         {
18659           filter = 2;
18660         }
18661       else
18662         {
18663           errmsg ("parse error '%U'", format_unformat_error, input);
18664           return -99;
18665         }
18666     }
18667
18668   if (!vam->json_output)
18669     {
18670       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18671     }
18672
18673   M (ONE_LOCATOR_SET_DUMP, mp);
18674
18675   mp->filter = filter;
18676
18677   /* send it... */
18678   S (mp);
18679
18680   /* Use a control ping for synchronization */
18681   MPING (CONTROL_PING, mp_ping);
18682   S (mp_ping);
18683
18684   /* Wait for a reply... */
18685   W (ret);
18686   return ret;
18687 }
18688
18689 #define api_lisp_locator_set_dump api_one_locator_set_dump
18690
18691 static int
18692 api_one_eid_table_map_dump (vat_main_t * vam)
18693 {
18694   u8 is_l2 = 0;
18695   u8 mode_set = 0;
18696   unformat_input_t *input = vam->input;
18697   vl_api_one_eid_table_map_dump_t *mp;
18698   vl_api_control_ping_t *mp_ping;
18699   int ret;
18700
18701   /* Parse args required to build the message */
18702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18703     {
18704       if (unformat (input, "l2"))
18705         {
18706           is_l2 = 1;
18707           mode_set = 1;
18708         }
18709       else if (unformat (input, "l3"))
18710         {
18711           is_l2 = 0;
18712           mode_set = 1;
18713         }
18714       else
18715         {
18716           errmsg ("parse error '%U'", format_unformat_error, input);
18717           return -99;
18718         }
18719     }
18720
18721   if (!mode_set)
18722     {
18723       errmsg ("expected one of 'l2' or 'l3' parameter!");
18724       return -99;
18725     }
18726
18727   if (!vam->json_output)
18728     {
18729       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18730     }
18731
18732   M (ONE_EID_TABLE_MAP_DUMP, mp);
18733   mp->is_l2 = is_l2;
18734
18735   /* send it... */
18736   S (mp);
18737
18738   /* Use a control ping for synchronization */
18739   MPING (CONTROL_PING, mp_ping);
18740   S (mp_ping);
18741
18742   /* Wait for a reply... */
18743   W (ret);
18744   return ret;
18745 }
18746
18747 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18748
18749 static int
18750 api_one_eid_table_vni_dump (vat_main_t * vam)
18751 {
18752   vl_api_one_eid_table_vni_dump_t *mp;
18753   vl_api_control_ping_t *mp_ping;
18754   int ret;
18755
18756   if (!vam->json_output)
18757     {
18758       print (vam->ofp, "VNI");
18759     }
18760
18761   M (ONE_EID_TABLE_VNI_DUMP, mp);
18762
18763   /* send it... */
18764   S (mp);
18765
18766   /* Use a control ping for synchronization */
18767   MPING (CONTROL_PING, mp_ping);
18768   S (mp_ping);
18769
18770   /* Wait for a reply... */
18771   W (ret);
18772   return ret;
18773 }
18774
18775 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18776
18777 static int
18778 api_one_eid_table_dump (vat_main_t * vam)
18779 {
18780   unformat_input_t *i = vam->input;
18781   vl_api_one_eid_table_dump_t *mp;
18782   vl_api_control_ping_t *mp_ping;
18783   struct in_addr ip4;
18784   struct in6_addr ip6;
18785   u8 mac[6];
18786   u8 eid_type = ~0, eid_set = 0;
18787   u32 prefix_length = ~0, t, vni = 0;
18788   u8 filter = 0;
18789   int ret;
18790   lisp_nsh_api_t nsh;
18791
18792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18793     {
18794       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18795         {
18796           eid_set = 1;
18797           eid_type = 0;
18798           prefix_length = t;
18799         }
18800       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18801         {
18802           eid_set = 1;
18803           eid_type = 1;
18804           prefix_length = t;
18805         }
18806       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18807         {
18808           eid_set = 1;
18809           eid_type = 2;
18810         }
18811       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18812         {
18813           eid_set = 1;
18814           eid_type = 3;
18815         }
18816       else if (unformat (i, "vni %d", &t))
18817         {
18818           vni = t;
18819         }
18820       else if (unformat (i, "local"))
18821         {
18822           filter = 1;
18823         }
18824       else if (unformat (i, "remote"))
18825         {
18826           filter = 2;
18827         }
18828       else
18829         {
18830           errmsg ("parse error '%U'", format_unformat_error, i);
18831           return -99;
18832         }
18833     }
18834
18835   if (!vam->json_output)
18836     {
18837       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18838              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18839     }
18840
18841   M (ONE_EID_TABLE_DUMP, mp);
18842
18843   mp->filter = filter;
18844   if (eid_set)
18845     {
18846       mp->eid_set = 1;
18847       mp->vni = htonl (vni);
18848       mp->eid_type = eid_type;
18849       switch (eid_type)
18850         {
18851         case 0:
18852           mp->prefix_length = prefix_length;
18853           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18854           break;
18855         case 1:
18856           mp->prefix_length = prefix_length;
18857           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18858           break;
18859         case 2:
18860           clib_memcpy (mp->eid, mac, sizeof (mac));
18861           break;
18862         case 3:
18863           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18864           break;
18865         default:
18866           errmsg ("unknown EID type %d!", eid_type);
18867           return -99;
18868         }
18869     }
18870
18871   /* send it... */
18872   S (mp);
18873
18874   /* Use a control ping for synchronization */
18875   MPING (CONTROL_PING, mp_ping);
18876   S (mp_ping);
18877
18878   /* Wait for a reply... */
18879   W (ret);
18880   return ret;
18881 }
18882
18883 #define api_lisp_eid_table_dump api_one_eid_table_dump
18884
18885 static int
18886 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18887 {
18888   unformat_input_t *i = vam->input;
18889   vl_api_gpe_fwd_entries_get_t *mp;
18890   u8 vni_set = 0;
18891   u32 vni = ~0;
18892   int ret;
18893
18894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18895     {
18896       if (unformat (i, "vni %d", &vni))
18897         {
18898           vni_set = 1;
18899         }
18900       else
18901         {
18902           errmsg ("parse error '%U'", format_unformat_error, i);
18903           return -99;
18904         }
18905     }
18906
18907   if (!vni_set)
18908     {
18909       errmsg ("vni not set!");
18910       return -99;
18911     }
18912
18913   if (!vam->json_output)
18914     {
18915       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18916              "leid", "reid");
18917     }
18918
18919   M (GPE_FWD_ENTRIES_GET, mp);
18920   mp->vni = clib_host_to_net_u32 (vni);
18921
18922   /* send it... */
18923   S (mp);
18924
18925   /* Wait for a reply... */
18926   W (ret);
18927   return ret;
18928 }
18929
18930 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18931 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18932 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18933 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18934 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18935 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18936 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18937 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18938
18939 static int
18940 api_one_adjacencies_get (vat_main_t * vam)
18941 {
18942   unformat_input_t *i = vam->input;
18943   vl_api_one_adjacencies_get_t *mp;
18944   u8 vni_set = 0;
18945   u32 vni = ~0;
18946   int ret;
18947
18948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18949     {
18950       if (unformat (i, "vni %d", &vni))
18951         {
18952           vni_set = 1;
18953         }
18954       else
18955         {
18956           errmsg ("parse error '%U'", format_unformat_error, i);
18957           return -99;
18958         }
18959     }
18960
18961   if (!vni_set)
18962     {
18963       errmsg ("vni not set!");
18964       return -99;
18965     }
18966
18967   if (!vam->json_output)
18968     {
18969       print (vam->ofp, "%s %40s", "leid", "reid");
18970     }
18971
18972   M (ONE_ADJACENCIES_GET, mp);
18973   mp->vni = clib_host_to_net_u32 (vni);
18974
18975   /* send it... */
18976   S (mp);
18977
18978   /* Wait for a reply... */
18979   W (ret);
18980   return ret;
18981 }
18982
18983 #define api_lisp_adjacencies_get api_one_adjacencies_get
18984
18985 static int
18986 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18987 {
18988   unformat_input_t *i = vam->input;
18989   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18990   int ret;
18991   u8 ip_family_set = 0, is_ip4 = 1;
18992
18993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18994     {
18995       if (unformat (i, "ip4"))
18996         {
18997           ip_family_set = 1;
18998           is_ip4 = 1;
18999         }
19000       else if (unformat (i, "ip6"))
19001         {
19002           ip_family_set = 1;
19003           is_ip4 = 0;
19004         }
19005       else
19006         {
19007           errmsg ("parse error '%U'", format_unformat_error, i);
19008           return -99;
19009         }
19010     }
19011
19012   if (!ip_family_set)
19013     {
19014       errmsg ("ip family not set!");
19015       return -99;
19016     }
19017
19018   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19019   mp->is_ip4 = is_ip4;
19020
19021   /* send it... */
19022   S (mp);
19023
19024   /* Wait for a reply... */
19025   W (ret);
19026   return ret;
19027 }
19028
19029 static int
19030 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19031 {
19032   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19033   int ret;
19034
19035   if (!vam->json_output)
19036     {
19037       print (vam->ofp, "VNIs");
19038     }
19039
19040   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19041
19042   /* send it... */
19043   S (mp);
19044
19045   /* Wait for a reply... */
19046   W (ret);
19047   return ret;
19048 }
19049
19050 static int
19051 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19052 {
19053   unformat_input_t *i = vam->input;
19054   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19055   int ret = 0;
19056   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19057   struct in_addr ip4;
19058   struct in6_addr ip6;
19059   u32 table_id = 0, nh_sw_if_index = ~0;
19060
19061   clib_memset (&ip4, 0, sizeof (ip4));
19062   clib_memset (&ip6, 0, sizeof (ip6));
19063
19064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19065     {
19066       if (unformat (i, "del"))
19067         is_add = 0;
19068       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19069                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19070         {
19071           ip_set = 1;
19072           is_ip4 = 1;
19073         }
19074       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19075                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19076         {
19077           ip_set = 1;
19078           is_ip4 = 0;
19079         }
19080       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19081         {
19082           ip_set = 1;
19083           is_ip4 = 1;
19084           nh_sw_if_index = ~0;
19085         }
19086       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19087         {
19088           ip_set = 1;
19089           is_ip4 = 0;
19090           nh_sw_if_index = ~0;
19091         }
19092       else if (unformat (i, "table %d", &table_id))
19093         ;
19094       else
19095         {
19096           errmsg ("parse error '%U'", format_unformat_error, i);
19097           return -99;
19098         }
19099     }
19100
19101   if (!ip_set)
19102     {
19103       errmsg ("nh addr not set!");
19104       return -99;
19105     }
19106
19107   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19108   mp->is_add = is_add;
19109   mp->table_id = clib_host_to_net_u32 (table_id);
19110   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19111   mp->is_ip4 = is_ip4;
19112   if (is_ip4)
19113     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19114   else
19115     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19116
19117   /* send it... */
19118   S (mp);
19119
19120   /* Wait for a reply... */
19121   W (ret);
19122   return ret;
19123 }
19124
19125 static int
19126 api_one_map_server_dump (vat_main_t * vam)
19127 {
19128   vl_api_one_map_server_dump_t *mp;
19129   vl_api_control_ping_t *mp_ping;
19130   int ret;
19131
19132   if (!vam->json_output)
19133     {
19134       print (vam->ofp, "%=20s", "Map server");
19135     }
19136
19137   M (ONE_MAP_SERVER_DUMP, mp);
19138   /* send it... */
19139   S (mp);
19140
19141   /* Use a control ping for synchronization */
19142   MPING (CONTROL_PING, mp_ping);
19143   S (mp_ping);
19144
19145   /* Wait for a reply... */
19146   W (ret);
19147   return ret;
19148 }
19149
19150 #define api_lisp_map_server_dump api_one_map_server_dump
19151
19152 static int
19153 api_one_map_resolver_dump (vat_main_t * vam)
19154 {
19155   vl_api_one_map_resolver_dump_t *mp;
19156   vl_api_control_ping_t *mp_ping;
19157   int ret;
19158
19159   if (!vam->json_output)
19160     {
19161       print (vam->ofp, "%=20s", "Map resolver");
19162     }
19163
19164   M (ONE_MAP_RESOLVER_DUMP, mp);
19165   /* send it... */
19166   S (mp);
19167
19168   /* Use a control ping for synchronization */
19169   MPING (CONTROL_PING, mp_ping);
19170   S (mp_ping);
19171
19172   /* Wait for a reply... */
19173   W (ret);
19174   return ret;
19175 }
19176
19177 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19178
19179 static int
19180 api_one_stats_flush (vat_main_t * vam)
19181 {
19182   vl_api_one_stats_flush_t *mp;
19183   int ret = 0;
19184
19185   M (ONE_STATS_FLUSH, mp);
19186   S (mp);
19187   W (ret);
19188   return ret;
19189 }
19190
19191 static int
19192 api_one_stats_dump (vat_main_t * vam)
19193 {
19194   vl_api_one_stats_dump_t *mp;
19195   vl_api_control_ping_t *mp_ping;
19196   int ret;
19197
19198   M (ONE_STATS_DUMP, mp);
19199   /* send it... */
19200   S (mp);
19201
19202   /* Use a control ping for synchronization */
19203   MPING (CONTROL_PING, mp_ping);
19204   S (mp_ping);
19205
19206   /* Wait for a reply... */
19207   W (ret);
19208   return ret;
19209 }
19210
19211 static int
19212 api_show_one_status (vat_main_t * vam)
19213 {
19214   vl_api_show_one_status_t *mp;
19215   int ret;
19216
19217   if (!vam->json_output)
19218     {
19219       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19220     }
19221
19222   M (SHOW_ONE_STATUS, mp);
19223   /* send it... */
19224   S (mp);
19225   /* Wait for a reply... */
19226   W (ret);
19227   return ret;
19228 }
19229
19230 #define api_show_lisp_status api_show_one_status
19231
19232 static int
19233 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19234 {
19235   vl_api_gpe_fwd_entry_path_dump_t *mp;
19236   vl_api_control_ping_t *mp_ping;
19237   unformat_input_t *i = vam->input;
19238   u32 fwd_entry_index = ~0;
19239   int ret;
19240
19241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19242     {
19243       if (unformat (i, "index %d", &fwd_entry_index))
19244         ;
19245       else
19246         break;
19247     }
19248
19249   if (~0 == fwd_entry_index)
19250     {
19251       errmsg ("no index specified!");
19252       return -99;
19253     }
19254
19255   if (!vam->json_output)
19256     {
19257       print (vam->ofp, "first line");
19258     }
19259
19260   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19261
19262   /* send it... */
19263   S (mp);
19264   /* Use a control ping for synchronization */
19265   MPING (CONTROL_PING, mp_ping);
19266   S (mp_ping);
19267
19268   /* Wait for a reply... */
19269   W (ret);
19270   return ret;
19271 }
19272
19273 static int
19274 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19275 {
19276   vl_api_one_get_map_request_itr_rlocs_t *mp;
19277   int ret;
19278
19279   if (!vam->json_output)
19280     {
19281       print (vam->ofp, "%=20s", "itr-rlocs:");
19282     }
19283
19284   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19285   /* send it... */
19286   S (mp);
19287   /* Wait for a reply... */
19288   W (ret);
19289   return ret;
19290 }
19291
19292 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19293
19294 static int
19295 api_af_packet_create (vat_main_t * vam)
19296 {
19297   unformat_input_t *i = vam->input;
19298   vl_api_af_packet_create_t *mp;
19299   u8 *host_if_name = 0;
19300   u8 hw_addr[6];
19301   u8 random_hw_addr = 1;
19302   int ret;
19303
19304   clib_memset (hw_addr, 0, sizeof (hw_addr));
19305
19306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19307     {
19308       if (unformat (i, "name %s", &host_if_name))
19309         vec_add1 (host_if_name, 0);
19310       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19311         random_hw_addr = 0;
19312       else
19313         break;
19314     }
19315
19316   if (!vec_len (host_if_name))
19317     {
19318       errmsg ("host-interface name must be specified");
19319       return -99;
19320     }
19321
19322   if (vec_len (host_if_name) > 64)
19323     {
19324       errmsg ("host-interface name too long");
19325       return -99;
19326     }
19327
19328   M (AF_PACKET_CREATE, mp);
19329
19330   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19331   clib_memcpy (mp->hw_addr, hw_addr, 6);
19332   mp->use_random_hw_addr = random_hw_addr;
19333   vec_free (host_if_name);
19334
19335   S (mp);
19336
19337   /* *INDENT-OFF* */
19338   W2 (ret,
19339       ({
19340         if (ret == 0)
19341           fprintf (vam->ofp ? vam->ofp : stderr,
19342                    " new sw_if_index = %d\n", vam->sw_if_index);
19343       }));
19344   /* *INDENT-ON* */
19345   return ret;
19346 }
19347
19348 static int
19349 api_af_packet_delete (vat_main_t * vam)
19350 {
19351   unformat_input_t *i = vam->input;
19352   vl_api_af_packet_delete_t *mp;
19353   u8 *host_if_name = 0;
19354   int ret;
19355
19356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19357     {
19358       if (unformat (i, "name %s", &host_if_name))
19359         vec_add1 (host_if_name, 0);
19360       else
19361         break;
19362     }
19363
19364   if (!vec_len (host_if_name))
19365     {
19366       errmsg ("host-interface name must be specified");
19367       return -99;
19368     }
19369
19370   if (vec_len (host_if_name) > 64)
19371     {
19372       errmsg ("host-interface name too long");
19373       return -99;
19374     }
19375
19376   M (AF_PACKET_DELETE, mp);
19377
19378   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19379   vec_free (host_if_name);
19380
19381   S (mp);
19382   W (ret);
19383   return ret;
19384 }
19385
19386 static void vl_api_af_packet_details_t_handler
19387   (vl_api_af_packet_details_t * mp)
19388 {
19389   vat_main_t *vam = &vat_main;
19390
19391   print (vam->ofp, "%-16s %d",
19392          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19393 }
19394
19395 static void vl_api_af_packet_details_t_handler_json
19396   (vl_api_af_packet_details_t * mp)
19397 {
19398   vat_main_t *vam = &vat_main;
19399   vat_json_node_t *node = NULL;
19400
19401   if (VAT_JSON_ARRAY != vam->json_tree.type)
19402     {
19403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19404       vat_json_init_array (&vam->json_tree);
19405     }
19406   node = vat_json_array_add (&vam->json_tree);
19407
19408   vat_json_init_object (node);
19409   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19410   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19411 }
19412
19413 static int
19414 api_af_packet_dump (vat_main_t * vam)
19415 {
19416   vl_api_af_packet_dump_t *mp;
19417   vl_api_control_ping_t *mp_ping;
19418   int ret;
19419
19420   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19421   /* Get list of tap interfaces */
19422   M (AF_PACKET_DUMP, mp);
19423   S (mp);
19424
19425   /* Use a control ping for synchronization */
19426   MPING (CONTROL_PING, mp_ping);
19427   S (mp_ping);
19428
19429   W (ret);
19430   return ret;
19431 }
19432
19433 static int
19434 api_policer_add_del (vat_main_t * vam)
19435 {
19436   unformat_input_t *i = vam->input;
19437   vl_api_policer_add_del_t *mp;
19438   u8 is_add = 1;
19439   u8 *name = 0;
19440   u32 cir = 0;
19441   u32 eir = 0;
19442   u64 cb = 0;
19443   u64 eb = 0;
19444   u8 rate_type = 0;
19445   u8 round_type = 0;
19446   u8 type = 0;
19447   u8 color_aware = 0;
19448   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19449   int ret;
19450
19451   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19452   conform_action.dscp = 0;
19453   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19454   exceed_action.dscp = 0;
19455   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19456   violate_action.dscp = 0;
19457
19458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19459     {
19460       if (unformat (i, "del"))
19461         is_add = 0;
19462       else if (unformat (i, "name %s", &name))
19463         vec_add1 (name, 0);
19464       else if (unformat (i, "cir %u", &cir))
19465         ;
19466       else if (unformat (i, "eir %u", &eir))
19467         ;
19468       else if (unformat (i, "cb %u", &cb))
19469         ;
19470       else if (unformat (i, "eb %u", &eb))
19471         ;
19472       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19473                          &rate_type))
19474         ;
19475       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19476                          &round_type))
19477         ;
19478       else if (unformat (i, "type %U", unformat_policer_type, &type))
19479         ;
19480       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19481                          &conform_action))
19482         ;
19483       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19484                          &exceed_action))
19485         ;
19486       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19487                          &violate_action))
19488         ;
19489       else if (unformat (i, "color-aware"))
19490         color_aware = 1;
19491       else
19492         break;
19493     }
19494
19495   if (!vec_len (name))
19496     {
19497       errmsg ("policer name must be specified");
19498       return -99;
19499     }
19500
19501   if (vec_len (name) > 64)
19502     {
19503       errmsg ("policer name too long");
19504       return -99;
19505     }
19506
19507   M (POLICER_ADD_DEL, mp);
19508
19509   clib_memcpy (mp->name, name, vec_len (name));
19510   vec_free (name);
19511   mp->is_add = is_add;
19512   mp->cir = ntohl (cir);
19513   mp->eir = ntohl (eir);
19514   mp->cb = clib_net_to_host_u64 (cb);
19515   mp->eb = clib_net_to_host_u64 (eb);
19516   mp->rate_type = rate_type;
19517   mp->round_type = round_type;
19518   mp->type = type;
19519   mp->conform_action_type = conform_action.action_type;
19520   mp->conform_dscp = conform_action.dscp;
19521   mp->exceed_action_type = exceed_action.action_type;
19522   mp->exceed_dscp = exceed_action.dscp;
19523   mp->violate_action_type = violate_action.action_type;
19524   mp->violate_dscp = violate_action.dscp;
19525   mp->color_aware = color_aware;
19526
19527   S (mp);
19528   W (ret);
19529   return ret;
19530 }
19531
19532 static int
19533 api_policer_dump (vat_main_t * vam)
19534 {
19535   unformat_input_t *i = vam->input;
19536   vl_api_policer_dump_t *mp;
19537   vl_api_control_ping_t *mp_ping;
19538   u8 *match_name = 0;
19539   u8 match_name_valid = 0;
19540   int ret;
19541
19542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19543     {
19544       if (unformat (i, "name %s", &match_name))
19545         {
19546           vec_add1 (match_name, 0);
19547           match_name_valid = 1;
19548         }
19549       else
19550         break;
19551     }
19552
19553   M (POLICER_DUMP, mp);
19554   mp->match_name_valid = match_name_valid;
19555   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19556   vec_free (match_name);
19557   /* send it... */
19558   S (mp);
19559
19560   /* Use a control ping for synchronization */
19561   MPING (CONTROL_PING, mp_ping);
19562   S (mp_ping);
19563
19564   /* Wait for a reply... */
19565   W (ret);
19566   return ret;
19567 }
19568
19569 static int
19570 api_policer_classify_set_interface (vat_main_t * vam)
19571 {
19572   unformat_input_t *i = vam->input;
19573   vl_api_policer_classify_set_interface_t *mp;
19574   u32 sw_if_index;
19575   int sw_if_index_set;
19576   u32 ip4_table_index = ~0;
19577   u32 ip6_table_index = ~0;
19578   u32 l2_table_index = ~0;
19579   u8 is_add = 1;
19580   int ret;
19581
19582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19583     {
19584       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19585         sw_if_index_set = 1;
19586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19587         sw_if_index_set = 1;
19588       else if (unformat (i, "del"))
19589         is_add = 0;
19590       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19591         ;
19592       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19593         ;
19594       else if (unformat (i, "l2-table %d", &l2_table_index))
19595         ;
19596       else
19597         {
19598           clib_warning ("parse error '%U'", format_unformat_error, i);
19599           return -99;
19600         }
19601     }
19602
19603   if (sw_if_index_set == 0)
19604     {
19605       errmsg ("missing interface name or sw_if_index");
19606       return -99;
19607     }
19608
19609   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19610
19611   mp->sw_if_index = ntohl (sw_if_index);
19612   mp->ip4_table_index = ntohl (ip4_table_index);
19613   mp->ip6_table_index = ntohl (ip6_table_index);
19614   mp->l2_table_index = ntohl (l2_table_index);
19615   mp->is_add = is_add;
19616
19617   S (mp);
19618   W (ret);
19619   return ret;
19620 }
19621
19622 static int
19623 api_policer_classify_dump (vat_main_t * vam)
19624 {
19625   unformat_input_t *i = vam->input;
19626   vl_api_policer_classify_dump_t *mp;
19627   vl_api_control_ping_t *mp_ping;
19628   u8 type = POLICER_CLASSIFY_N_TABLES;
19629   int ret;
19630
19631   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19632     ;
19633   else
19634     {
19635       errmsg ("classify table type must be specified");
19636       return -99;
19637     }
19638
19639   if (!vam->json_output)
19640     {
19641       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19642     }
19643
19644   M (POLICER_CLASSIFY_DUMP, mp);
19645   mp->type = type;
19646   /* send it... */
19647   S (mp);
19648
19649   /* Use a control ping for synchronization */
19650   MPING (CONTROL_PING, mp_ping);
19651   S (mp_ping);
19652
19653   /* Wait for a reply... */
19654   W (ret);
19655   return ret;
19656 }
19657
19658 static int
19659 api_netmap_create (vat_main_t * vam)
19660 {
19661   unformat_input_t *i = vam->input;
19662   vl_api_netmap_create_t *mp;
19663   u8 *if_name = 0;
19664   u8 hw_addr[6];
19665   u8 random_hw_addr = 1;
19666   u8 is_pipe = 0;
19667   u8 is_master = 0;
19668   int ret;
19669
19670   clib_memset (hw_addr, 0, sizeof (hw_addr));
19671
19672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19673     {
19674       if (unformat (i, "name %s", &if_name))
19675         vec_add1 (if_name, 0);
19676       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19677         random_hw_addr = 0;
19678       else if (unformat (i, "pipe"))
19679         is_pipe = 1;
19680       else if (unformat (i, "master"))
19681         is_master = 1;
19682       else if (unformat (i, "slave"))
19683         is_master = 0;
19684       else
19685         break;
19686     }
19687
19688   if (!vec_len (if_name))
19689     {
19690       errmsg ("interface name must be specified");
19691       return -99;
19692     }
19693
19694   if (vec_len (if_name) > 64)
19695     {
19696       errmsg ("interface name too long");
19697       return -99;
19698     }
19699
19700   M (NETMAP_CREATE, mp);
19701
19702   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19703   clib_memcpy (mp->hw_addr, hw_addr, 6);
19704   mp->use_random_hw_addr = random_hw_addr;
19705   mp->is_pipe = is_pipe;
19706   mp->is_master = is_master;
19707   vec_free (if_name);
19708
19709   S (mp);
19710   W (ret);
19711   return ret;
19712 }
19713
19714 static int
19715 api_netmap_delete (vat_main_t * vam)
19716 {
19717   unformat_input_t *i = vam->input;
19718   vl_api_netmap_delete_t *mp;
19719   u8 *if_name = 0;
19720   int ret;
19721
19722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19723     {
19724       if (unformat (i, "name %s", &if_name))
19725         vec_add1 (if_name, 0);
19726       else
19727         break;
19728     }
19729
19730   if (!vec_len (if_name))
19731     {
19732       errmsg ("interface name must be specified");
19733       return -99;
19734     }
19735
19736   if (vec_len (if_name) > 64)
19737     {
19738       errmsg ("interface name too long");
19739       return -99;
19740     }
19741
19742   M (NETMAP_DELETE, mp);
19743
19744   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19745   vec_free (if_name);
19746
19747   S (mp);
19748   W (ret);
19749   return ret;
19750 }
19751
19752 static void
19753 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19754 {
19755   if (fp->afi == IP46_TYPE_IP6)
19756     print (vam->ofp,
19757            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19758            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19759            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19760            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19761            format_ip6_address, fp->next_hop);
19762   else if (fp->afi == IP46_TYPE_IP4)
19763     print (vam->ofp,
19764            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19765            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19766            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19767            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19768            format_ip4_address, fp->next_hop);
19769 }
19770
19771 static void
19772 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19773                                  vl_api_fib_path_t * fp)
19774 {
19775   struct in_addr ip4;
19776   struct in6_addr ip6;
19777
19778   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19779   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19780   vat_json_object_add_uint (node, "is_local", fp->is_local);
19781   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19782   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19783   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19784   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19785   if (fp->afi == IP46_TYPE_IP4)
19786     {
19787       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19788       vat_json_object_add_ip4 (node, "next_hop", ip4);
19789     }
19790   else if (fp->afi == IP46_TYPE_IP6)
19791     {
19792       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19793       vat_json_object_add_ip6 (node, "next_hop", ip6);
19794     }
19795 }
19796
19797 static void
19798 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19799 {
19800   vat_main_t *vam = &vat_main;
19801   int count = ntohl (mp->mt_count);
19802   vl_api_fib_path_t *fp;
19803   i32 i;
19804
19805   print (vam->ofp, "[%d]: sw_if_index %d via:",
19806          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19807   fp = mp->mt_paths;
19808   for (i = 0; i < count; i++)
19809     {
19810       vl_api_mpls_fib_path_print (vam, fp);
19811       fp++;
19812     }
19813
19814   print (vam->ofp, "");
19815 }
19816
19817 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19818 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19819
19820 static void
19821 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19822 {
19823   vat_main_t *vam = &vat_main;
19824   vat_json_node_t *node = NULL;
19825   int count = ntohl (mp->mt_count);
19826   vl_api_fib_path_t *fp;
19827   i32 i;
19828
19829   if (VAT_JSON_ARRAY != vam->json_tree.type)
19830     {
19831       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19832       vat_json_init_array (&vam->json_tree);
19833     }
19834   node = vat_json_array_add (&vam->json_tree);
19835
19836   vat_json_init_object (node);
19837   vat_json_object_add_uint (node, "tunnel_index",
19838                             ntohl (mp->mt_tunnel_index));
19839   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19840
19841   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19842
19843   fp = mp->mt_paths;
19844   for (i = 0; i < count; i++)
19845     {
19846       vl_api_mpls_fib_path_json_print (node, fp);
19847       fp++;
19848     }
19849 }
19850
19851 static int
19852 api_mpls_tunnel_dump (vat_main_t * vam)
19853 {
19854   vl_api_mpls_tunnel_dump_t *mp;
19855   vl_api_control_ping_t *mp_ping;
19856   u32 sw_if_index = ~0;
19857   int ret;
19858
19859   /* Parse args required to build the message */
19860   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19861     {
19862       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19863         ;
19864     }
19865
19866   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19867
19868   M (MPLS_TUNNEL_DUMP, mp);
19869   mp->sw_if_index = htonl (sw_if_index);
19870   S (mp);
19871
19872   /* Use a control ping for synchronization */
19873   MPING (CONTROL_PING, mp_ping);
19874   S (mp_ping);
19875
19876   W (ret);
19877   return ret;
19878 }
19879
19880 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19881 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19882
19883
19884 static void
19885 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19886 {
19887   vat_main_t *vam = &vat_main;
19888   int count = ntohl (mp->count);
19889   vl_api_fib_path_t *fp;
19890   int i;
19891
19892   print (vam->ofp,
19893          "table-id %d, label %u, ess_bit %u",
19894          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19895   fp = mp->path;
19896   for (i = 0; i < count; i++)
19897     {
19898       vl_api_mpls_fib_path_print (vam, fp);
19899       fp++;
19900     }
19901 }
19902
19903 static void vl_api_mpls_fib_details_t_handler_json
19904   (vl_api_mpls_fib_details_t * mp)
19905 {
19906   vat_main_t *vam = &vat_main;
19907   int count = ntohl (mp->count);
19908   vat_json_node_t *node = NULL;
19909   vl_api_fib_path_t *fp;
19910   int i;
19911
19912   if (VAT_JSON_ARRAY != vam->json_tree.type)
19913     {
19914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19915       vat_json_init_array (&vam->json_tree);
19916     }
19917   node = vat_json_array_add (&vam->json_tree);
19918
19919   vat_json_init_object (node);
19920   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19921   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19922   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19923   vat_json_object_add_uint (node, "path_count", count);
19924   fp = mp->path;
19925   for (i = 0; i < count; i++)
19926     {
19927       vl_api_mpls_fib_path_json_print (node, fp);
19928       fp++;
19929     }
19930 }
19931
19932 static int
19933 api_mpls_fib_dump (vat_main_t * vam)
19934 {
19935   vl_api_mpls_fib_dump_t *mp;
19936   vl_api_control_ping_t *mp_ping;
19937   int ret;
19938
19939   M (MPLS_FIB_DUMP, mp);
19940   S (mp);
19941
19942   /* Use a control ping for synchronization */
19943   MPING (CONTROL_PING, mp_ping);
19944   S (mp_ping);
19945
19946   W (ret);
19947   return ret;
19948 }
19949
19950 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19951 #define vl_api_ip_fib_details_t_print vl_noop_handler
19952
19953 static void
19954 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19955 {
19956   vat_main_t *vam = &vat_main;
19957   int count = ntohl (mp->count);
19958   vl_api_fib_path_t *fp;
19959   int i;
19960
19961   print (vam->ofp,
19962          "table-id %d, prefix %U/%d stats-index %d",
19963          ntohl (mp->table_id), format_ip4_address, mp->address,
19964          mp->address_length, ntohl (mp->stats_index));
19965   fp = mp->path;
19966   for (i = 0; i < count; i++)
19967     {
19968       if (fp->afi == IP46_TYPE_IP6)
19969         print (vam->ofp,
19970                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19971                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19972                "next_hop_table %d",
19973                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19974                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19975                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19976       else if (fp->afi == IP46_TYPE_IP4)
19977         print (vam->ofp,
19978                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19979                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19980                "next_hop_table %d",
19981                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19982                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19983                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19984       fp++;
19985     }
19986 }
19987
19988 static void vl_api_ip_fib_details_t_handler_json
19989   (vl_api_ip_fib_details_t * mp)
19990 {
19991   vat_main_t *vam = &vat_main;
19992   int count = ntohl (mp->count);
19993   vat_json_node_t *node = NULL;
19994   struct in_addr ip4;
19995   struct in6_addr ip6;
19996   vl_api_fib_path_t *fp;
19997   int i;
19998
19999   if (VAT_JSON_ARRAY != vam->json_tree.type)
20000     {
20001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20002       vat_json_init_array (&vam->json_tree);
20003     }
20004   node = vat_json_array_add (&vam->json_tree);
20005
20006   vat_json_init_object (node);
20007   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20008   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20009   vat_json_object_add_ip4 (node, "prefix", ip4);
20010   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20011   vat_json_object_add_uint (node, "path_count", count);
20012   fp = mp->path;
20013   for (i = 0; i < count; i++)
20014     {
20015       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20016       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20017       vat_json_object_add_uint (node, "is_local", fp->is_local);
20018       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20019       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20020       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20021       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20022       if (fp->afi == IP46_TYPE_IP4)
20023         {
20024           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20025           vat_json_object_add_ip4 (node, "next_hop", ip4);
20026         }
20027       else if (fp->afi == IP46_TYPE_IP6)
20028         {
20029           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20030           vat_json_object_add_ip6 (node, "next_hop", ip6);
20031         }
20032     }
20033 }
20034
20035 static int
20036 api_ip_fib_dump (vat_main_t * vam)
20037 {
20038   vl_api_ip_fib_dump_t *mp;
20039   vl_api_control_ping_t *mp_ping;
20040   int ret;
20041
20042   M (IP_FIB_DUMP, mp);
20043   S (mp);
20044
20045   /* Use a control ping for synchronization */
20046   MPING (CONTROL_PING, mp_ping);
20047   S (mp_ping);
20048
20049   W (ret);
20050   return ret;
20051 }
20052
20053 static int
20054 api_ip_mfib_dump (vat_main_t * vam)
20055 {
20056   vl_api_ip_mfib_dump_t *mp;
20057   vl_api_control_ping_t *mp_ping;
20058   int ret;
20059
20060   M (IP_MFIB_DUMP, mp);
20061   S (mp);
20062
20063   /* Use a control ping for synchronization */
20064   MPING (CONTROL_PING, mp_ping);
20065   S (mp_ping);
20066
20067   W (ret);
20068   return ret;
20069 }
20070
20071 static void vl_api_ip_neighbor_details_t_handler
20072   (vl_api_ip_neighbor_details_t * mp)
20073 {
20074   vat_main_t *vam = &vat_main;
20075
20076   print (vam->ofp, "%c %U %U",
20077          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
20078          format_vl_api_mac_address, &mp->neighbor.mac_address,
20079          format_vl_api_address, &mp->neighbor.ip_address);
20080 }
20081
20082 static void vl_api_ip_neighbor_details_t_handler_json
20083   (vl_api_ip_neighbor_details_t * mp)
20084 {
20085
20086   vat_main_t *vam = &vat_main;
20087   vat_json_node_t *node;
20088   struct in_addr ip4;
20089   struct in6_addr ip6;
20090
20091   if (VAT_JSON_ARRAY != vam->json_tree.type)
20092     {
20093       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20094       vat_json_init_array (&vam->json_tree);
20095     }
20096   node = vat_json_array_add (&vam->json_tree);
20097
20098   vat_json_init_object (node);
20099   vat_json_object_add_string_copy
20100     (node, "flag",
20101      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
20102       (u8 *) "static" : (u8 *) "dynamic"));
20103
20104   vat_json_object_add_string_copy (node, "link_layer",
20105                                    format (0, "%U", format_vl_api_mac_address,
20106                                            &mp->neighbor.mac_address));
20107
20108   if (ADDRESS_IP6 == mp->neighbor.ip_address.af)
20109     {
20110       clib_memcpy (&ip6, &mp->neighbor.ip_address.un.ip6, sizeof (ip6));
20111       vat_json_object_add_ip6 (node, "ip_address", ip6);
20112     }
20113   else
20114     {
20115       clib_memcpy (&ip4, &mp->neighbor.ip_address.un.ip4, sizeof (ip4));
20116       vat_json_object_add_ip4 (node, "ip_address", ip4);
20117     }
20118 }
20119
20120 static int
20121 api_ip_neighbor_dump (vat_main_t * vam)
20122 {
20123   unformat_input_t *i = vam->input;
20124   vl_api_ip_neighbor_dump_t *mp;
20125   vl_api_control_ping_t *mp_ping;
20126   u8 is_ipv6 = 0;
20127   u32 sw_if_index = ~0;
20128   int ret;
20129
20130   /* Parse args required to build the message */
20131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20132     {
20133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20134         ;
20135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20136         ;
20137       else if (unformat (i, "ip6"))
20138         is_ipv6 = 1;
20139       else
20140         break;
20141     }
20142
20143   if (sw_if_index == ~0)
20144     {
20145       errmsg ("missing interface name or sw_if_index");
20146       return -99;
20147     }
20148
20149   M (IP_NEIGHBOR_DUMP, mp);
20150   mp->is_ipv6 = (u8) is_ipv6;
20151   mp->sw_if_index = ntohl (sw_if_index);
20152   S (mp);
20153
20154   /* Use a control ping for synchronization */
20155   MPING (CONTROL_PING, mp_ping);
20156   S (mp_ping);
20157
20158   W (ret);
20159   return ret;
20160 }
20161
20162 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20163 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20164
20165 static void
20166 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20167 {
20168   vat_main_t *vam = &vat_main;
20169   int count = ntohl (mp->count);
20170   vl_api_fib_path_t *fp;
20171   int i;
20172
20173   print (vam->ofp,
20174          "table-id %d, prefix %U/%d stats-index %d",
20175          ntohl (mp->table_id), format_ip6_address, mp->address,
20176          mp->address_length, ntohl (mp->stats_index));
20177   fp = mp->path;
20178   for (i = 0; i < count; i++)
20179     {
20180       if (fp->afi == IP46_TYPE_IP6)
20181         print (vam->ofp,
20182                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20183                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20184                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20185                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20186                format_ip6_address, fp->next_hop);
20187       else if (fp->afi == IP46_TYPE_IP4)
20188         print (vam->ofp,
20189                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20190                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20191                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20192                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20193                format_ip4_address, fp->next_hop);
20194       fp++;
20195     }
20196 }
20197
20198 static void vl_api_ip6_fib_details_t_handler_json
20199   (vl_api_ip6_fib_details_t * mp)
20200 {
20201   vat_main_t *vam = &vat_main;
20202   int count = ntohl (mp->count);
20203   vat_json_node_t *node = NULL;
20204   struct in_addr ip4;
20205   struct in6_addr ip6;
20206   vl_api_fib_path_t *fp;
20207   int i;
20208
20209   if (VAT_JSON_ARRAY != vam->json_tree.type)
20210     {
20211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20212       vat_json_init_array (&vam->json_tree);
20213     }
20214   node = vat_json_array_add (&vam->json_tree);
20215
20216   vat_json_init_object (node);
20217   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20218   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20219   vat_json_object_add_ip6 (node, "prefix", ip6);
20220   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20221   vat_json_object_add_uint (node, "path_count", count);
20222   fp = mp->path;
20223   for (i = 0; i < count; i++)
20224     {
20225       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20226       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20227       vat_json_object_add_uint (node, "is_local", fp->is_local);
20228       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20229       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20230       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20231       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20232       if (fp->afi == IP46_TYPE_IP4)
20233         {
20234           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20235           vat_json_object_add_ip4 (node, "next_hop", ip4);
20236         }
20237       else if (fp->afi == IP46_TYPE_IP6)
20238         {
20239           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20240           vat_json_object_add_ip6 (node, "next_hop", ip6);
20241         }
20242     }
20243 }
20244
20245 static int
20246 api_ip6_fib_dump (vat_main_t * vam)
20247 {
20248   vl_api_ip6_fib_dump_t *mp;
20249   vl_api_control_ping_t *mp_ping;
20250   int ret;
20251
20252   M (IP6_FIB_DUMP, mp);
20253   S (mp);
20254
20255   /* Use a control ping for synchronization */
20256   MPING (CONTROL_PING, mp_ping);
20257   S (mp_ping);
20258
20259   W (ret);
20260   return ret;
20261 }
20262
20263 static int
20264 api_ip6_mfib_dump (vat_main_t * vam)
20265 {
20266   vl_api_ip6_mfib_dump_t *mp;
20267   vl_api_control_ping_t *mp_ping;
20268   int ret;
20269
20270   M (IP6_MFIB_DUMP, mp);
20271   S (mp);
20272
20273   /* Use a control ping for synchronization */
20274   MPING (CONTROL_PING, mp_ping);
20275   S (mp_ping);
20276
20277   W (ret);
20278   return ret;
20279 }
20280
20281 int
20282 api_classify_table_ids (vat_main_t * vam)
20283 {
20284   vl_api_classify_table_ids_t *mp;
20285   int ret;
20286
20287   /* Construct the API message */
20288   M (CLASSIFY_TABLE_IDS, mp);
20289   mp->context = 0;
20290
20291   S (mp);
20292   W (ret);
20293   return ret;
20294 }
20295
20296 int
20297 api_classify_table_by_interface (vat_main_t * vam)
20298 {
20299   unformat_input_t *input = vam->input;
20300   vl_api_classify_table_by_interface_t *mp;
20301
20302   u32 sw_if_index = ~0;
20303   int ret;
20304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20305     {
20306       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20307         ;
20308       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20309         ;
20310       else
20311         break;
20312     }
20313   if (sw_if_index == ~0)
20314     {
20315       errmsg ("missing interface name or sw_if_index");
20316       return -99;
20317     }
20318
20319   /* Construct the API message */
20320   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20321   mp->context = 0;
20322   mp->sw_if_index = ntohl (sw_if_index);
20323
20324   S (mp);
20325   W (ret);
20326   return ret;
20327 }
20328
20329 int
20330 api_classify_table_info (vat_main_t * vam)
20331 {
20332   unformat_input_t *input = vam->input;
20333   vl_api_classify_table_info_t *mp;
20334
20335   u32 table_id = ~0;
20336   int ret;
20337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20338     {
20339       if (unformat (input, "table_id %d", &table_id))
20340         ;
20341       else
20342         break;
20343     }
20344   if (table_id == ~0)
20345     {
20346       errmsg ("missing table id");
20347       return -99;
20348     }
20349
20350   /* Construct the API message */
20351   M (CLASSIFY_TABLE_INFO, mp);
20352   mp->context = 0;
20353   mp->table_id = ntohl (table_id);
20354
20355   S (mp);
20356   W (ret);
20357   return ret;
20358 }
20359
20360 int
20361 api_classify_session_dump (vat_main_t * vam)
20362 {
20363   unformat_input_t *input = vam->input;
20364   vl_api_classify_session_dump_t *mp;
20365   vl_api_control_ping_t *mp_ping;
20366
20367   u32 table_id = ~0;
20368   int ret;
20369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20370     {
20371       if (unformat (input, "table_id %d", &table_id))
20372         ;
20373       else
20374         break;
20375     }
20376   if (table_id == ~0)
20377     {
20378       errmsg ("missing table id");
20379       return -99;
20380     }
20381
20382   /* Construct the API message */
20383   M (CLASSIFY_SESSION_DUMP, mp);
20384   mp->context = 0;
20385   mp->table_id = ntohl (table_id);
20386   S (mp);
20387
20388   /* Use a control ping for synchronization */
20389   MPING (CONTROL_PING, mp_ping);
20390   S (mp_ping);
20391
20392   W (ret);
20393   return ret;
20394 }
20395
20396 static void
20397 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20398 {
20399   vat_main_t *vam = &vat_main;
20400
20401   print (vam->ofp, "collector_address %U, collector_port %d, "
20402          "src_address %U, vrf_id %d, path_mtu %u, "
20403          "template_interval %u, udp_checksum %d",
20404          format_ip4_address, mp->collector_address,
20405          ntohs (mp->collector_port),
20406          format_ip4_address, mp->src_address,
20407          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20408          ntohl (mp->template_interval), mp->udp_checksum);
20409
20410   vam->retval = 0;
20411   vam->result_ready = 1;
20412 }
20413
20414 static void
20415   vl_api_ipfix_exporter_details_t_handler_json
20416   (vl_api_ipfix_exporter_details_t * mp)
20417 {
20418   vat_main_t *vam = &vat_main;
20419   vat_json_node_t node;
20420   struct in_addr collector_address;
20421   struct in_addr src_address;
20422
20423   vat_json_init_object (&node);
20424   clib_memcpy (&collector_address, &mp->collector_address,
20425                sizeof (collector_address));
20426   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20427   vat_json_object_add_uint (&node, "collector_port",
20428                             ntohs (mp->collector_port));
20429   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20430   vat_json_object_add_ip4 (&node, "src_address", src_address);
20431   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20432   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20433   vat_json_object_add_uint (&node, "template_interval",
20434                             ntohl (mp->template_interval));
20435   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20436
20437   vat_json_print (vam->ofp, &node);
20438   vat_json_free (&node);
20439   vam->retval = 0;
20440   vam->result_ready = 1;
20441 }
20442
20443 int
20444 api_ipfix_exporter_dump (vat_main_t * vam)
20445 {
20446   vl_api_ipfix_exporter_dump_t *mp;
20447   int ret;
20448
20449   /* Construct the API message */
20450   M (IPFIX_EXPORTER_DUMP, mp);
20451   mp->context = 0;
20452
20453   S (mp);
20454   W (ret);
20455   return ret;
20456 }
20457
20458 static int
20459 api_ipfix_classify_stream_dump (vat_main_t * vam)
20460 {
20461   vl_api_ipfix_classify_stream_dump_t *mp;
20462   int ret;
20463
20464   /* Construct the API message */
20465   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20466   mp->context = 0;
20467
20468   S (mp);
20469   W (ret);
20470   return ret;
20471   /* NOTREACHED */
20472   return 0;
20473 }
20474
20475 static void
20476   vl_api_ipfix_classify_stream_details_t_handler
20477   (vl_api_ipfix_classify_stream_details_t * mp)
20478 {
20479   vat_main_t *vam = &vat_main;
20480   print (vam->ofp, "domain_id %d, src_port %d",
20481          ntohl (mp->domain_id), ntohs (mp->src_port));
20482   vam->retval = 0;
20483   vam->result_ready = 1;
20484 }
20485
20486 static void
20487   vl_api_ipfix_classify_stream_details_t_handler_json
20488   (vl_api_ipfix_classify_stream_details_t * mp)
20489 {
20490   vat_main_t *vam = &vat_main;
20491   vat_json_node_t node;
20492
20493   vat_json_init_object (&node);
20494   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20495   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20496
20497   vat_json_print (vam->ofp, &node);
20498   vat_json_free (&node);
20499   vam->retval = 0;
20500   vam->result_ready = 1;
20501 }
20502
20503 static int
20504 api_ipfix_classify_table_dump (vat_main_t * vam)
20505 {
20506   vl_api_ipfix_classify_table_dump_t *mp;
20507   vl_api_control_ping_t *mp_ping;
20508   int ret;
20509
20510   if (!vam->json_output)
20511     {
20512       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20513              "transport_protocol");
20514     }
20515
20516   /* Construct the API message */
20517   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20518
20519   /* send it... */
20520   S (mp);
20521
20522   /* Use a control ping for synchronization */
20523   MPING (CONTROL_PING, mp_ping);
20524   S (mp_ping);
20525
20526   W (ret);
20527   return ret;
20528 }
20529
20530 static void
20531   vl_api_ipfix_classify_table_details_t_handler
20532   (vl_api_ipfix_classify_table_details_t * mp)
20533 {
20534   vat_main_t *vam = &vat_main;
20535   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20536          mp->transport_protocol);
20537 }
20538
20539 static void
20540   vl_api_ipfix_classify_table_details_t_handler_json
20541   (vl_api_ipfix_classify_table_details_t * mp)
20542 {
20543   vat_json_node_t *node = NULL;
20544   vat_main_t *vam = &vat_main;
20545
20546   if (VAT_JSON_ARRAY != vam->json_tree.type)
20547     {
20548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20549       vat_json_init_array (&vam->json_tree);
20550     }
20551
20552   node = vat_json_array_add (&vam->json_tree);
20553   vat_json_init_object (node);
20554
20555   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20556   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20557   vat_json_object_add_uint (node, "transport_protocol",
20558                             mp->transport_protocol);
20559 }
20560
20561 static int
20562 api_sw_interface_span_enable_disable (vat_main_t * vam)
20563 {
20564   unformat_input_t *i = vam->input;
20565   vl_api_sw_interface_span_enable_disable_t *mp;
20566   u32 src_sw_if_index = ~0;
20567   u32 dst_sw_if_index = ~0;
20568   u8 state = 3;
20569   int ret;
20570   u8 is_l2 = 0;
20571
20572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20573     {
20574       if (unformat
20575           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20576         ;
20577       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20578         ;
20579       else
20580         if (unformat
20581             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20582         ;
20583       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20584         ;
20585       else if (unformat (i, "disable"))
20586         state = 0;
20587       else if (unformat (i, "rx"))
20588         state = 1;
20589       else if (unformat (i, "tx"))
20590         state = 2;
20591       else if (unformat (i, "both"))
20592         state = 3;
20593       else if (unformat (i, "l2"))
20594         is_l2 = 1;
20595       else
20596         break;
20597     }
20598
20599   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20600
20601   mp->sw_if_index_from = htonl (src_sw_if_index);
20602   mp->sw_if_index_to = htonl (dst_sw_if_index);
20603   mp->state = state;
20604   mp->is_l2 = is_l2;
20605
20606   S (mp);
20607   W (ret);
20608   return ret;
20609 }
20610
20611 static void
20612 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20613                                             * mp)
20614 {
20615   vat_main_t *vam = &vat_main;
20616   u8 *sw_if_from_name = 0;
20617   u8 *sw_if_to_name = 0;
20618   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20619   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20620   char *states[] = { "none", "rx", "tx", "both" };
20621   hash_pair_t *p;
20622
20623   /* *INDENT-OFF* */
20624   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20625   ({
20626     if ((u32) p->value[0] == sw_if_index_from)
20627       {
20628         sw_if_from_name = (u8 *)(p->key);
20629         if (sw_if_to_name)
20630           break;
20631       }
20632     if ((u32) p->value[0] == sw_if_index_to)
20633       {
20634         sw_if_to_name = (u8 *)(p->key);
20635         if (sw_if_from_name)
20636           break;
20637       }
20638   }));
20639   /* *INDENT-ON* */
20640   print (vam->ofp, "%20s => %20s (%s) %s",
20641          sw_if_from_name, sw_if_to_name, states[mp->state],
20642          mp->is_l2 ? "l2" : "device");
20643 }
20644
20645 static void
20646   vl_api_sw_interface_span_details_t_handler_json
20647   (vl_api_sw_interface_span_details_t * mp)
20648 {
20649   vat_main_t *vam = &vat_main;
20650   vat_json_node_t *node = NULL;
20651   u8 *sw_if_from_name = 0;
20652   u8 *sw_if_to_name = 0;
20653   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20654   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20655   hash_pair_t *p;
20656
20657   /* *INDENT-OFF* */
20658   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20659   ({
20660     if ((u32) p->value[0] == sw_if_index_from)
20661       {
20662         sw_if_from_name = (u8 *)(p->key);
20663         if (sw_if_to_name)
20664           break;
20665       }
20666     if ((u32) p->value[0] == sw_if_index_to)
20667       {
20668         sw_if_to_name = (u8 *)(p->key);
20669         if (sw_if_from_name)
20670           break;
20671       }
20672   }));
20673   /* *INDENT-ON* */
20674
20675   if (VAT_JSON_ARRAY != vam->json_tree.type)
20676     {
20677       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20678       vat_json_init_array (&vam->json_tree);
20679     }
20680   node = vat_json_array_add (&vam->json_tree);
20681
20682   vat_json_init_object (node);
20683   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20684   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20685   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20686   if (0 != sw_if_to_name)
20687     {
20688       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20689     }
20690   vat_json_object_add_uint (node, "state", mp->state);
20691   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20692 }
20693
20694 static int
20695 api_sw_interface_span_dump (vat_main_t * vam)
20696 {
20697   unformat_input_t *input = vam->input;
20698   vl_api_sw_interface_span_dump_t *mp;
20699   vl_api_control_ping_t *mp_ping;
20700   u8 is_l2 = 0;
20701   int ret;
20702
20703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20704     {
20705       if (unformat (input, "l2"))
20706         is_l2 = 1;
20707       else
20708         break;
20709     }
20710
20711   M (SW_INTERFACE_SPAN_DUMP, mp);
20712   mp->is_l2 = is_l2;
20713   S (mp);
20714
20715   /* Use a control ping for synchronization */
20716   MPING (CONTROL_PING, mp_ping);
20717   S (mp_ping);
20718
20719   W (ret);
20720   return ret;
20721 }
20722
20723 int
20724 api_pg_create_interface (vat_main_t * vam)
20725 {
20726   unformat_input_t *input = vam->input;
20727   vl_api_pg_create_interface_t *mp;
20728
20729   u32 if_id = ~0;
20730   int ret;
20731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20732     {
20733       if (unformat (input, "if_id %d", &if_id))
20734         ;
20735       else
20736         break;
20737     }
20738   if (if_id == ~0)
20739     {
20740       errmsg ("missing pg interface index");
20741       return -99;
20742     }
20743
20744   /* Construct the API message */
20745   M (PG_CREATE_INTERFACE, mp);
20746   mp->context = 0;
20747   mp->interface_id = ntohl (if_id);
20748
20749   S (mp);
20750   W (ret);
20751   return ret;
20752 }
20753
20754 int
20755 api_pg_capture (vat_main_t * vam)
20756 {
20757   unformat_input_t *input = vam->input;
20758   vl_api_pg_capture_t *mp;
20759
20760   u32 if_id = ~0;
20761   u8 enable = 1;
20762   u32 count = 1;
20763   u8 pcap_file_set = 0;
20764   u8 *pcap_file = 0;
20765   int ret;
20766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20767     {
20768       if (unformat (input, "if_id %d", &if_id))
20769         ;
20770       else if (unformat (input, "pcap %s", &pcap_file))
20771         pcap_file_set = 1;
20772       else if (unformat (input, "count %d", &count))
20773         ;
20774       else if (unformat (input, "disable"))
20775         enable = 0;
20776       else
20777         break;
20778     }
20779   if (if_id == ~0)
20780     {
20781       errmsg ("missing pg interface index");
20782       return -99;
20783     }
20784   if (pcap_file_set > 0)
20785     {
20786       if (vec_len (pcap_file) > 255)
20787         {
20788           errmsg ("pcap file name is too long");
20789           return -99;
20790         }
20791     }
20792
20793   u32 name_len = vec_len (pcap_file);
20794   /* Construct the API message */
20795   M (PG_CAPTURE, mp);
20796   mp->context = 0;
20797   mp->interface_id = ntohl (if_id);
20798   mp->is_enabled = enable;
20799   mp->count = ntohl (count);
20800   mp->pcap_name_length = ntohl (name_len);
20801   if (pcap_file_set != 0)
20802     {
20803       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20804     }
20805   vec_free (pcap_file);
20806
20807   S (mp);
20808   W (ret);
20809   return ret;
20810 }
20811
20812 int
20813 api_pg_enable_disable (vat_main_t * vam)
20814 {
20815   unformat_input_t *input = vam->input;
20816   vl_api_pg_enable_disable_t *mp;
20817
20818   u8 enable = 1;
20819   u8 stream_name_set = 0;
20820   u8 *stream_name = 0;
20821   int ret;
20822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20823     {
20824       if (unformat (input, "stream %s", &stream_name))
20825         stream_name_set = 1;
20826       else if (unformat (input, "disable"))
20827         enable = 0;
20828       else
20829         break;
20830     }
20831
20832   if (stream_name_set > 0)
20833     {
20834       if (vec_len (stream_name) > 255)
20835         {
20836           errmsg ("stream name too long");
20837           return -99;
20838         }
20839     }
20840
20841   u32 name_len = vec_len (stream_name);
20842   /* Construct the API message */
20843   M (PG_ENABLE_DISABLE, mp);
20844   mp->context = 0;
20845   mp->is_enabled = enable;
20846   if (stream_name_set != 0)
20847     {
20848       mp->stream_name_length = ntohl (name_len);
20849       clib_memcpy (mp->stream_name, stream_name, name_len);
20850     }
20851   vec_free (stream_name);
20852
20853   S (mp);
20854   W (ret);
20855   return ret;
20856 }
20857
20858 int
20859 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20860 {
20861   unformat_input_t *input = vam->input;
20862   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20863
20864   u16 *low_ports = 0;
20865   u16 *high_ports = 0;
20866   u16 this_low;
20867   u16 this_hi;
20868   vl_api_prefix_t prefix;
20869   u32 tmp, tmp2;
20870   u8 prefix_set = 0;
20871   u32 vrf_id = ~0;
20872   u8 is_add = 1;
20873   u8 is_ipv6 = 0;
20874   int ret;
20875
20876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20877     {
20878       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20879         prefix_set = 1;
20880       else if (unformat (input, "vrf %d", &vrf_id))
20881         ;
20882       else if (unformat (input, "del"))
20883         is_add = 0;
20884       else if (unformat (input, "port %d", &tmp))
20885         {
20886           if (tmp == 0 || tmp > 65535)
20887             {
20888               errmsg ("port %d out of range", tmp);
20889               return -99;
20890             }
20891           this_low = tmp;
20892           this_hi = this_low + 1;
20893           vec_add1 (low_ports, this_low);
20894           vec_add1 (high_ports, this_hi);
20895         }
20896       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20897         {
20898           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20899             {
20900               errmsg ("incorrect range parameters");
20901               return -99;
20902             }
20903           this_low = tmp;
20904           /* Note: in debug CLI +1 is added to high before
20905              passing to real fn that does "the work"
20906              (ip_source_and_port_range_check_add_del).
20907              This fn is a wrapper around the binary API fn a
20908              control plane will call, which expects this increment
20909              to have occurred. Hence letting the binary API control
20910              plane fn do the increment for consistency between VAT
20911              and other control planes.
20912            */
20913           this_hi = tmp2;
20914           vec_add1 (low_ports, this_low);
20915           vec_add1 (high_ports, this_hi);
20916         }
20917       else
20918         break;
20919     }
20920
20921   if (prefix_set == 0)
20922     {
20923       errmsg ("<address>/<mask> not specified");
20924       return -99;
20925     }
20926
20927   if (vrf_id == ~0)
20928     {
20929       errmsg ("VRF ID required, not specified");
20930       return -99;
20931     }
20932
20933   if (vrf_id == 0)
20934     {
20935       errmsg
20936         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20937       return -99;
20938     }
20939
20940   if (vec_len (low_ports) == 0)
20941     {
20942       errmsg ("At least one port or port range required");
20943       return -99;
20944     }
20945
20946   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20947
20948   mp->is_add = is_add;
20949
20950   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20951
20952   mp->number_of_ranges = vec_len (low_ports);
20953
20954   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20955   vec_free (low_ports);
20956
20957   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20958   vec_free (high_ports);
20959
20960   mp->vrf_id = ntohl (vrf_id);
20961
20962   S (mp);
20963   W (ret);
20964   return ret;
20965 }
20966
20967 int
20968 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20969 {
20970   unformat_input_t *input = vam->input;
20971   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20972   u32 sw_if_index = ~0;
20973   int vrf_set = 0;
20974   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20975   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20976   u8 is_add = 1;
20977   int ret;
20978
20979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20980     {
20981       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20982         ;
20983       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20984         ;
20985       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20986         vrf_set = 1;
20987       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20988         vrf_set = 1;
20989       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20990         vrf_set = 1;
20991       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20992         vrf_set = 1;
20993       else if (unformat (input, "del"))
20994         is_add = 0;
20995       else
20996         break;
20997     }
20998
20999   if (sw_if_index == ~0)
21000     {
21001       errmsg ("Interface required but not specified");
21002       return -99;
21003     }
21004
21005   if (vrf_set == 0)
21006     {
21007       errmsg ("VRF ID required but not specified");
21008       return -99;
21009     }
21010
21011   if (tcp_out_vrf_id == 0
21012       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21013     {
21014       errmsg
21015         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21016       return -99;
21017     }
21018
21019   /* Construct the API message */
21020   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21021
21022   mp->sw_if_index = ntohl (sw_if_index);
21023   mp->is_add = is_add;
21024   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21025   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21026   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21027   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21028
21029   /* send it... */
21030   S (mp);
21031
21032   /* Wait for a reply... */
21033   W (ret);
21034   return ret;
21035 }
21036
21037 static int
21038 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21039 {
21040   unformat_input_t *i = vam->input;
21041   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21042   u32 local_sa_id = 0;
21043   u32 remote_sa_id = 0;
21044   ip4_address_t src_address;
21045   ip4_address_t dst_address;
21046   u8 is_add = 1;
21047   int ret;
21048
21049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21050     {
21051       if (unformat (i, "local_sa %d", &local_sa_id))
21052         ;
21053       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21054         ;
21055       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21056         ;
21057       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21058         ;
21059       else if (unformat (i, "del"))
21060         is_add = 0;
21061       else
21062         {
21063           clib_warning ("parse error '%U'", format_unformat_error, i);
21064           return -99;
21065         }
21066     }
21067
21068   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21069
21070   mp->local_sa_id = ntohl (local_sa_id);
21071   mp->remote_sa_id = ntohl (remote_sa_id);
21072   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21073   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21074   mp->is_add = is_add;
21075
21076   S (mp);
21077   W (ret);
21078   return ret;
21079 }
21080
21081 static int
21082 api_set_punt (vat_main_t * vam)
21083 {
21084   unformat_input_t *i = vam->input;
21085   vl_api_set_punt_t *mp;
21086   u32 ipv = ~0;
21087   u32 protocol = ~0;
21088   u32 port = ~0;
21089   int is_add = 1;
21090   int ret;
21091
21092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21093     {
21094       if (unformat (i, "ip %d", &ipv))
21095         ;
21096       else if (unformat (i, "protocol %d", &protocol))
21097         ;
21098       else if (unformat (i, "port %d", &port))
21099         ;
21100       else if (unformat (i, "del"))
21101         is_add = 0;
21102       else
21103         {
21104           clib_warning ("parse error '%U'", format_unformat_error, i);
21105           return -99;
21106         }
21107     }
21108
21109   M (SET_PUNT, mp);
21110
21111   mp->is_add = (u8) is_add;
21112   mp->punt.ipv = (u8) ipv;
21113   mp->punt.l4_protocol = (u8) protocol;
21114   mp->punt.l4_port = htons ((u16) port);
21115
21116   S (mp);
21117   W (ret);
21118   return ret;
21119 }
21120
21121 static void vl_api_ipsec_gre_tunnel_details_t_handler
21122   (vl_api_ipsec_gre_tunnel_details_t * mp)
21123 {
21124   vat_main_t *vam = &vat_main;
21125
21126   print (vam->ofp, "%11d%15U%15U%14d%14d",
21127          ntohl (mp->sw_if_index),
21128          format_ip4_address, &mp->src_address,
21129          format_ip4_address, &mp->dst_address,
21130          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21131 }
21132
21133 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21134   (vl_api_ipsec_gre_tunnel_details_t * mp)
21135 {
21136   vat_main_t *vam = &vat_main;
21137   vat_json_node_t *node = NULL;
21138   struct in_addr ip4;
21139
21140   if (VAT_JSON_ARRAY != vam->json_tree.type)
21141     {
21142       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21143       vat_json_init_array (&vam->json_tree);
21144     }
21145   node = vat_json_array_add (&vam->json_tree);
21146
21147   vat_json_init_object (node);
21148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21149   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21150   vat_json_object_add_ip4 (node, "src_address", ip4);
21151   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21152   vat_json_object_add_ip4 (node, "dst_address", ip4);
21153   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21154   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21155 }
21156
21157 static int
21158 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21159 {
21160   unformat_input_t *i = vam->input;
21161   vl_api_ipsec_gre_tunnel_dump_t *mp;
21162   vl_api_control_ping_t *mp_ping;
21163   u32 sw_if_index;
21164   u8 sw_if_index_set = 0;
21165   int ret;
21166
21167   /* Parse args required to build the message */
21168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21169     {
21170       if (unformat (i, "sw_if_index %d", &sw_if_index))
21171         sw_if_index_set = 1;
21172       else
21173         break;
21174     }
21175
21176   if (sw_if_index_set == 0)
21177     {
21178       sw_if_index = ~0;
21179     }
21180
21181   if (!vam->json_output)
21182     {
21183       print (vam->ofp, "%11s%15s%15s%14s%14s",
21184              "sw_if_index", "src_address", "dst_address",
21185              "local_sa_id", "remote_sa_id");
21186     }
21187
21188   /* Get list of gre-tunnel interfaces */
21189   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21190
21191   mp->sw_if_index = htonl (sw_if_index);
21192
21193   S (mp);
21194
21195   /* Use a control ping for synchronization */
21196   MPING (CONTROL_PING, mp_ping);
21197   S (mp_ping);
21198
21199   W (ret);
21200   return ret;
21201 }
21202
21203 static int
21204 api_delete_subif (vat_main_t * vam)
21205 {
21206   unformat_input_t *i = vam->input;
21207   vl_api_delete_subif_t *mp;
21208   u32 sw_if_index = ~0;
21209   int ret;
21210
21211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21212     {
21213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21214         ;
21215       if (unformat (i, "sw_if_index %d", &sw_if_index))
21216         ;
21217       else
21218         break;
21219     }
21220
21221   if (sw_if_index == ~0)
21222     {
21223       errmsg ("missing sw_if_index");
21224       return -99;
21225     }
21226
21227   /* Construct the API message */
21228   M (DELETE_SUBIF, mp);
21229   mp->sw_if_index = ntohl (sw_if_index);
21230
21231   S (mp);
21232   W (ret);
21233   return ret;
21234 }
21235
21236 #define foreach_pbb_vtr_op      \
21237 _("disable",  L2_VTR_DISABLED)  \
21238 _("pop",  L2_VTR_POP_2)         \
21239 _("push",  L2_VTR_PUSH_2)
21240
21241 static int
21242 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21243 {
21244   unformat_input_t *i = vam->input;
21245   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21246   u32 sw_if_index = ~0, vtr_op = ~0;
21247   u16 outer_tag = ~0;
21248   u8 dmac[6], smac[6];
21249   u8 dmac_set = 0, smac_set = 0;
21250   u16 vlanid = 0;
21251   u32 sid = ~0;
21252   u32 tmp;
21253   int ret;
21254
21255   /* Shut up coverity */
21256   clib_memset (dmac, 0, sizeof (dmac));
21257   clib_memset (smac, 0, sizeof (smac));
21258
21259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21260     {
21261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21262         ;
21263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21264         ;
21265       else if (unformat (i, "vtr_op %d", &vtr_op))
21266         ;
21267 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21268       foreach_pbb_vtr_op
21269 #undef _
21270         else if (unformat (i, "translate_pbb_stag"))
21271         {
21272           if (unformat (i, "%d", &tmp))
21273             {
21274               vtr_op = L2_VTR_TRANSLATE_2_1;
21275               outer_tag = tmp;
21276             }
21277           else
21278             {
21279               errmsg
21280                 ("translate_pbb_stag operation requires outer tag definition");
21281               return -99;
21282             }
21283         }
21284       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21285         dmac_set++;
21286       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21287         smac_set++;
21288       else if (unformat (i, "sid %d", &sid))
21289         ;
21290       else if (unformat (i, "vlanid %d", &tmp))
21291         vlanid = tmp;
21292       else
21293         {
21294           clib_warning ("parse error '%U'", format_unformat_error, i);
21295           return -99;
21296         }
21297     }
21298
21299   if ((sw_if_index == ~0) || (vtr_op == ~0))
21300     {
21301       errmsg ("missing sw_if_index or vtr operation");
21302       return -99;
21303     }
21304   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21305       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21306     {
21307       errmsg
21308         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21309       return -99;
21310     }
21311
21312   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21313   mp->sw_if_index = ntohl (sw_if_index);
21314   mp->vtr_op = ntohl (vtr_op);
21315   mp->outer_tag = ntohs (outer_tag);
21316   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21317   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21318   mp->b_vlanid = ntohs (vlanid);
21319   mp->i_sid = ntohl (sid);
21320
21321   S (mp);
21322   W (ret);
21323   return ret;
21324 }
21325
21326 static int
21327 api_flow_classify_set_interface (vat_main_t * vam)
21328 {
21329   unformat_input_t *i = vam->input;
21330   vl_api_flow_classify_set_interface_t *mp;
21331   u32 sw_if_index;
21332   int sw_if_index_set;
21333   u32 ip4_table_index = ~0;
21334   u32 ip6_table_index = ~0;
21335   u8 is_add = 1;
21336   int ret;
21337
21338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21339     {
21340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21341         sw_if_index_set = 1;
21342       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21343         sw_if_index_set = 1;
21344       else if (unformat (i, "del"))
21345         is_add = 0;
21346       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21347         ;
21348       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21349         ;
21350       else
21351         {
21352           clib_warning ("parse error '%U'", format_unformat_error, i);
21353           return -99;
21354         }
21355     }
21356
21357   if (sw_if_index_set == 0)
21358     {
21359       errmsg ("missing interface name or sw_if_index");
21360       return -99;
21361     }
21362
21363   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21364
21365   mp->sw_if_index = ntohl (sw_if_index);
21366   mp->ip4_table_index = ntohl (ip4_table_index);
21367   mp->ip6_table_index = ntohl (ip6_table_index);
21368   mp->is_add = is_add;
21369
21370   S (mp);
21371   W (ret);
21372   return ret;
21373 }
21374
21375 static int
21376 api_flow_classify_dump (vat_main_t * vam)
21377 {
21378   unformat_input_t *i = vam->input;
21379   vl_api_flow_classify_dump_t *mp;
21380   vl_api_control_ping_t *mp_ping;
21381   u8 type = FLOW_CLASSIFY_N_TABLES;
21382   int ret;
21383
21384   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21385     ;
21386   else
21387     {
21388       errmsg ("classify table type must be specified");
21389       return -99;
21390     }
21391
21392   if (!vam->json_output)
21393     {
21394       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21395     }
21396
21397   M (FLOW_CLASSIFY_DUMP, mp);
21398   mp->type = type;
21399   /* send it... */
21400   S (mp);
21401
21402   /* Use a control ping for synchronization */
21403   MPING (CONTROL_PING, mp_ping);
21404   S (mp_ping);
21405
21406   /* Wait for a reply... */
21407   W (ret);
21408   return ret;
21409 }
21410
21411 static int
21412 api_feature_enable_disable (vat_main_t * vam)
21413 {
21414   unformat_input_t *i = vam->input;
21415   vl_api_feature_enable_disable_t *mp;
21416   u8 *arc_name = 0;
21417   u8 *feature_name = 0;
21418   u32 sw_if_index = ~0;
21419   u8 enable = 1;
21420   int ret;
21421
21422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21423     {
21424       if (unformat (i, "arc_name %s", &arc_name))
21425         ;
21426       else if (unformat (i, "feature_name %s", &feature_name))
21427         ;
21428       else
21429         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21430         ;
21431       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21432         ;
21433       else if (unformat (i, "disable"))
21434         enable = 0;
21435       else
21436         break;
21437     }
21438
21439   if (arc_name == 0)
21440     {
21441       errmsg ("missing arc name");
21442       return -99;
21443     }
21444   if (vec_len (arc_name) > 63)
21445     {
21446       errmsg ("arc name too long");
21447     }
21448
21449   if (feature_name == 0)
21450     {
21451       errmsg ("missing feature name");
21452       return -99;
21453     }
21454   if (vec_len (feature_name) > 63)
21455     {
21456       errmsg ("feature name too long");
21457     }
21458
21459   if (sw_if_index == ~0)
21460     {
21461       errmsg ("missing interface name or sw_if_index");
21462       return -99;
21463     }
21464
21465   /* Construct the API message */
21466   M (FEATURE_ENABLE_DISABLE, mp);
21467   mp->sw_if_index = ntohl (sw_if_index);
21468   mp->enable = enable;
21469   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21470   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21471   vec_free (arc_name);
21472   vec_free (feature_name);
21473
21474   S (mp);
21475   W (ret);
21476   return ret;
21477 }
21478
21479 static int
21480 api_sw_interface_tag_add_del (vat_main_t * vam)
21481 {
21482   unformat_input_t *i = vam->input;
21483   vl_api_sw_interface_tag_add_del_t *mp;
21484   u32 sw_if_index = ~0;
21485   u8 *tag = 0;
21486   u8 enable = 1;
21487   int ret;
21488
21489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21490     {
21491       if (unformat (i, "tag %s", &tag))
21492         ;
21493       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21494         ;
21495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21496         ;
21497       else if (unformat (i, "del"))
21498         enable = 0;
21499       else
21500         break;
21501     }
21502
21503   if (sw_if_index == ~0)
21504     {
21505       errmsg ("missing interface name or sw_if_index");
21506       return -99;
21507     }
21508
21509   if (enable && (tag == 0))
21510     {
21511       errmsg ("no tag specified");
21512       return -99;
21513     }
21514
21515   /* Construct the API message */
21516   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21517   mp->sw_if_index = ntohl (sw_if_index);
21518   mp->is_add = enable;
21519   if (enable)
21520     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21521   vec_free (tag);
21522
21523   S (mp);
21524   W (ret);
21525   return ret;
21526 }
21527
21528 static void vl_api_l2_xconnect_details_t_handler
21529   (vl_api_l2_xconnect_details_t * mp)
21530 {
21531   vat_main_t *vam = &vat_main;
21532
21533   print (vam->ofp, "%15d%15d",
21534          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21535 }
21536
21537 static void vl_api_l2_xconnect_details_t_handler_json
21538   (vl_api_l2_xconnect_details_t * mp)
21539 {
21540   vat_main_t *vam = &vat_main;
21541   vat_json_node_t *node = NULL;
21542
21543   if (VAT_JSON_ARRAY != vam->json_tree.type)
21544     {
21545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21546       vat_json_init_array (&vam->json_tree);
21547     }
21548   node = vat_json_array_add (&vam->json_tree);
21549
21550   vat_json_init_object (node);
21551   vat_json_object_add_uint (node, "rx_sw_if_index",
21552                             ntohl (mp->rx_sw_if_index));
21553   vat_json_object_add_uint (node, "tx_sw_if_index",
21554                             ntohl (mp->tx_sw_if_index));
21555 }
21556
21557 static int
21558 api_l2_xconnect_dump (vat_main_t * vam)
21559 {
21560   vl_api_l2_xconnect_dump_t *mp;
21561   vl_api_control_ping_t *mp_ping;
21562   int ret;
21563
21564   if (!vam->json_output)
21565     {
21566       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21567     }
21568
21569   M (L2_XCONNECT_DUMP, mp);
21570
21571   S (mp);
21572
21573   /* Use a control ping for synchronization */
21574   MPING (CONTROL_PING, mp_ping);
21575   S (mp_ping);
21576
21577   W (ret);
21578   return ret;
21579 }
21580
21581 static int
21582 api_hw_interface_set_mtu (vat_main_t * vam)
21583 {
21584   unformat_input_t *i = vam->input;
21585   vl_api_hw_interface_set_mtu_t *mp;
21586   u32 sw_if_index = ~0;
21587   u32 mtu = 0;
21588   int ret;
21589
21590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21591     {
21592       if (unformat (i, "mtu %d", &mtu))
21593         ;
21594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21595         ;
21596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21597         ;
21598       else
21599         break;
21600     }
21601
21602   if (sw_if_index == ~0)
21603     {
21604       errmsg ("missing interface name or sw_if_index");
21605       return -99;
21606     }
21607
21608   if (mtu == 0)
21609     {
21610       errmsg ("no mtu specified");
21611       return -99;
21612     }
21613
21614   /* Construct the API message */
21615   M (HW_INTERFACE_SET_MTU, mp);
21616   mp->sw_if_index = ntohl (sw_if_index);
21617   mp->mtu = ntohs ((u16) mtu);
21618
21619   S (mp);
21620   W (ret);
21621   return ret;
21622 }
21623
21624 static int
21625 api_p2p_ethernet_add (vat_main_t * vam)
21626 {
21627   unformat_input_t *i = vam->input;
21628   vl_api_p2p_ethernet_add_t *mp;
21629   u32 parent_if_index = ~0;
21630   u32 sub_id = ~0;
21631   u8 remote_mac[6];
21632   u8 mac_set = 0;
21633   int ret;
21634
21635   clib_memset (remote_mac, 0, sizeof (remote_mac));
21636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21637     {
21638       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21639         ;
21640       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21641         ;
21642       else
21643         if (unformat
21644             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21645         mac_set++;
21646       else if (unformat (i, "sub_id %d", &sub_id))
21647         ;
21648       else
21649         {
21650           clib_warning ("parse error '%U'", format_unformat_error, i);
21651           return -99;
21652         }
21653     }
21654
21655   if (parent_if_index == ~0)
21656     {
21657       errmsg ("missing interface name or sw_if_index");
21658       return -99;
21659     }
21660   if (mac_set == 0)
21661     {
21662       errmsg ("missing remote mac address");
21663       return -99;
21664     }
21665   if (sub_id == ~0)
21666     {
21667       errmsg ("missing sub-interface id");
21668       return -99;
21669     }
21670
21671   M (P2P_ETHERNET_ADD, mp);
21672   mp->parent_if_index = ntohl (parent_if_index);
21673   mp->subif_id = ntohl (sub_id);
21674   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21675
21676   S (mp);
21677   W (ret);
21678   return ret;
21679 }
21680
21681 static int
21682 api_p2p_ethernet_del (vat_main_t * vam)
21683 {
21684   unformat_input_t *i = vam->input;
21685   vl_api_p2p_ethernet_del_t *mp;
21686   u32 parent_if_index = ~0;
21687   u8 remote_mac[6];
21688   u8 mac_set = 0;
21689   int ret;
21690
21691   clib_memset (remote_mac, 0, sizeof (remote_mac));
21692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21693     {
21694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21695         ;
21696       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21697         ;
21698       else
21699         if (unformat
21700             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21701         mac_set++;
21702       else
21703         {
21704           clib_warning ("parse error '%U'", format_unformat_error, i);
21705           return -99;
21706         }
21707     }
21708
21709   if (parent_if_index == ~0)
21710     {
21711       errmsg ("missing interface name or sw_if_index");
21712       return -99;
21713     }
21714   if (mac_set == 0)
21715     {
21716       errmsg ("missing remote mac address");
21717       return -99;
21718     }
21719
21720   M (P2P_ETHERNET_DEL, mp);
21721   mp->parent_if_index = ntohl (parent_if_index);
21722   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21723
21724   S (mp);
21725   W (ret);
21726   return ret;
21727 }
21728
21729 static int
21730 api_lldp_config (vat_main_t * vam)
21731 {
21732   unformat_input_t *i = vam->input;
21733   vl_api_lldp_config_t *mp;
21734   int tx_hold = 0;
21735   int tx_interval = 0;
21736   u8 *sys_name = NULL;
21737   int ret;
21738
21739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21740     {
21741       if (unformat (i, "system-name %s", &sys_name))
21742         ;
21743       else if (unformat (i, "tx-hold %d", &tx_hold))
21744         ;
21745       else if (unformat (i, "tx-interval %d", &tx_interval))
21746         ;
21747       else
21748         {
21749           clib_warning ("parse error '%U'", format_unformat_error, i);
21750           return -99;
21751         }
21752     }
21753
21754   vec_add1 (sys_name, 0);
21755
21756   M (LLDP_CONFIG, mp);
21757   mp->tx_hold = htonl (tx_hold);
21758   mp->tx_interval = htonl (tx_interval);
21759   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21760   vec_free (sys_name);
21761
21762   S (mp);
21763   W (ret);
21764   return ret;
21765 }
21766
21767 static int
21768 api_sw_interface_set_lldp (vat_main_t * vam)
21769 {
21770   unformat_input_t *i = vam->input;
21771   vl_api_sw_interface_set_lldp_t *mp;
21772   u32 sw_if_index = ~0;
21773   u32 enable = 1;
21774   u8 *port_desc = NULL, *mgmt_oid = NULL;
21775   ip4_address_t ip4_addr;
21776   ip6_address_t ip6_addr;
21777   int ret;
21778
21779   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21780   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21781
21782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21783     {
21784       if (unformat (i, "disable"))
21785         enable = 0;
21786       else
21787         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21788         ;
21789       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21790         ;
21791       else if (unformat (i, "port-desc %s", &port_desc))
21792         ;
21793       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21794         ;
21795       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21796         ;
21797       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21798         ;
21799       else
21800         break;
21801     }
21802
21803   if (sw_if_index == ~0)
21804     {
21805       errmsg ("missing interface name or sw_if_index");
21806       return -99;
21807     }
21808
21809   /* Construct the API message */
21810   vec_add1 (port_desc, 0);
21811   vec_add1 (mgmt_oid, 0);
21812   M (SW_INTERFACE_SET_LLDP, mp);
21813   mp->sw_if_index = ntohl (sw_if_index);
21814   mp->enable = enable;
21815   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21816   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21817   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21818   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21819   vec_free (port_desc);
21820   vec_free (mgmt_oid);
21821
21822   S (mp);
21823   W (ret);
21824   return ret;
21825 }
21826
21827 static int
21828 api_tcp_configure_src_addresses (vat_main_t * vam)
21829 {
21830   vl_api_tcp_configure_src_addresses_t *mp;
21831   unformat_input_t *i = vam->input;
21832   ip4_address_t v4first, v4last;
21833   ip6_address_t v6first, v6last;
21834   u8 range_set = 0;
21835   u32 vrf_id = 0;
21836   int ret;
21837
21838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21839     {
21840       if (unformat (i, "%U - %U",
21841                     unformat_ip4_address, &v4first,
21842                     unformat_ip4_address, &v4last))
21843         {
21844           if (range_set)
21845             {
21846               errmsg ("one range per message (range already set)");
21847               return -99;
21848             }
21849           range_set = 1;
21850         }
21851       else if (unformat (i, "%U - %U",
21852                          unformat_ip6_address, &v6first,
21853                          unformat_ip6_address, &v6last))
21854         {
21855           if (range_set)
21856             {
21857               errmsg ("one range per message (range already set)");
21858               return -99;
21859             }
21860           range_set = 2;
21861         }
21862       else if (unformat (i, "vrf %d", &vrf_id))
21863         ;
21864       else
21865         break;
21866     }
21867
21868   if (range_set == 0)
21869     {
21870       errmsg ("address range not set");
21871       return -99;
21872     }
21873
21874   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21875   mp->vrf_id = ntohl (vrf_id);
21876   /* ipv6? */
21877   if (range_set == 2)
21878     {
21879       mp->is_ipv6 = 1;
21880       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21881       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21882     }
21883   else
21884     {
21885       mp->is_ipv6 = 0;
21886       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21887       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21888     }
21889   S (mp);
21890   W (ret);
21891   return ret;
21892 }
21893
21894 static void vl_api_app_namespace_add_del_reply_t_handler
21895   (vl_api_app_namespace_add_del_reply_t * mp)
21896 {
21897   vat_main_t *vam = &vat_main;
21898   i32 retval = ntohl (mp->retval);
21899   if (vam->async_mode)
21900     {
21901       vam->async_errors += (retval < 0);
21902     }
21903   else
21904     {
21905       vam->retval = retval;
21906       if (retval == 0)
21907         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21908       vam->result_ready = 1;
21909     }
21910 }
21911
21912 static void vl_api_app_namespace_add_del_reply_t_handler_json
21913   (vl_api_app_namespace_add_del_reply_t * mp)
21914 {
21915   vat_main_t *vam = &vat_main;
21916   vat_json_node_t node;
21917
21918   vat_json_init_object (&node);
21919   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21920   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21921
21922   vat_json_print (vam->ofp, &node);
21923   vat_json_free (&node);
21924
21925   vam->retval = ntohl (mp->retval);
21926   vam->result_ready = 1;
21927 }
21928
21929 static int
21930 api_app_namespace_add_del (vat_main_t * vam)
21931 {
21932   vl_api_app_namespace_add_del_t *mp;
21933   unformat_input_t *i = vam->input;
21934   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21935   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21936   u64 secret;
21937   int ret;
21938
21939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21940     {
21941       if (unformat (i, "id %_%v%_", &ns_id))
21942         ;
21943       else if (unformat (i, "secret %lu", &secret))
21944         secret_set = 1;
21945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21946         sw_if_index_set = 1;
21947       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21948         ;
21949       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21950         ;
21951       else
21952         break;
21953     }
21954   if (!ns_id || !secret_set || !sw_if_index_set)
21955     {
21956       errmsg ("namespace id, secret and sw_if_index must be set");
21957       return -99;
21958     }
21959   if (vec_len (ns_id) > 64)
21960     {
21961       errmsg ("namespace id too long");
21962       return -99;
21963     }
21964   M (APP_NAMESPACE_ADD_DEL, mp);
21965
21966   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21967   mp->namespace_id_len = vec_len (ns_id);
21968   mp->secret = clib_host_to_net_u64 (secret);
21969   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21970   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21971   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21972   vec_free (ns_id);
21973   S (mp);
21974   W (ret);
21975   return ret;
21976 }
21977
21978 static int
21979 api_sock_init_shm (vat_main_t * vam)
21980 {
21981 #if VPP_API_TEST_BUILTIN == 0
21982   unformat_input_t *i = vam->input;
21983   vl_api_shm_elem_config_t *config = 0;
21984   u64 size = 64 << 20;
21985   int rv;
21986
21987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21988     {
21989       if (unformat (i, "size %U", unformat_memory_size, &size))
21990         ;
21991       else
21992         break;
21993     }
21994
21995   /*
21996    * Canned custom ring allocator config.
21997    * Should probably parse all of this
21998    */
21999   vec_validate (config, 6);
22000   config[0].type = VL_API_VLIB_RING;
22001   config[0].size = 256;
22002   config[0].count = 32;
22003
22004   config[1].type = VL_API_VLIB_RING;
22005   config[1].size = 1024;
22006   config[1].count = 16;
22007
22008   config[2].type = VL_API_VLIB_RING;
22009   config[2].size = 4096;
22010   config[2].count = 2;
22011
22012   config[3].type = VL_API_CLIENT_RING;
22013   config[3].size = 256;
22014   config[3].count = 32;
22015
22016   config[4].type = VL_API_CLIENT_RING;
22017   config[4].size = 1024;
22018   config[4].count = 16;
22019
22020   config[5].type = VL_API_CLIENT_RING;
22021   config[5].size = 4096;
22022   config[5].count = 2;
22023
22024   config[6].type = VL_API_QUEUE;
22025   config[6].count = 128;
22026   config[6].size = sizeof (uword);
22027
22028   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
22029   if (!rv)
22030     vam->client_index_invalid = 1;
22031   return rv;
22032 #else
22033   return -99;
22034 #endif
22035 }
22036
22037 static int
22038 api_dns_enable_disable (vat_main_t * vam)
22039 {
22040   unformat_input_t *line_input = vam->input;
22041   vl_api_dns_enable_disable_t *mp;
22042   u8 enable_disable = 1;
22043   int ret;
22044
22045   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22046     {
22047       if (unformat (line_input, "disable"))
22048         enable_disable = 0;
22049       if (unformat (line_input, "enable"))
22050         enable_disable = 1;
22051       else
22052         break;
22053     }
22054
22055   /* Construct the API message */
22056   M (DNS_ENABLE_DISABLE, mp);
22057   mp->enable = enable_disable;
22058
22059   /* send it... */
22060   S (mp);
22061   /* Wait for the reply */
22062   W (ret);
22063   return ret;
22064 }
22065
22066 static int
22067 api_dns_resolve_name (vat_main_t * vam)
22068 {
22069   unformat_input_t *line_input = vam->input;
22070   vl_api_dns_resolve_name_t *mp;
22071   u8 *name = 0;
22072   int ret;
22073
22074   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22075     {
22076       if (unformat (line_input, "%s", &name))
22077         ;
22078       else
22079         break;
22080     }
22081
22082   if (vec_len (name) > 127)
22083     {
22084       errmsg ("name too long");
22085       return -99;
22086     }
22087
22088   /* Construct the API message */
22089   M (DNS_RESOLVE_NAME, mp);
22090   memcpy (mp->name, name, vec_len (name));
22091   vec_free (name);
22092
22093   /* send it... */
22094   S (mp);
22095   /* Wait for the reply */
22096   W (ret);
22097   return ret;
22098 }
22099
22100 static int
22101 api_dns_resolve_ip (vat_main_t * vam)
22102 {
22103   unformat_input_t *line_input = vam->input;
22104   vl_api_dns_resolve_ip_t *mp;
22105   int is_ip6 = -1;
22106   ip4_address_t addr4;
22107   ip6_address_t addr6;
22108   int ret;
22109
22110   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22111     {
22112       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22113         is_ip6 = 1;
22114       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22115         is_ip6 = 0;
22116       else
22117         break;
22118     }
22119
22120   if (is_ip6 == -1)
22121     {
22122       errmsg ("missing address");
22123       return -99;
22124     }
22125
22126   /* Construct the API message */
22127   M (DNS_RESOLVE_IP, mp);
22128   mp->is_ip6 = is_ip6;
22129   if (is_ip6)
22130     memcpy (mp->address, &addr6, sizeof (addr6));
22131   else
22132     memcpy (mp->address, &addr4, sizeof (addr4));
22133
22134   /* send it... */
22135   S (mp);
22136   /* Wait for the reply */
22137   W (ret);
22138   return ret;
22139 }
22140
22141 static int
22142 api_dns_name_server_add_del (vat_main_t * vam)
22143 {
22144   unformat_input_t *i = vam->input;
22145   vl_api_dns_name_server_add_del_t *mp;
22146   u8 is_add = 1;
22147   ip6_address_t ip6_server;
22148   ip4_address_t ip4_server;
22149   int ip6_set = 0;
22150   int ip4_set = 0;
22151   int ret = 0;
22152
22153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22154     {
22155       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22156         ip6_set = 1;
22157       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22158         ip4_set = 1;
22159       else if (unformat (i, "del"))
22160         is_add = 0;
22161       else
22162         {
22163           clib_warning ("parse error '%U'", format_unformat_error, i);
22164           return -99;
22165         }
22166     }
22167
22168   if (ip4_set && ip6_set)
22169     {
22170       errmsg ("Only one server address allowed per message");
22171       return -99;
22172     }
22173   if ((ip4_set + ip6_set) == 0)
22174     {
22175       errmsg ("Server address required");
22176       return -99;
22177     }
22178
22179   /* Construct the API message */
22180   M (DNS_NAME_SERVER_ADD_DEL, mp);
22181
22182   if (ip6_set)
22183     {
22184       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22185       mp->is_ip6 = 1;
22186     }
22187   else
22188     {
22189       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22190       mp->is_ip6 = 0;
22191     }
22192
22193   mp->is_add = is_add;
22194
22195   /* send it... */
22196   S (mp);
22197
22198   /* Wait for a reply, return good/bad news  */
22199   W (ret);
22200   return ret;
22201 }
22202
22203 static void
22204 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22205 {
22206   vat_main_t *vam = &vat_main;
22207
22208   if (mp->is_ip4)
22209     {
22210       print (vam->ofp,
22211              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22212              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22213              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22214              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22215              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22216              clib_net_to_host_u32 (mp->action_index), mp->tag);
22217     }
22218   else
22219     {
22220       print (vam->ofp,
22221              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22222              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22223              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22224              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22225              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22226              clib_net_to_host_u32 (mp->action_index), mp->tag);
22227     }
22228 }
22229
22230 static void
22231 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22232                                              mp)
22233 {
22234   vat_main_t *vam = &vat_main;
22235   vat_json_node_t *node = NULL;
22236   struct in6_addr ip6;
22237   struct in_addr ip4;
22238
22239   if (VAT_JSON_ARRAY != vam->json_tree.type)
22240     {
22241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22242       vat_json_init_array (&vam->json_tree);
22243     }
22244   node = vat_json_array_add (&vam->json_tree);
22245   vat_json_init_object (node);
22246
22247   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22248   vat_json_object_add_uint (node, "appns_index",
22249                             clib_net_to_host_u32 (mp->appns_index));
22250   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22251   vat_json_object_add_uint (node, "scope", mp->scope);
22252   vat_json_object_add_uint (node, "action_index",
22253                             clib_net_to_host_u32 (mp->action_index));
22254   vat_json_object_add_uint (node, "lcl_port",
22255                             clib_net_to_host_u16 (mp->lcl_port));
22256   vat_json_object_add_uint (node, "rmt_port",
22257                             clib_net_to_host_u16 (mp->rmt_port));
22258   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22259   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22260   vat_json_object_add_string_copy (node, "tag", mp->tag);
22261   if (mp->is_ip4)
22262     {
22263       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22264       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22265       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22266       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22267     }
22268   else
22269     {
22270       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22271       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22272       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22273       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22274     }
22275 }
22276
22277 static int
22278 api_session_rule_add_del (vat_main_t * vam)
22279 {
22280   vl_api_session_rule_add_del_t *mp;
22281   unformat_input_t *i = vam->input;
22282   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22283   u32 appns_index = 0, scope = 0;
22284   ip4_address_t lcl_ip4, rmt_ip4;
22285   ip6_address_t lcl_ip6, rmt_ip6;
22286   u8 is_ip4 = 1, conn_set = 0;
22287   u8 is_add = 1, *tag = 0;
22288   int ret;
22289
22290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22291     {
22292       if (unformat (i, "del"))
22293         is_add = 0;
22294       else if (unformat (i, "add"))
22295         ;
22296       else if (unformat (i, "proto tcp"))
22297         proto = 0;
22298       else if (unformat (i, "proto udp"))
22299         proto = 1;
22300       else if (unformat (i, "appns %d", &appns_index))
22301         ;
22302       else if (unformat (i, "scope %d", &scope))
22303         ;
22304       else if (unformat (i, "tag %_%v%_", &tag))
22305         ;
22306       else
22307         if (unformat
22308             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22309              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22310              &rmt_port))
22311         {
22312           is_ip4 = 1;
22313           conn_set = 1;
22314         }
22315       else
22316         if (unformat
22317             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22318              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22319              &rmt_port))
22320         {
22321           is_ip4 = 0;
22322           conn_set = 1;
22323         }
22324       else if (unformat (i, "action %d", &action))
22325         ;
22326       else
22327         break;
22328     }
22329   if (proto == ~0 || !conn_set || action == ~0)
22330     {
22331       errmsg ("transport proto, connection and action must be set");
22332       return -99;
22333     }
22334
22335   if (scope > 3)
22336     {
22337       errmsg ("scope should be 0-3");
22338       return -99;
22339     }
22340
22341   M (SESSION_RULE_ADD_DEL, mp);
22342
22343   mp->is_ip4 = is_ip4;
22344   mp->transport_proto = proto;
22345   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22346   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22347   mp->lcl_plen = lcl_plen;
22348   mp->rmt_plen = rmt_plen;
22349   mp->action_index = clib_host_to_net_u32 (action);
22350   mp->appns_index = clib_host_to_net_u32 (appns_index);
22351   mp->scope = scope;
22352   mp->is_add = is_add;
22353   if (is_ip4)
22354     {
22355       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22356       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22357     }
22358   else
22359     {
22360       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22361       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22362     }
22363   if (tag)
22364     {
22365       clib_memcpy (mp->tag, tag, vec_len (tag));
22366       vec_free (tag);
22367     }
22368
22369   S (mp);
22370   W (ret);
22371   return ret;
22372 }
22373
22374 static int
22375 api_session_rules_dump (vat_main_t * vam)
22376 {
22377   vl_api_session_rules_dump_t *mp;
22378   vl_api_control_ping_t *mp_ping;
22379   int ret;
22380
22381   if (!vam->json_output)
22382     {
22383       print (vam->ofp, "%=20s", "Session Rules");
22384     }
22385
22386   M (SESSION_RULES_DUMP, mp);
22387   /* send it... */
22388   S (mp);
22389
22390   /* Use a control ping for synchronization */
22391   MPING (CONTROL_PING, mp_ping);
22392   S (mp_ping);
22393
22394   /* Wait for a reply... */
22395   W (ret);
22396   return ret;
22397 }
22398
22399 static int
22400 api_ip_container_proxy_add_del (vat_main_t * vam)
22401 {
22402   vl_api_ip_container_proxy_add_del_t *mp;
22403   unformat_input_t *i = vam->input;
22404   u32 sw_if_index = ~0;
22405   vl_api_prefix_t pfx = { };
22406   u8 is_add = 1;
22407   int ret;
22408
22409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22410     {
22411       if (unformat (i, "del"))
22412         is_add = 0;
22413       else if (unformat (i, "add"))
22414         ;
22415       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
22416         ;
22417       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22418         ;
22419       else
22420         break;
22421     }
22422   if (sw_if_index == ~0 || pfx.address_length == 0)
22423     {
22424       errmsg ("address and sw_if_index must be set");
22425       return -99;
22426     }
22427
22428   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22429
22430   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22431   mp->is_add = is_add;
22432   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
22433
22434   S (mp);
22435   W (ret);
22436   return ret;
22437 }
22438
22439 static int
22440 api_qos_record_enable_disable (vat_main_t * vam)
22441 {
22442   unformat_input_t *i = vam->input;
22443   vl_api_qos_record_enable_disable_t *mp;
22444   u32 sw_if_index, qs = 0xff;
22445   u8 sw_if_index_set = 0;
22446   u8 enable = 1;
22447   int ret;
22448
22449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22450     {
22451       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22452         sw_if_index_set = 1;
22453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22454         sw_if_index_set = 1;
22455       else if (unformat (i, "%U", unformat_qos_source, &qs))
22456         ;
22457       else if (unformat (i, "disable"))
22458         enable = 0;
22459       else
22460         {
22461           clib_warning ("parse error '%U'", format_unformat_error, i);
22462           return -99;
22463         }
22464     }
22465
22466   if (sw_if_index_set == 0)
22467     {
22468       errmsg ("missing interface name or sw_if_index");
22469       return -99;
22470     }
22471   if (qs == 0xff)
22472     {
22473       errmsg ("input location must be specified");
22474       return -99;
22475     }
22476
22477   M (QOS_RECORD_ENABLE_DISABLE, mp);
22478
22479   mp->sw_if_index = ntohl (sw_if_index);
22480   mp->input_source = qs;
22481   mp->enable = enable;
22482
22483   S (mp);
22484   W (ret);
22485   return ret;
22486 }
22487
22488
22489 static int
22490 q_or_quit (vat_main_t * vam)
22491 {
22492 #if VPP_API_TEST_BUILTIN == 0
22493   longjmp (vam->jump_buf, 1);
22494 #endif
22495   return 0;                     /* not so much */
22496 }
22497
22498 static int
22499 q (vat_main_t * vam)
22500 {
22501   return q_or_quit (vam);
22502 }
22503
22504 static int
22505 quit (vat_main_t * vam)
22506 {
22507   return q_or_quit (vam);
22508 }
22509
22510 static int
22511 comment (vat_main_t * vam)
22512 {
22513   return 0;
22514 }
22515
22516 static int
22517 statseg (vat_main_t * vam)
22518 {
22519   ssvm_private_t *ssvmp = &vam->stat_segment;
22520   ssvm_shared_header_t *shared_header = ssvmp->sh;
22521   vlib_counter_t **counters;
22522   u64 thread0_index1_packets;
22523   u64 thread0_index1_bytes;
22524   f64 vector_rate, input_rate;
22525   uword *p;
22526
22527   uword *counter_vector_by_name;
22528   if (vam->stat_segment_lockp == 0)
22529     {
22530       errmsg ("Stat segment not mapped...");
22531       return -99;
22532     }
22533
22534   /* look up "/if/rx for sw_if_index 1 as a test */
22535
22536   clib_spinlock_lock (vam->stat_segment_lockp);
22537
22538   counter_vector_by_name = (uword *) shared_header->opaque[1];
22539
22540   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22541   if (p == 0)
22542     {
22543       clib_spinlock_unlock (vam->stat_segment_lockp);
22544       errmsg ("/if/tx not found?");
22545       return -99;
22546     }
22547
22548   /* Fish per-thread vector of combined counters from shared memory */
22549   counters = (vlib_counter_t **) p[0];
22550
22551   if (vec_len (counters[0]) < 2)
22552     {
22553       clib_spinlock_unlock (vam->stat_segment_lockp);
22554       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22555       return -99;
22556     }
22557
22558   /* Read thread 0 sw_if_index 1 counter */
22559   thread0_index1_packets = counters[0][1].packets;
22560   thread0_index1_bytes = counters[0][1].bytes;
22561
22562   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22563   if (p == 0)
22564     {
22565       clib_spinlock_unlock (vam->stat_segment_lockp);
22566       errmsg ("vector_rate not found?");
22567       return -99;
22568     }
22569
22570   vector_rate = *(f64 *) (p[0]);
22571   p = hash_get_mem (counter_vector_by_name, "input_rate");
22572   if (p == 0)
22573     {
22574       clib_spinlock_unlock (vam->stat_segment_lockp);
22575       errmsg ("input_rate not found?");
22576       return -99;
22577     }
22578   input_rate = *(f64 *) (p[0]);
22579
22580   clib_spinlock_unlock (vam->stat_segment_lockp);
22581
22582   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22583          vector_rate, input_rate);
22584   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22585          thread0_index1_packets, thread0_index1_bytes);
22586
22587   return 0;
22588 }
22589
22590 static int
22591 cmd_cmp (void *a1, void *a2)
22592 {
22593   u8 **c1 = a1;
22594   u8 **c2 = a2;
22595
22596   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22597 }
22598
22599 static int
22600 help (vat_main_t * vam)
22601 {
22602   u8 **cmds = 0;
22603   u8 *name = 0;
22604   hash_pair_t *p;
22605   unformat_input_t *i = vam->input;
22606   int j;
22607
22608   if (unformat (i, "%s", &name))
22609     {
22610       uword *hs;
22611
22612       vec_add1 (name, 0);
22613
22614       hs = hash_get_mem (vam->help_by_name, name);
22615       if (hs)
22616         print (vam->ofp, "usage: %s %s", name, hs[0]);
22617       else
22618         print (vam->ofp, "No such msg / command '%s'", name);
22619       vec_free (name);
22620       return 0;
22621     }
22622
22623   print (vam->ofp, "Help is available for the following:");
22624
22625     /* *INDENT-OFF* */
22626     hash_foreach_pair (p, vam->function_by_name,
22627     ({
22628       vec_add1 (cmds, (u8 *)(p->key));
22629     }));
22630     /* *INDENT-ON* */
22631
22632   vec_sort_with_function (cmds, cmd_cmp);
22633
22634   for (j = 0; j < vec_len (cmds); j++)
22635     print (vam->ofp, "%s", cmds[j]);
22636
22637   vec_free (cmds);
22638   return 0;
22639 }
22640
22641 static int
22642 set (vat_main_t * vam)
22643 {
22644   u8 *name = 0, *value = 0;
22645   unformat_input_t *i = vam->input;
22646
22647   if (unformat (i, "%s", &name))
22648     {
22649       /* The input buffer is a vector, not a string. */
22650       value = vec_dup (i->buffer);
22651       vec_delete (value, i->index, 0);
22652       /* Almost certainly has a trailing newline */
22653       if (value[vec_len (value) - 1] == '\n')
22654         value[vec_len (value) - 1] = 0;
22655       /* Make sure it's a proper string, one way or the other */
22656       vec_add1 (value, 0);
22657       (void) clib_macro_set_value (&vam->macro_main,
22658                                    (char *) name, (char *) value);
22659     }
22660   else
22661     errmsg ("usage: set <name> <value>");
22662
22663   vec_free (name);
22664   vec_free (value);
22665   return 0;
22666 }
22667
22668 static int
22669 unset (vat_main_t * vam)
22670 {
22671   u8 *name = 0;
22672
22673   if (unformat (vam->input, "%s", &name))
22674     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22675       errmsg ("unset: %s wasn't set", name);
22676   vec_free (name);
22677   return 0;
22678 }
22679
22680 typedef struct
22681 {
22682   u8 *name;
22683   u8 *value;
22684 } macro_sort_t;
22685
22686
22687 static int
22688 macro_sort_cmp (void *a1, void *a2)
22689 {
22690   macro_sort_t *s1 = a1;
22691   macro_sort_t *s2 = a2;
22692
22693   return strcmp ((char *) (s1->name), (char *) (s2->name));
22694 }
22695
22696 static int
22697 dump_macro_table (vat_main_t * vam)
22698 {
22699   macro_sort_t *sort_me = 0, *sm;
22700   int i;
22701   hash_pair_t *p;
22702
22703     /* *INDENT-OFF* */
22704     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22705     ({
22706       vec_add2 (sort_me, sm, 1);
22707       sm->name = (u8 *)(p->key);
22708       sm->value = (u8 *) (p->value[0]);
22709     }));
22710     /* *INDENT-ON* */
22711
22712   vec_sort_with_function (sort_me, macro_sort_cmp);
22713
22714   if (vec_len (sort_me))
22715     print (vam->ofp, "%-15s%s", "Name", "Value");
22716   else
22717     print (vam->ofp, "The macro table is empty...");
22718
22719   for (i = 0; i < vec_len (sort_me); i++)
22720     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22721   return 0;
22722 }
22723
22724 static int
22725 dump_node_table (vat_main_t * vam)
22726 {
22727   int i, j;
22728   vlib_node_t *node, *next_node;
22729
22730   if (vec_len (vam->graph_nodes) == 0)
22731     {
22732       print (vam->ofp, "Node table empty, issue get_node_graph...");
22733       return 0;
22734     }
22735
22736   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22737     {
22738       node = vam->graph_nodes[0][i];
22739       print (vam->ofp, "[%d] %s", i, node->name);
22740       for (j = 0; j < vec_len (node->next_nodes); j++)
22741         {
22742           if (node->next_nodes[j] != ~0)
22743             {
22744               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22745               print (vam->ofp, "  [%d] %s", j, next_node->name);
22746             }
22747         }
22748     }
22749   return 0;
22750 }
22751
22752 static int
22753 value_sort_cmp (void *a1, void *a2)
22754 {
22755   name_sort_t *n1 = a1;
22756   name_sort_t *n2 = a2;
22757
22758   if (n1->value < n2->value)
22759     return -1;
22760   if (n1->value > n2->value)
22761     return 1;
22762   return 0;
22763 }
22764
22765
22766 static int
22767 dump_msg_api_table (vat_main_t * vam)
22768 {
22769   api_main_t *am = &api_main;
22770   name_sort_t *nses = 0, *ns;
22771   hash_pair_t *hp;
22772   int i;
22773
22774   /* *INDENT-OFF* */
22775   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22776   ({
22777     vec_add2 (nses, ns, 1);
22778     ns->name = (u8 *)(hp->key);
22779     ns->value = (u32) hp->value[0];
22780   }));
22781   /* *INDENT-ON* */
22782
22783   vec_sort_with_function (nses, value_sort_cmp);
22784
22785   for (i = 0; i < vec_len (nses); i++)
22786     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22787   vec_free (nses);
22788   return 0;
22789 }
22790
22791 static int
22792 get_msg_id (vat_main_t * vam)
22793 {
22794   u8 *name_and_crc;
22795   u32 message_index;
22796
22797   if (unformat (vam->input, "%s", &name_and_crc))
22798     {
22799       message_index = vl_msg_api_get_msg_index (name_and_crc);
22800       if (message_index == ~0)
22801         {
22802           print (vam->ofp, " '%s' not found", name_and_crc);
22803           return 0;
22804         }
22805       print (vam->ofp, " '%s' has message index %d",
22806              name_and_crc, message_index);
22807       return 0;
22808     }
22809   errmsg ("name_and_crc required...");
22810   return 0;
22811 }
22812
22813 static int
22814 search_node_table (vat_main_t * vam)
22815 {
22816   unformat_input_t *line_input = vam->input;
22817   u8 *node_to_find;
22818   int j;
22819   vlib_node_t *node, *next_node;
22820   uword *p;
22821
22822   if (vam->graph_node_index_by_name == 0)
22823     {
22824       print (vam->ofp, "Node table empty, issue get_node_graph...");
22825       return 0;
22826     }
22827
22828   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22829     {
22830       if (unformat (line_input, "%s", &node_to_find))
22831         {
22832           vec_add1 (node_to_find, 0);
22833           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22834           if (p == 0)
22835             {
22836               print (vam->ofp, "%s not found...", node_to_find);
22837               goto out;
22838             }
22839           node = vam->graph_nodes[0][p[0]];
22840           print (vam->ofp, "[%d] %s", p[0], node->name);
22841           for (j = 0; j < vec_len (node->next_nodes); j++)
22842             {
22843               if (node->next_nodes[j] != ~0)
22844                 {
22845                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22846                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22847                 }
22848             }
22849         }
22850
22851       else
22852         {
22853           clib_warning ("parse error '%U'", format_unformat_error,
22854                         line_input);
22855           return -99;
22856         }
22857
22858     out:
22859       vec_free (node_to_find);
22860
22861     }
22862
22863   return 0;
22864 }
22865
22866
22867 static int
22868 script (vat_main_t * vam)
22869 {
22870 #if (VPP_API_TEST_BUILTIN==0)
22871   u8 *s = 0;
22872   char *save_current_file;
22873   unformat_input_t save_input;
22874   jmp_buf save_jump_buf;
22875   u32 save_line_number;
22876
22877   FILE *new_fp, *save_ifp;
22878
22879   if (unformat (vam->input, "%s", &s))
22880     {
22881       new_fp = fopen ((char *) s, "r");
22882       if (new_fp == 0)
22883         {
22884           errmsg ("Couldn't open script file %s", s);
22885           vec_free (s);
22886           return -99;
22887         }
22888     }
22889   else
22890     {
22891       errmsg ("Missing script name");
22892       return -99;
22893     }
22894
22895   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22896   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22897   save_ifp = vam->ifp;
22898   save_line_number = vam->input_line_number;
22899   save_current_file = (char *) vam->current_file;
22900
22901   vam->input_line_number = 0;
22902   vam->ifp = new_fp;
22903   vam->current_file = s;
22904   do_one_file (vam);
22905
22906   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22907   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22908   vam->ifp = save_ifp;
22909   vam->input_line_number = save_line_number;
22910   vam->current_file = (u8 *) save_current_file;
22911   vec_free (s);
22912
22913   return 0;
22914 #else
22915   clib_warning ("use the exec command...");
22916   return -99;
22917 #endif
22918 }
22919
22920 static int
22921 echo (vat_main_t * vam)
22922 {
22923   print (vam->ofp, "%v", vam->input->buffer);
22924   return 0;
22925 }
22926
22927 /* List of API message constructors, CLI names map to api_xxx */
22928 #define foreach_vpe_api_msg                                             \
22929 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22930 _(sw_interface_dump,"")                                                 \
22931 _(sw_interface_set_flags,                                               \
22932   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22933 _(sw_interface_add_del_address,                                         \
22934   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22935 _(sw_interface_set_rx_mode,                                             \
22936   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22937 _(sw_interface_set_rx_placement,                                        \
22938   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22939 _(sw_interface_rx_placement_dump,                                       \
22940   "[<intfc> | sw_if_index <id>]")                                         \
22941 _(sw_interface_set_table,                                               \
22942   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22943 _(sw_interface_set_mpls_enable,                                         \
22944   "<intfc> | sw_if_index [disable | dis]")                              \
22945 _(sw_interface_set_vpath,                                               \
22946   "<intfc> | sw_if_index <id> enable | disable")                        \
22947 _(sw_interface_set_vxlan_bypass,                                        \
22948   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22949 _(sw_interface_set_geneve_bypass,                                       \
22950   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22951 _(sw_interface_set_l2_xconnect,                                         \
22952   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22953   "enable | disable")                                                   \
22954 _(sw_interface_set_l2_bridge,                                           \
22955   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22956   "[shg <split-horizon-group>] [bvi]\n"                                 \
22957   "enable | disable")                                                   \
22958 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22959 _(bridge_domain_add_del,                                                \
22960   "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") \
22961 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22962 _(l2fib_add_del,                                                        \
22963   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22964 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22965 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22966 _(l2_flags,                                                             \
22967   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22968 _(bridge_flags,                                                         \
22969   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22970 _(tap_create_v2,                                                        \
22971   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22972 _(tap_delete_v2,                                                        \
22973   "<vpp-if-name> | sw_if_index <id>")                                   \
22974 _(sw_interface_tap_v2_dump, "")                                         \
22975 _(virtio_pci_create,                                                    \
22976   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22977 _(virtio_pci_delete,                                                    \
22978   "<vpp-if-name> | sw_if_index <id>")                                   \
22979 _(sw_interface_virtio_pci_dump, "")                                     \
22980 _(bond_create,                                                          \
22981   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22982   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22983   "[id <if-id>]")                                                       \
22984 _(bond_delete,                                                          \
22985   "<vpp-if-name> | sw_if_index <id>")                                   \
22986 _(bond_enslave,                                                         \
22987   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22988 _(bond_detach_slave,                                                    \
22989   "sw_if_index <n>")                                                    \
22990 _(sw_interface_bond_dump, "")                                           \
22991 _(sw_interface_slave_dump,                                              \
22992   "<vpp-if-name> | sw_if_index <id>")                                   \
22993 _(ip_table_add_del,                                                     \
22994   "table <n> [ipv6] [add | del]\n")                                     \
22995 _(ip_add_del_route,                                                     \
22996   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22997   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22998   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22999   "[multipath] [count <n>] [del]")                                      \
23000 _(ip_mroute_add_del,                                                    \
23001   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23002   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23003 _(mpls_table_add_del,                                                   \
23004   "table <n> [add | del]\n")                                            \
23005 _(mpls_route_add_del,                                                   \
23006   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23007   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23008   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23009   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23010   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23011   "[count <n>] [del]")                                                  \
23012 _(mpls_ip_bind_unbind,                                                  \
23013   "<label> <addr/len>")                                                 \
23014 _(mpls_tunnel_add_del,                                                  \
23015   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23016   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23017   "[l2-only]  [out-label <n>]")                                         \
23018 _(sr_mpls_policy_add,                                                   \
23019   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23020 _(sr_mpls_policy_del,                                                   \
23021   "bsid <id>")                                                          \
23022 _(bier_table_add_del,                                                   \
23023   "<label> <sub-domain> <set> <bsl> [del]")                             \
23024 _(bier_route_add_del,                                                   \
23025   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23026   "[<intfc> | sw_if_index <id>]"                                        \
23027   "[weight <n>] [del] [multipath]")                                     \
23028 _(proxy_arp_add_del,                                                    \
23029   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23030 _(proxy_arp_intfc_enable_disable,                                       \
23031   "<intfc> | sw_if_index <id> enable | disable")                        \
23032 _(sw_interface_set_unnumbered,                                          \
23033   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23034 _(ip_neighbor_add_del,                                                  \
23035   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23036   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23037 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23038 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23039   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23040   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23041   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23042 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23043 _(reset_fib, "vrf <n> [ipv6]")                                          \
23044 _(dhcp_proxy_config,                                                    \
23045   "svr <v46-address> src <v46-address>\n"                               \
23046    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23047 _(dhcp_proxy_set_vss,                                                   \
23048   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23049 _(dhcp_proxy_dump, "ip6")                                               \
23050 _(dhcp_client_config,                                                   \
23051   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23052 _(set_ip_flow_hash,                                                     \
23053   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23054 _(sw_interface_ip6_enable_disable,                                      \
23055   "<intfc> | sw_if_index <id> enable | disable")                        \
23056 _(ip6nd_proxy_add_del,                                                  \
23057   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23058 _(ip6nd_proxy_dump, "")                                                 \
23059 _(sw_interface_ip6nd_ra_prefix,                                         \
23060   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23061   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23062   "[nolink] [isno]")                                                    \
23063 _(sw_interface_ip6nd_ra_config,                                         \
23064   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23065   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23066   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23067 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23068 _(l2_patch_add_del,                                                     \
23069   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23070   "enable | disable")                                                   \
23071 _(sr_localsid_add_del,                                                  \
23072   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23073   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23074 _(classify_add_del_table,                                               \
23075   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23076   " [del] [del-chain] mask <mask-value>\n"                              \
23077   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23078   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23079 _(classify_add_del_session,                                             \
23080   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23081   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23082   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23083   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23084 _(classify_set_interface_ip_table,                                      \
23085   "<intfc> | sw_if_index <nn> table <nn>")                              \
23086 _(classify_set_interface_l2_tables,                                     \
23087   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23088   "  [other-table <nn>]")                                               \
23089 _(get_node_index, "node <node-name")                                    \
23090 _(add_node_next, "node <node-name> next <next-node-name>")              \
23091 _(l2tpv3_create_tunnel,                                                 \
23092   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23093   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23094   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23095 _(l2tpv3_set_tunnel_cookies,                                            \
23096   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23097   "[new_remote_cookie <nn>]\n")                                         \
23098 _(l2tpv3_interface_enable_disable,                                      \
23099   "<intfc> | sw_if_index <nn> enable | disable")                        \
23100 _(l2tpv3_set_lookup_key,                                                \
23101   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23102 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23103 _(vxlan_offload_rx,                                                     \
23104   "hw { <interface name> | hw_if_index <nn>} "                          \
23105   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23106 _(vxlan_add_del_tunnel,                                                 \
23107   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23108   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23109   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23110 _(geneve_add_del_tunnel,                                                \
23111   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23112   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23113   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23114 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23115 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23116 _(gre_add_del_tunnel,                                                   \
23117   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23118   "[teb | erspan <session-id>] [del]")                                  \
23119 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23120 _(l2_fib_clear_table, "")                                               \
23121 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23122 _(l2_interface_vlan_tag_rewrite,                                        \
23123   "<intfc> | sw_if_index <nn> \n"                                       \
23124   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23125   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23126 _(create_vhost_user_if,                                                 \
23127         "socket <filename> [server] [renumber <dev_instance>] "         \
23128         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23129         "[mac <mac_address>]")                                          \
23130 _(modify_vhost_user_if,                                                 \
23131         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23132         "[server] [renumber <dev_instance>]")                           \
23133 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23134 _(sw_interface_vhost_user_dump, "")                                     \
23135 _(show_version, "")                                                     \
23136 _(show_threads, "")                                                     \
23137 _(vxlan_gpe_add_del_tunnel,                                             \
23138   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23139   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23140   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23141   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23142 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23143 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23144 _(interface_name_renumber,                                              \
23145   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23146 _(input_acl_set_interface,                                              \
23147   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23148   "  [l2-table <nn>] [del]")                                            \
23149 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23150 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23151   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23152 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23153 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23154 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23155 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23156 _(ip_dump, "ipv4 | ipv6")                                               \
23157 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23158 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23159   "  spid_id <n> ")                                                     \
23160 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23161   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23162   "  integ_alg <alg> integ_key <hex>")                                  \
23163 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
23164   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23165   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23166   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23167 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23168 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23169   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23170   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23171   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23172   "  [instance <n>]")     \
23173 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23174 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23175   "  <alg> <hex>\n")                                                    \
23176 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23177 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23178 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23179   "(auth_data 0x<data> | auth_data <data>)")                            \
23180 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23181   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23182 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23183   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23184   "(local|remote)")                                                     \
23185 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23186 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23187 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23188 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23189 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23190 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23191 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23192 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23193 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23194 _(delete_loopback,"sw_if_index <nn>")                                   \
23195 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23196 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
23197 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
23198 _(want_interface_events,  "enable|disable")                             \
23199 _(get_first_msg_id, "client <name>")                                    \
23200 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23201 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23202   "fib-id <nn> [ip4][ip6][default]")                                    \
23203 _(get_node_graph, " ")                                                  \
23204 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23205 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23206 _(ioam_disable, "")                                                     \
23207 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23208                             " sw_if_index <sw_if_index> p <priority> "  \
23209                             "w <weight>] [del]")                        \
23210 _(one_add_del_locator, "locator-set <locator_name> "                    \
23211                         "iface <intf> | sw_if_index <sw_if_index> "     \
23212                         "p <priority> w <weight> [del]")                \
23213 _(one_add_del_local_eid,"vni <vni> eid "                                \
23214                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23215                          "locator-set <locator_name> [del]"             \
23216                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23217 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23218 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23219 _(one_enable_disable, "enable|disable")                                 \
23220 _(one_map_register_enable_disable, "enable|disable")                    \
23221 _(one_map_register_fallback_threshold, "<value>")                       \
23222 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23223 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23224                                "[seid <seid>] "                         \
23225                                "rloc <locator> p <prio> "               \
23226                                "w <weight> [rloc <loc> ... ] "          \
23227                                "action <action> [del-all]")             \
23228 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23229                           "<local-eid>")                                \
23230 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23231 _(one_use_petr, "ip-address> | disable")                                \
23232 _(one_map_request_mode, "src-dst|dst-only")                             \
23233 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23234 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23235 _(one_locator_set_dump, "[local | remote]")                             \
23236 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23237 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23238                        "[local] | [remote]")                            \
23239 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23240 _(one_ndp_bd_get, "")                                                   \
23241 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23242 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23243 _(one_l2_arp_bd_get, "")                                                \
23244 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23245 _(one_stats_enable_disable, "enable|disable")                           \
23246 _(show_one_stats_enable_disable, "")                                    \
23247 _(one_eid_table_vni_dump, "")                                           \
23248 _(one_eid_table_map_dump, "l2|l3")                                      \
23249 _(one_map_resolver_dump, "")                                            \
23250 _(one_map_server_dump, "")                                              \
23251 _(one_adjacencies_get, "vni <vni>")                                     \
23252 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23253 _(show_one_rloc_probe_state, "")                                        \
23254 _(show_one_map_register_state, "")                                      \
23255 _(show_one_status, "")                                                  \
23256 _(one_stats_dump, "")                                                   \
23257 _(one_stats_flush, "")                                                  \
23258 _(one_get_map_request_itr_rlocs, "")                                    \
23259 _(one_map_register_set_ttl, "<ttl>")                                    \
23260 _(one_set_transport_protocol, "udp|api")                                \
23261 _(one_get_transport_protocol, "")                                       \
23262 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23263 _(one_show_xtr_mode, "")                                                \
23264 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23265 _(one_show_pitr_mode, "")                                               \
23266 _(one_enable_disable_petr_mode, "enable|disable")                       \
23267 _(one_show_petr_mode, "")                                               \
23268 _(show_one_nsh_mapping, "")                                             \
23269 _(show_one_pitr, "")                                                    \
23270 _(show_one_use_petr, "")                                                \
23271 _(show_one_map_request_mode, "")                                        \
23272 _(show_one_map_register_ttl, "")                                        \
23273 _(show_one_map_register_fallback_threshold, "")                         \
23274 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23275                             " sw_if_index <sw_if_index> p <priority> "  \
23276                             "w <weight>] [del]")                        \
23277 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23278                         "iface <intf> | sw_if_index <sw_if_index> "     \
23279                         "p <priority> w <weight> [del]")                \
23280 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23281                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23282                          "locator-set <locator_name> [del]"             \
23283                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23284 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23285 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23286 _(lisp_enable_disable, "enable|disable")                                \
23287 _(lisp_map_register_enable_disable, "enable|disable")                   \
23288 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23289 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23290                                "[seid <seid>] "                         \
23291                                "rloc <locator> p <prio> "               \
23292                                "w <weight> [rloc <loc> ... ] "          \
23293                                "action <action> [del-all]")             \
23294 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23295                           "<local-eid>")                                \
23296 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23297 _(lisp_use_petr, "<ip-address> | disable")                              \
23298 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23299 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23300 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23301 _(lisp_locator_set_dump, "[local | remote]")                            \
23302 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23303 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23304                        "[local] | [remote]")                            \
23305 _(lisp_eid_table_vni_dump, "")                                          \
23306 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23307 _(lisp_map_resolver_dump, "")                                           \
23308 _(lisp_map_server_dump, "")                                             \
23309 _(lisp_adjacencies_get, "vni <vni>")                                    \
23310 _(gpe_fwd_entry_vnis_get, "")                                           \
23311 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23312 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23313                                 "[table <table-id>]")                   \
23314 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23315 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23316 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23317 _(gpe_get_encap_mode, "")                                               \
23318 _(lisp_gpe_add_del_iface, "up|down")                                    \
23319 _(lisp_gpe_enable_disable, "enable|disable")                            \
23320 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23321   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23322 _(show_lisp_rloc_probe_state, "")                                       \
23323 _(show_lisp_map_register_state, "")                                     \
23324 _(show_lisp_status, "")                                                 \
23325 _(lisp_get_map_request_itr_rlocs, "")                                   \
23326 _(show_lisp_pitr, "")                                                   \
23327 _(show_lisp_use_petr, "")                                               \
23328 _(show_lisp_map_request_mode, "")                                       \
23329 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23330 _(af_packet_delete, "name <host interface name>")                       \
23331 _(af_packet_dump, "")                                                   \
23332 _(policer_add_del, "name <policer name> <params> [del]")                \
23333 _(policer_dump, "[name <policer name>]")                                \
23334 _(policer_classify_set_interface,                                       \
23335   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23336   "  [l2-table <nn>] [del]")                                            \
23337 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23338 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23339     "[master|slave]")                                                   \
23340 _(netmap_delete, "name <interface name>")                               \
23341 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23342 _(mpls_fib_dump, "")                                                    \
23343 _(classify_table_ids, "")                                               \
23344 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23345 _(classify_table_info, "table_id <nn>")                                 \
23346 _(classify_session_dump, "table_id <nn>")                               \
23347 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23348     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23349     "[template_interval <nn>] [udp_checksum]")                          \
23350 _(ipfix_exporter_dump, "")                                              \
23351 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23352 _(ipfix_classify_stream_dump, "")                                       \
23353 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23354 _(ipfix_classify_table_dump, "")                                        \
23355 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23356 _(sw_interface_span_dump, "[l2]")                                           \
23357 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23358 _(pg_create_interface, "if_id <nn>")                                    \
23359 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23360 _(pg_enable_disable, "[stream <id>] disable")                           \
23361 _(ip_source_and_port_range_check_add_del,                               \
23362   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23363 _(ip_source_and_port_range_check_interface_add_del,                     \
23364   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23365   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23366 _(ipsec_gre_add_del_tunnel,                                             \
23367   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23368 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23369 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23370 _(l2_interface_pbb_tag_rewrite,                                         \
23371   "<intfc> | sw_if_index <nn> \n"                                       \
23372   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23373   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23374 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23375 _(flow_classify_set_interface,                                          \
23376   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23377 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23378 _(ip_fib_dump, "")                                                      \
23379 _(ip_mfib_dump, "")                                                     \
23380 _(ip6_fib_dump, "")                                                     \
23381 _(ip6_mfib_dump, "")                                                    \
23382 _(feature_enable_disable, "arc_name <arc_name> "                        \
23383   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23384 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23385 "[disable]")                                                            \
23386 _(l2_xconnect_dump, "")                                                 \
23387 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23388 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23389 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23390 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23391 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23392 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23393 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23394   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23395 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23396 _(sock_init_shm, "size <nnn>")                                          \
23397 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23398 _(dns_enable_disable, "[enable][disable]")                              \
23399 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23400 _(dns_resolve_name, "<hostname>")                                       \
23401 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23402 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23403 _(dns_resolve_name, "<hostname>")                                       \
23404 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23405   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23406 _(session_rules_dump, "")                                               \
23407 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23408 _(output_acl_set_interface,                                             \
23409   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23410   "  [l2-table <nn>] [del]")                                            \
23411 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23412
23413 /* List of command functions, CLI names map directly to functions */
23414 #define foreach_cli_function                                    \
23415 _(comment, "usage: comment <ignore-rest-of-line>")              \
23416 _(dump_interface_table, "usage: dump_interface_table")          \
23417 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23418 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23419 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23420 _(dump_macro_table, "usage: dump_macro_table ")                 \
23421 _(dump_node_table, "usage: dump_node_table")                    \
23422 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23423 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23424 _(echo, "usage: echo <message>")                                \
23425 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23426 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23427 _(help, "usage: help")                                          \
23428 _(q, "usage: quit")                                             \
23429 _(quit, "usage: quit")                                          \
23430 _(search_node_table, "usage: search_node_table <name>...")      \
23431 _(set, "usage: set <variable-name> <value>")                    \
23432 _(script, "usage: script <file-name>")                          \
23433 _(statseg, "usage: statseg");                                   \
23434 _(unset, "usage: unset <variable-name>")
23435
23436 #define _(N,n)                                  \
23437     static void vl_api_##n##_t_handler_uni      \
23438     (vl_api_##n##_t * mp)                       \
23439     {                                           \
23440         vat_main_t * vam = &vat_main;           \
23441         if (vam->json_output) {                 \
23442             vl_api_##n##_t_handler_json(mp);    \
23443         } else {                                \
23444             vl_api_##n##_t_handler(mp);         \
23445         }                                       \
23446     }
23447 foreach_vpe_api_reply_msg;
23448 #if VPP_API_TEST_BUILTIN == 0
23449 foreach_standalone_reply_msg;
23450 #endif
23451 #undef _
23452
23453 void
23454 vat_api_hookup (vat_main_t * vam)
23455 {
23456 #define _(N,n)                                                  \
23457     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23458                            vl_api_##n##_t_handler_uni,          \
23459                            vl_noop_handler,                     \
23460                            vl_api_##n##_t_endian,               \
23461                            vl_api_##n##_t_print,                \
23462                            sizeof(vl_api_##n##_t), 1);
23463   foreach_vpe_api_reply_msg;
23464 #if VPP_API_TEST_BUILTIN == 0
23465   foreach_standalone_reply_msg;
23466 #endif
23467 #undef _
23468
23469 #if (VPP_API_TEST_BUILTIN==0)
23470   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23471
23472   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23473
23474   vam->function_by_name = hash_create_string (0, sizeof (uword));
23475
23476   vam->help_by_name = hash_create_string (0, sizeof (uword));
23477 #endif
23478
23479   /* API messages we can send */
23480 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23481   foreach_vpe_api_msg;
23482 #undef _
23483
23484   /* Help strings */
23485 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23486   foreach_vpe_api_msg;
23487 #undef _
23488
23489   /* CLI functions */
23490 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23491   foreach_cli_function;
23492 #undef _
23493
23494   /* Help strings */
23495 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23496   foreach_cli_function;
23497 #undef _
23498 }
23499
23500 #if VPP_API_TEST_BUILTIN
23501 static clib_error_t *
23502 vat_api_hookup_shim (vlib_main_t * vm)
23503 {
23504   vat_api_hookup (&vat_main);
23505   return 0;
23506 }
23507
23508 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23509 #endif
23510
23511 /*
23512  * fd.io coding-style-patch-verification: ON
23513  *
23514  * Local Variables:
23515  * eval: (c-set-style "gnu")
23516  * End:
23517  */