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