IPSEC: API modernisation
[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   mp->entry.is_ip_any = is_ip_any;
14928
14929   S (mp);
14930   W (ret);
14931   return ret;
14932 }
14933
14934 static int
14935 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14936 {
14937   unformat_input_t *i = vam->input;
14938   vl_api_ipsec_sad_entry_add_del_t *mp;
14939   u32 sad_id = 0, spi = 0;
14940   u8 *ck = 0, *ik = 0;
14941   u8 is_add = 1;
14942
14943   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14944   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14945   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14946   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14947   vl_api_address_t tun_src, tun_dst;
14948   int ret;
14949
14950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14951     {
14952       if (unformat (i, "del"))
14953         is_add = 0;
14954       else if (unformat (i, "sad_id %d", &sad_id))
14955         ;
14956       else if (unformat (i, "spi %d", &spi))
14957         ;
14958       else if (unformat (i, "esp"))
14959         protocol = IPSEC_API_PROTO_ESP;
14960       else
14961         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14962         {
14963           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14964           if (ADDRESS_IP6 == tun_src.af)
14965             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14966         }
14967       else
14968         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14969         {
14970           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14971           if (ADDRESS_IP6 == tun_src.af)
14972             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14973         }
14974       else
14975         if (unformat (i, "crypto_alg %U",
14976                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14977         ;
14978       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14979         ;
14980       else if (unformat (i, "integ_alg %U",
14981                          unformat_ipsec_api_integ_alg, &integ_alg))
14982         ;
14983       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14984         ;
14985       else
14986         {
14987           clib_warning ("parse error '%U'", format_unformat_error, i);
14988           return -99;
14989         }
14990
14991     }
14992
14993   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14994
14995   mp->is_add = is_add;
14996   mp->entry.sad_id = ntohl (sad_id);
14997   mp->entry.protocol = protocol;
14998   mp->entry.spi = ntohl (spi);
14999   mp->entry.flags = flags;
15000
15001   mp->entry.crypto_algorithm = crypto_alg;
15002   mp->entry.integrity_algorithm = integ_alg;
15003   mp->entry.crypto_key.length = vec_len (ck);
15004   mp->entry.integrity_key.length = vec_len (ik);
15005
15006   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
15007     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
15008
15009   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
15010     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
15011
15012   if (ck)
15013     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
15014   if (ik)
15015     clib_memcpy (mp->entry.integrity_key.data, ik,
15016                  mp->entry.integrity_key.length);
15017
15018   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
15019     {
15020       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
15021                    sizeof (mp->entry.tunnel_src));
15022       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
15023                    sizeof (mp->entry.tunnel_dst));
15024     }
15025
15026   S (mp);
15027   W (ret);
15028   return ret;
15029 }
15030
15031 static int
15032 api_ipsec_sa_set_key (vat_main_t * vam)
15033 {
15034   unformat_input_t *i = vam->input;
15035   vl_api_ipsec_sa_set_key_t *mp;
15036   u32 sa_id;
15037   u8 *ck = 0, *ik = 0;
15038   int ret;
15039
15040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (i, "sa_id %d", &sa_id))
15043         ;
15044       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15045         ;
15046       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15047         ;
15048       else
15049         {
15050           clib_warning ("parse error '%U'", format_unformat_error, i);
15051           return -99;
15052         }
15053     }
15054
15055   M (IPSEC_SA_SET_KEY, mp);
15056
15057   mp->sa_id = ntohl (sa_id);
15058   mp->crypto_key.length = vec_len (ck);
15059   mp->integrity_key.length = vec_len (ik);
15060
15061   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15062     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15063
15064   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15065     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15066
15067   if (ck)
15068     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15069   if (ik)
15070     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15071
15072   S (mp);
15073   W (ret);
15074   return ret;
15075 }
15076
15077 static int
15078 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15079 {
15080   unformat_input_t *i = vam->input;
15081   vl_api_ipsec_tunnel_if_add_del_t *mp;
15082   u32 local_spi = 0, remote_spi = 0;
15083   u32 crypto_alg = 0, integ_alg = 0;
15084   u8 *lck = NULL, *rck = NULL;
15085   u8 *lik = NULL, *rik = NULL;
15086   ip4_address_t local_ip = { {0} };
15087   ip4_address_t remote_ip = { {0} };
15088   u8 is_add = 1;
15089   u8 esn = 0;
15090   u8 anti_replay = 0;
15091   u8 renumber = 0;
15092   u32 instance = ~0;
15093   int ret;
15094
15095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15096     {
15097       if (unformat (i, "del"))
15098         is_add = 0;
15099       else if (unformat (i, "esn"))
15100         esn = 1;
15101       else if (unformat (i, "anti_replay"))
15102         anti_replay = 1;
15103       else if (unformat (i, "local_spi %d", &local_spi))
15104         ;
15105       else if (unformat (i, "remote_spi %d", &remote_spi))
15106         ;
15107       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15108         ;
15109       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15110         ;
15111       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15112         ;
15113       else
15114         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15115         ;
15116       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15117         ;
15118       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15119         ;
15120       else
15121         if (unformat
15122             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15123         {
15124           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15125             {
15126               errmsg ("unsupported crypto-alg: '%U'\n",
15127                       format_ipsec_crypto_alg, crypto_alg);
15128               return -99;
15129             }
15130         }
15131       else
15132         if (unformat
15133             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15134         {
15135           if (integ_alg >= IPSEC_INTEG_N_ALG)
15136             {
15137               errmsg ("unsupported integ-alg: '%U'\n",
15138                       format_ipsec_integ_alg, integ_alg);
15139               return -99;
15140             }
15141         }
15142       else if (unformat (i, "instance %u", &instance))
15143         renumber = 1;
15144       else
15145         {
15146           errmsg ("parse error '%U'\n", format_unformat_error, i);
15147           return -99;
15148         }
15149     }
15150
15151   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15152
15153   mp->is_add = is_add;
15154   mp->esn = esn;
15155   mp->anti_replay = anti_replay;
15156
15157   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15158   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15159
15160   mp->local_spi = htonl (local_spi);
15161   mp->remote_spi = htonl (remote_spi);
15162   mp->crypto_alg = (u8) crypto_alg;
15163
15164   mp->local_crypto_key_len = 0;
15165   if (lck)
15166     {
15167       mp->local_crypto_key_len = vec_len (lck);
15168       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15169         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15170       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15171     }
15172
15173   mp->remote_crypto_key_len = 0;
15174   if (rck)
15175     {
15176       mp->remote_crypto_key_len = vec_len (rck);
15177       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15178         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15179       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15180     }
15181
15182   mp->integ_alg = (u8) integ_alg;
15183
15184   mp->local_integ_key_len = 0;
15185   if (lik)
15186     {
15187       mp->local_integ_key_len = vec_len (lik);
15188       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15189         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15190       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15191     }
15192
15193   mp->remote_integ_key_len = 0;
15194   if (rik)
15195     {
15196       mp->remote_integ_key_len = vec_len (rik);
15197       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15198         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15199       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15200     }
15201
15202   if (renumber)
15203     {
15204       mp->renumber = renumber;
15205       mp->show_instance = ntohl (instance);
15206     }
15207
15208   S (mp);
15209   W (ret);
15210   return ret;
15211 }
15212
15213 static void
15214 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15215 {
15216   vat_main_t *vam = &vat_main;
15217
15218   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15219          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15220          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15221          "tunnel_src_addr %U tunnel_dst_addr %U "
15222          "salt %u seq_outbound %lu last_seq_inbound %lu "
15223          "replay_window %lu total_data_size %lu\n",
15224          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15225          mp->protocol,
15226          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15227          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15228          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15229          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15230          mp->tunnel_src_addr,
15231          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15232          mp->tunnel_dst_addr,
15233          ntohl (mp->salt),
15234          clib_net_to_host_u64 (mp->seq_outbound),
15235          clib_net_to_host_u64 (mp->last_seq_inbound),
15236          clib_net_to_host_u64 (mp->replay_window),
15237          clib_net_to_host_u64 (mp->total_data_size));
15238 }
15239
15240 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15241 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15242
15243 static void vl_api_ipsec_sa_details_t_handler_json
15244   (vl_api_ipsec_sa_details_t * mp)
15245 {
15246   vat_main_t *vam = &vat_main;
15247   vat_json_node_t *node = NULL;
15248   struct in_addr src_ip4, dst_ip4;
15249   struct in6_addr src_ip6, dst_ip6;
15250
15251   if (VAT_JSON_ARRAY != vam->json_tree.type)
15252     {
15253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15254       vat_json_init_array (&vam->json_tree);
15255     }
15256   node = vat_json_array_add (&vam->json_tree);
15257
15258   vat_json_init_object (node);
15259   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15260   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15261   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15262   vat_json_object_add_uint (node, "proto", mp->protocol);
15263   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15264   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15265   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15266   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15267   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15268   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15269   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15270                              mp->crypto_key_len);
15271   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15272                              mp->integ_key_len);
15273   if (mp->is_tunnel_ip6)
15274     {
15275       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15276       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15277       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15278       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15279     }
15280   else
15281     {
15282       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15283       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15284       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15285       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15286     }
15287   vat_json_object_add_uint (node, "replay_window",
15288                             clib_net_to_host_u64 (mp->replay_window));
15289   vat_json_object_add_uint (node, "total_data_size",
15290                             clib_net_to_host_u64 (mp->total_data_size));
15291
15292 }
15293
15294 static int
15295 api_ipsec_sa_dump (vat_main_t * vam)
15296 {
15297   unformat_input_t *i = vam->input;
15298   vl_api_ipsec_sa_dump_t *mp;
15299   vl_api_control_ping_t *mp_ping;
15300   u32 sa_id = ~0;
15301   int ret;
15302
15303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15304     {
15305       if (unformat (i, "sa_id %d", &sa_id))
15306         ;
15307       else
15308         {
15309           clib_warning ("parse error '%U'", format_unformat_error, i);
15310           return -99;
15311         }
15312     }
15313
15314   M (IPSEC_SA_DUMP, mp);
15315
15316   mp->sa_id = ntohl (sa_id);
15317
15318   S (mp);
15319
15320   /* Use a control ping for synchronization */
15321   M (CONTROL_PING, mp_ping);
15322   S (mp_ping);
15323
15324   W (ret);
15325   return ret;
15326 }
15327
15328 static int
15329 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15330 {
15331   unformat_input_t *i = vam->input;
15332   vl_api_ipsec_tunnel_if_set_key_t *mp;
15333   u32 sw_if_index = ~0;
15334   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15335   u8 *key = 0;
15336   u32 alg = ~0;
15337   int ret;
15338
15339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15340     {
15341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15342         ;
15343       else
15344         if (unformat
15345             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15346         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15347       else
15348         if (unformat
15349             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15350         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15351       else
15352         if (unformat
15353             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15354         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15355       else
15356         if (unformat
15357             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15358         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15359       else if (unformat (i, "%U", unformat_hex_string, &key))
15360         ;
15361       else
15362         {
15363           clib_warning ("parse error '%U'", format_unformat_error, i);
15364           return -99;
15365         }
15366     }
15367
15368   if (sw_if_index == ~0)
15369     {
15370       errmsg ("interface must be specified");
15371       return -99;
15372     }
15373
15374   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15375     {
15376       errmsg ("key type must be specified");
15377       return -99;
15378     }
15379
15380   if (alg == ~0)
15381     {
15382       errmsg ("algorithm must be specified");
15383       return -99;
15384     }
15385
15386   if (vec_len (key) == 0)
15387     {
15388       errmsg ("key must be specified");
15389       return -99;
15390     }
15391
15392   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15393
15394   mp->sw_if_index = htonl (sw_if_index);
15395   mp->alg = alg;
15396   mp->key_type = key_type;
15397   mp->key_len = vec_len (key);
15398   clib_memcpy (mp->key, key, vec_len (key));
15399
15400   S (mp);
15401   W (ret);
15402
15403   return ret;
15404 }
15405
15406 static int
15407 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15408 {
15409   unformat_input_t *i = vam->input;
15410   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15411   u32 sw_if_index = ~0;
15412   u32 sa_id = ~0;
15413   u8 is_outbound = (u8) ~ 0;
15414   int ret;
15415
15416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15417     {
15418       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15419         ;
15420       else if (unformat (i, "sa_id %d", &sa_id))
15421         ;
15422       else if (unformat (i, "outbound"))
15423         is_outbound = 1;
15424       else if (unformat (i, "inbound"))
15425         is_outbound = 0;
15426       else
15427         {
15428           clib_warning ("parse error '%U'", format_unformat_error, i);
15429           return -99;
15430         }
15431     }
15432
15433   if (sw_if_index == ~0)
15434     {
15435       errmsg ("interface must be specified");
15436       return -99;
15437     }
15438
15439   if (sa_id == ~0)
15440     {
15441       errmsg ("SA ID must be specified");
15442       return -99;
15443     }
15444
15445   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15446
15447   mp->sw_if_index = htonl (sw_if_index);
15448   mp->sa_id = htonl (sa_id);
15449   mp->is_outbound = is_outbound;
15450
15451   S (mp);
15452   W (ret);
15453
15454   return ret;
15455 }
15456
15457 static int
15458 api_ikev2_profile_add_del (vat_main_t * vam)
15459 {
15460   unformat_input_t *i = vam->input;
15461   vl_api_ikev2_profile_add_del_t *mp;
15462   u8 is_add = 1;
15463   u8 *name = 0;
15464   int ret;
15465
15466   const char *valid_chars = "a-zA-Z0-9_";
15467
15468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15469     {
15470       if (unformat (i, "del"))
15471         is_add = 0;
15472       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15473         vec_add1 (name, 0);
15474       else
15475         {
15476           errmsg ("parse error '%U'", format_unformat_error, i);
15477           return -99;
15478         }
15479     }
15480
15481   if (!vec_len (name))
15482     {
15483       errmsg ("profile name must be specified");
15484       return -99;
15485     }
15486
15487   if (vec_len (name) > 64)
15488     {
15489       errmsg ("profile name too long");
15490       return -99;
15491     }
15492
15493   M (IKEV2_PROFILE_ADD_DEL, mp);
15494
15495   clib_memcpy (mp->name, name, vec_len (name));
15496   mp->is_add = is_add;
15497   vec_free (name);
15498
15499   S (mp);
15500   W (ret);
15501   return ret;
15502 }
15503
15504 static int
15505 api_ikev2_profile_set_auth (vat_main_t * vam)
15506 {
15507   unformat_input_t *i = vam->input;
15508   vl_api_ikev2_profile_set_auth_t *mp;
15509   u8 *name = 0;
15510   u8 *data = 0;
15511   u32 auth_method = 0;
15512   u8 is_hex = 0;
15513   int ret;
15514
15515   const char *valid_chars = "a-zA-Z0-9_";
15516
15517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15518     {
15519       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15520         vec_add1 (name, 0);
15521       else if (unformat (i, "auth_method %U",
15522                          unformat_ikev2_auth_method, &auth_method))
15523         ;
15524       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15525         is_hex = 1;
15526       else if (unformat (i, "auth_data %v", &data))
15527         ;
15528       else
15529         {
15530           errmsg ("parse error '%U'", format_unformat_error, i);
15531           return -99;
15532         }
15533     }
15534
15535   if (!vec_len (name))
15536     {
15537       errmsg ("profile name must be specified");
15538       return -99;
15539     }
15540
15541   if (vec_len (name) > 64)
15542     {
15543       errmsg ("profile name too long");
15544       return -99;
15545     }
15546
15547   if (!vec_len (data))
15548     {
15549       errmsg ("auth_data must be specified");
15550       return -99;
15551     }
15552
15553   if (!auth_method)
15554     {
15555       errmsg ("auth_method must be specified");
15556       return -99;
15557     }
15558
15559   M (IKEV2_PROFILE_SET_AUTH, mp);
15560
15561   mp->is_hex = is_hex;
15562   mp->auth_method = (u8) auth_method;
15563   mp->data_len = vec_len (data);
15564   clib_memcpy (mp->name, name, vec_len (name));
15565   clib_memcpy (mp->data, data, vec_len (data));
15566   vec_free (name);
15567   vec_free (data);
15568
15569   S (mp);
15570   W (ret);
15571   return ret;
15572 }
15573
15574 static int
15575 api_ikev2_profile_set_id (vat_main_t * vam)
15576 {
15577   unformat_input_t *i = vam->input;
15578   vl_api_ikev2_profile_set_id_t *mp;
15579   u8 *name = 0;
15580   u8 *data = 0;
15581   u8 is_local = 0;
15582   u32 id_type = 0;
15583   ip4_address_t ip4;
15584   int ret;
15585
15586   const char *valid_chars = "a-zA-Z0-9_";
15587
15588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15589     {
15590       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15591         vec_add1 (name, 0);
15592       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15593         ;
15594       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15595         {
15596           data = vec_new (u8, 4);
15597           clib_memcpy (data, ip4.as_u8, 4);
15598         }
15599       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15600         ;
15601       else if (unformat (i, "id_data %v", &data))
15602         ;
15603       else if (unformat (i, "local"))
15604         is_local = 1;
15605       else if (unformat (i, "remote"))
15606         is_local = 0;
15607       else
15608         {
15609           errmsg ("parse error '%U'", format_unformat_error, i);
15610           return -99;
15611         }
15612     }
15613
15614   if (!vec_len (name))
15615     {
15616       errmsg ("profile name must be specified");
15617       return -99;
15618     }
15619
15620   if (vec_len (name) > 64)
15621     {
15622       errmsg ("profile name too long");
15623       return -99;
15624     }
15625
15626   if (!vec_len (data))
15627     {
15628       errmsg ("id_data must be specified");
15629       return -99;
15630     }
15631
15632   if (!id_type)
15633     {
15634       errmsg ("id_type must be specified");
15635       return -99;
15636     }
15637
15638   M (IKEV2_PROFILE_SET_ID, mp);
15639
15640   mp->is_local = is_local;
15641   mp->id_type = (u8) id_type;
15642   mp->data_len = vec_len (data);
15643   clib_memcpy (mp->name, name, vec_len (name));
15644   clib_memcpy (mp->data, data, vec_len (data));
15645   vec_free (name);
15646   vec_free (data);
15647
15648   S (mp);
15649   W (ret);
15650   return ret;
15651 }
15652
15653 static int
15654 api_ikev2_profile_set_ts (vat_main_t * vam)
15655 {
15656   unformat_input_t *i = vam->input;
15657   vl_api_ikev2_profile_set_ts_t *mp;
15658   u8 *name = 0;
15659   u8 is_local = 0;
15660   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15661   ip4_address_t start_addr, end_addr;
15662
15663   const char *valid_chars = "a-zA-Z0-9_";
15664   int ret;
15665
15666   start_addr.as_u32 = 0;
15667   end_addr.as_u32 = (u32) ~ 0;
15668
15669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15672         vec_add1 (name, 0);
15673       else if (unformat (i, "protocol %d", &proto))
15674         ;
15675       else if (unformat (i, "start_port %d", &start_port))
15676         ;
15677       else if (unformat (i, "end_port %d", &end_port))
15678         ;
15679       else
15680         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15681         ;
15682       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15683         ;
15684       else if (unformat (i, "local"))
15685         is_local = 1;
15686       else if (unformat (i, "remote"))
15687         is_local = 0;
15688       else
15689         {
15690           errmsg ("parse error '%U'", format_unformat_error, i);
15691           return -99;
15692         }
15693     }
15694
15695   if (!vec_len (name))
15696     {
15697       errmsg ("profile name must be specified");
15698       return -99;
15699     }
15700
15701   if (vec_len (name) > 64)
15702     {
15703       errmsg ("profile name too long");
15704       return -99;
15705     }
15706
15707   M (IKEV2_PROFILE_SET_TS, mp);
15708
15709   mp->is_local = is_local;
15710   mp->proto = (u8) proto;
15711   mp->start_port = (u16) start_port;
15712   mp->end_port = (u16) end_port;
15713   mp->start_addr = start_addr.as_u32;
15714   mp->end_addr = end_addr.as_u32;
15715   clib_memcpy (mp->name, name, vec_len (name));
15716   vec_free (name);
15717
15718   S (mp);
15719   W (ret);
15720   return ret;
15721 }
15722
15723 static int
15724 api_ikev2_set_local_key (vat_main_t * vam)
15725 {
15726   unformat_input_t *i = vam->input;
15727   vl_api_ikev2_set_local_key_t *mp;
15728   u8 *file = 0;
15729   int ret;
15730
15731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15732     {
15733       if (unformat (i, "file %v", &file))
15734         vec_add1 (file, 0);
15735       else
15736         {
15737           errmsg ("parse error '%U'", format_unformat_error, i);
15738           return -99;
15739         }
15740     }
15741
15742   if (!vec_len (file))
15743     {
15744       errmsg ("RSA key file must be specified");
15745       return -99;
15746     }
15747
15748   if (vec_len (file) > 256)
15749     {
15750       errmsg ("file name too long");
15751       return -99;
15752     }
15753
15754   M (IKEV2_SET_LOCAL_KEY, mp);
15755
15756   clib_memcpy (mp->key_file, file, vec_len (file));
15757   vec_free (file);
15758
15759   S (mp);
15760   W (ret);
15761   return ret;
15762 }
15763
15764 static int
15765 api_ikev2_set_responder (vat_main_t * vam)
15766 {
15767   unformat_input_t *i = vam->input;
15768   vl_api_ikev2_set_responder_t *mp;
15769   int ret;
15770   u8 *name = 0;
15771   u32 sw_if_index = ~0;
15772   ip4_address_t address;
15773
15774   const char *valid_chars = "a-zA-Z0-9_";
15775
15776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15777     {
15778       if (unformat
15779           (i, "%U interface %d address %U", unformat_token, valid_chars,
15780            &name, &sw_if_index, unformat_ip4_address, &address))
15781         vec_add1 (name, 0);
15782       else
15783         {
15784           errmsg ("parse error '%U'", format_unformat_error, i);
15785           return -99;
15786         }
15787     }
15788
15789   if (!vec_len (name))
15790     {
15791       errmsg ("profile name must be specified");
15792       return -99;
15793     }
15794
15795   if (vec_len (name) > 64)
15796     {
15797       errmsg ("profile name too long");
15798       return -99;
15799     }
15800
15801   M (IKEV2_SET_RESPONDER, mp);
15802
15803   clib_memcpy (mp->name, name, vec_len (name));
15804   vec_free (name);
15805
15806   mp->sw_if_index = sw_if_index;
15807   clib_memcpy (mp->address, &address, sizeof (address));
15808
15809   S (mp);
15810   W (ret);
15811   return ret;
15812 }
15813
15814 static int
15815 api_ikev2_set_ike_transforms (vat_main_t * vam)
15816 {
15817   unformat_input_t *i = vam->input;
15818   vl_api_ikev2_set_ike_transforms_t *mp;
15819   int ret;
15820   u8 *name = 0;
15821   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15822
15823   const char *valid_chars = "a-zA-Z0-9_";
15824
15825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15826     {
15827       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15828                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15829         vec_add1 (name, 0);
15830       else
15831         {
15832           errmsg ("parse error '%U'", format_unformat_error, i);
15833           return -99;
15834         }
15835     }
15836
15837   if (!vec_len (name))
15838     {
15839       errmsg ("profile name must be specified");
15840       return -99;
15841     }
15842
15843   if (vec_len (name) > 64)
15844     {
15845       errmsg ("profile name too long");
15846       return -99;
15847     }
15848
15849   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15850
15851   clib_memcpy (mp->name, name, vec_len (name));
15852   vec_free (name);
15853   mp->crypto_alg = crypto_alg;
15854   mp->crypto_key_size = crypto_key_size;
15855   mp->integ_alg = integ_alg;
15856   mp->dh_group = dh_group;
15857
15858   S (mp);
15859   W (ret);
15860   return ret;
15861 }
15862
15863
15864 static int
15865 api_ikev2_set_esp_transforms (vat_main_t * vam)
15866 {
15867   unformat_input_t *i = vam->input;
15868   vl_api_ikev2_set_esp_transforms_t *mp;
15869   int ret;
15870   u8 *name = 0;
15871   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15872
15873   const char *valid_chars = "a-zA-Z0-9_";
15874
15875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15876     {
15877       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15878                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15879         vec_add1 (name, 0);
15880       else
15881         {
15882           errmsg ("parse error '%U'", format_unformat_error, i);
15883           return -99;
15884         }
15885     }
15886
15887   if (!vec_len (name))
15888     {
15889       errmsg ("profile name must be specified");
15890       return -99;
15891     }
15892
15893   if (vec_len (name) > 64)
15894     {
15895       errmsg ("profile name too long");
15896       return -99;
15897     }
15898
15899   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15900
15901   clib_memcpy (mp->name, name, vec_len (name));
15902   vec_free (name);
15903   mp->crypto_alg = crypto_alg;
15904   mp->crypto_key_size = crypto_key_size;
15905   mp->integ_alg = integ_alg;
15906   mp->dh_group = dh_group;
15907
15908   S (mp);
15909   W (ret);
15910   return ret;
15911 }
15912
15913 static int
15914 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15915 {
15916   unformat_input_t *i = vam->input;
15917   vl_api_ikev2_set_sa_lifetime_t *mp;
15918   int ret;
15919   u8 *name = 0;
15920   u64 lifetime, lifetime_maxdata;
15921   u32 lifetime_jitter, handover;
15922
15923   const char *valid_chars = "a-zA-Z0-9_";
15924
15925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15926     {
15927       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15928                     &lifetime, &lifetime_jitter, &handover,
15929                     &lifetime_maxdata))
15930         vec_add1 (name, 0);
15931       else
15932         {
15933           errmsg ("parse error '%U'", format_unformat_error, i);
15934           return -99;
15935         }
15936     }
15937
15938   if (!vec_len (name))
15939     {
15940       errmsg ("profile name must be specified");
15941       return -99;
15942     }
15943
15944   if (vec_len (name) > 64)
15945     {
15946       errmsg ("profile name too long");
15947       return -99;
15948     }
15949
15950   M (IKEV2_SET_SA_LIFETIME, mp);
15951
15952   clib_memcpy (mp->name, name, vec_len (name));
15953   vec_free (name);
15954   mp->lifetime = lifetime;
15955   mp->lifetime_jitter = lifetime_jitter;
15956   mp->handover = handover;
15957   mp->lifetime_maxdata = lifetime_maxdata;
15958
15959   S (mp);
15960   W (ret);
15961   return ret;
15962 }
15963
15964 static int
15965 api_ikev2_initiate_sa_init (vat_main_t * vam)
15966 {
15967   unformat_input_t *i = vam->input;
15968   vl_api_ikev2_initiate_sa_init_t *mp;
15969   int ret;
15970   u8 *name = 0;
15971
15972   const char *valid_chars = "a-zA-Z0-9_";
15973
15974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15975     {
15976       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15977         vec_add1 (name, 0);
15978       else
15979         {
15980           errmsg ("parse error '%U'", format_unformat_error, i);
15981           return -99;
15982         }
15983     }
15984
15985   if (!vec_len (name))
15986     {
15987       errmsg ("profile name must be specified");
15988       return -99;
15989     }
15990
15991   if (vec_len (name) > 64)
15992     {
15993       errmsg ("profile name too long");
15994       return -99;
15995     }
15996
15997   M (IKEV2_INITIATE_SA_INIT, mp);
15998
15999   clib_memcpy (mp->name, name, vec_len (name));
16000   vec_free (name);
16001
16002   S (mp);
16003   W (ret);
16004   return ret;
16005 }
16006
16007 static int
16008 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16009 {
16010   unformat_input_t *i = vam->input;
16011   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16012   int ret;
16013   u64 ispi;
16014
16015
16016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16017     {
16018       if (unformat (i, "%lx", &ispi))
16019         ;
16020       else
16021         {
16022           errmsg ("parse error '%U'", format_unformat_error, i);
16023           return -99;
16024         }
16025     }
16026
16027   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16028
16029   mp->ispi = ispi;
16030
16031   S (mp);
16032   W (ret);
16033   return ret;
16034 }
16035
16036 static int
16037 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16038 {
16039   unformat_input_t *i = vam->input;
16040   vl_api_ikev2_initiate_del_child_sa_t *mp;
16041   int ret;
16042   u32 ispi;
16043
16044
16045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16046     {
16047       if (unformat (i, "%x", &ispi))
16048         ;
16049       else
16050         {
16051           errmsg ("parse error '%U'", format_unformat_error, i);
16052           return -99;
16053         }
16054     }
16055
16056   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16057
16058   mp->ispi = ispi;
16059
16060   S (mp);
16061   W (ret);
16062   return ret;
16063 }
16064
16065 static int
16066 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16067 {
16068   unformat_input_t *i = vam->input;
16069   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16070   int ret;
16071   u32 ispi;
16072
16073
16074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16075     {
16076       if (unformat (i, "%x", &ispi))
16077         ;
16078       else
16079         {
16080           errmsg ("parse error '%U'", format_unformat_error, i);
16081           return -99;
16082         }
16083     }
16084
16085   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16086
16087   mp->ispi = ispi;
16088
16089   S (mp);
16090   W (ret);
16091   return ret;
16092 }
16093
16094 static int
16095 api_get_first_msg_id (vat_main_t * vam)
16096 {
16097   vl_api_get_first_msg_id_t *mp;
16098   unformat_input_t *i = vam->input;
16099   u8 *name;
16100   u8 name_set = 0;
16101   int ret;
16102
16103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16104     {
16105       if (unformat (i, "client %s", &name))
16106         name_set = 1;
16107       else
16108         break;
16109     }
16110
16111   if (name_set == 0)
16112     {
16113       errmsg ("missing client name");
16114       return -99;
16115     }
16116   vec_add1 (name, 0);
16117
16118   if (vec_len (name) > 63)
16119     {
16120       errmsg ("client name too long");
16121       return -99;
16122     }
16123
16124   M (GET_FIRST_MSG_ID, mp);
16125   clib_memcpy (mp->name, name, vec_len (name));
16126   S (mp);
16127   W (ret);
16128   return ret;
16129 }
16130
16131 static int
16132 api_cop_interface_enable_disable (vat_main_t * vam)
16133 {
16134   unformat_input_t *line_input = vam->input;
16135   vl_api_cop_interface_enable_disable_t *mp;
16136   u32 sw_if_index = ~0;
16137   u8 enable_disable = 1;
16138   int ret;
16139
16140   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16141     {
16142       if (unformat (line_input, "disable"))
16143         enable_disable = 0;
16144       if (unformat (line_input, "enable"))
16145         enable_disable = 1;
16146       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16147                          vam, &sw_if_index))
16148         ;
16149       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16150         ;
16151       else
16152         break;
16153     }
16154
16155   if (sw_if_index == ~0)
16156     {
16157       errmsg ("missing interface name or sw_if_index");
16158       return -99;
16159     }
16160
16161   /* Construct the API message */
16162   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16163   mp->sw_if_index = ntohl (sw_if_index);
16164   mp->enable_disable = enable_disable;
16165
16166   /* send it... */
16167   S (mp);
16168   /* Wait for the reply */
16169   W (ret);
16170   return ret;
16171 }
16172
16173 static int
16174 api_cop_whitelist_enable_disable (vat_main_t * vam)
16175 {
16176   unformat_input_t *line_input = vam->input;
16177   vl_api_cop_whitelist_enable_disable_t *mp;
16178   u32 sw_if_index = ~0;
16179   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16180   u32 fib_id = 0;
16181   int ret;
16182
16183   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16184     {
16185       if (unformat (line_input, "ip4"))
16186         ip4 = 1;
16187       else if (unformat (line_input, "ip6"))
16188         ip6 = 1;
16189       else if (unformat (line_input, "default"))
16190         default_cop = 1;
16191       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16192                          vam, &sw_if_index))
16193         ;
16194       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16195         ;
16196       else if (unformat (line_input, "fib-id %d", &fib_id))
16197         ;
16198       else
16199         break;
16200     }
16201
16202   if (sw_if_index == ~0)
16203     {
16204       errmsg ("missing interface name or sw_if_index");
16205       return -99;
16206     }
16207
16208   /* Construct the API message */
16209   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16210   mp->sw_if_index = ntohl (sw_if_index);
16211   mp->fib_id = ntohl (fib_id);
16212   mp->ip4 = ip4;
16213   mp->ip6 = ip6;
16214   mp->default_cop = default_cop;
16215
16216   /* send it... */
16217   S (mp);
16218   /* Wait for the reply */
16219   W (ret);
16220   return ret;
16221 }
16222
16223 static int
16224 api_get_node_graph (vat_main_t * vam)
16225 {
16226   vl_api_get_node_graph_t *mp;
16227   int ret;
16228
16229   M (GET_NODE_GRAPH, mp);
16230
16231   /* send it... */
16232   S (mp);
16233   /* Wait for the reply */
16234   W (ret);
16235   return ret;
16236 }
16237
16238 /* *INDENT-OFF* */
16239 /** Used for parsing LISP eids */
16240 typedef CLIB_PACKED(struct{
16241   u8 addr[16];   /**< eid address */
16242   u32 len;       /**< prefix length if IP */
16243   u8 type;      /**< type of eid */
16244 }) lisp_eid_vat_t;
16245 /* *INDENT-ON* */
16246
16247 static uword
16248 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16249 {
16250   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16251
16252   clib_memset (a, 0, sizeof (a[0]));
16253
16254   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16255     {
16256       a->type = 0;              /* ipv4 type */
16257     }
16258   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16259     {
16260       a->type = 1;              /* ipv6 type */
16261     }
16262   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16263     {
16264       a->type = 2;              /* mac type */
16265     }
16266   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16267     {
16268       a->type = 3;              /* NSH type */
16269       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16270       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16271     }
16272   else
16273     {
16274       return 0;
16275     }
16276
16277   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16278     {
16279       return 0;
16280     }
16281
16282   return 1;
16283 }
16284
16285 static int
16286 lisp_eid_size_vat (u8 type)
16287 {
16288   switch (type)
16289     {
16290     case 0:
16291       return 4;
16292     case 1:
16293       return 16;
16294     case 2:
16295       return 6;
16296     case 3:
16297       return 5;
16298     }
16299   return 0;
16300 }
16301
16302 static void
16303 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16304 {
16305   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16306 }
16307
16308 static int
16309 api_one_add_del_locator_set (vat_main_t * vam)
16310 {
16311   unformat_input_t *input = vam->input;
16312   vl_api_one_add_del_locator_set_t *mp;
16313   u8 is_add = 1;
16314   u8 *locator_set_name = NULL;
16315   u8 locator_set_name_set = 0;
16316   vl_api_local_locator_t locator, *locators = 0;
16317   u32 sw_if_index, priority, weight;
16318   u32 data_len = 0;
16319
16320   int ret;
16321   /* Parse args required to build the message */
16322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16323     {
16324       if (unformat (input, "del"))
16325         {
16326           is_add = 0;
16327         }
16328       else if (unformat (input, "locator-set %s", &locator_set_name))
16329         {
16330           locator_set_name_set = 1;
16331         }
16332       else if (unformat (input, "sw_if_index %u p %u w %u",
16333                          &sw_if_index, &priority, &weight))
16334         {
16335           locator.sw_if_index = htonl (sw_if_index);
16336           locator.priority = priority;
16337           locator.weight = weight;
16338           vec_add1 (locators, locator);
16339         }
16340       else
16341         if (unformat
16342             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16343              &sw_if_index, &priority, &weight))
16344         {
16345           locator.sw_if_index = htonl (sw_if_index);
16346           locator.priority = priority;
16347           locator.weight = weight;
16348           vec_add1 (locators, locator);
16349         }
16350       else
16351         break;
16352     }
16353
16354   if (locator_set_name_set == 0)
16355     {
16356       errmsg ("missing locator-set name");
16357       vec_free (locators);
16358       return -99;
16359     }
16360
16361   if (vec_len (locator_set_name) > 64)
16362     {
16363       errmsg ("locator-set name too long");
16364       vec_free (locator_set_name);
16365       vec_free (locators);
16366       return -99;
16367     }
16368   vec_add1 (locator_set_name, 0);
16369
16370   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16371
16372   /* Construct the API message */
16373   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16374
16375   mp->is_add = is_add;
16376   clib_memcpy (mp->locator_set_name, locator_set_name,
16377                vec_len (locator_set_name));
16378   vec_free (locator_set_name);
16379
16380   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16381   if (locators)
16382     clib_memcpy (mp->locators, locators, data_len);
16383   vec_free (locators);
16384
16385   /* send it... */
16386   S (mp);
16387
16388   /* Wait for a reply... */
16389   W (ret);
16390   return ret;
16391 }
16392
16393 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16394
16395 static int
16396 api_one_add_del_locator (vat_main_t * vam)
16397 {
16398   unformat_input_t *input = vam->input;
16399   vl_api_one_add_del_locator_t *mp;
16400   u32 tmp_if_index = ~0;
16401   u32 sw_if_index = ~0;
16402   u8 sw_if_index_set = 0;
16403   u8 sw_if_index_if_name_set = 0;
16404   u32 priority = ~0;
16405   u8 priority_set = 0;
16406   u32 weight = ~0;
16407   u8 weight_set = 0;
16408   u8 is_add = 1;
16409   u8 *locator_set_name = NULL;
16410   u8 locator_set_name_set = 0;
16411   int ret;
16412
16413   /* Parse args required to build the message */
16414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16415     {
16416       if (unformat (input, "del"))
16417         {
16418           is_add = 0;
16419         }
16420       else if (unformat (input, "locator-set %s", &locator_set_name))
16421         {
16422           locator_set_name_set = 1;
16423         }
16424       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16425                          &tmp_if_index))
16426         {
16427           sw_if_index_if_name_set = 1;
16428           sw_if_index = tmp_if_index;
16429         }
16430       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16431         {
16432           sw_if_index_set = 1;
16433           sw_if_index = tmp_if_index;
16434         }
16435       else if (unformat (input, "p %d", &priority))
16436         {
16437           priority_set = 1;
16438         }
16439       else if (unformat (input, "w %d", &weight))
16440         {
16441           weight_set = 1;
16442         }
16443       else
16444         break;
16445     }
16446
16447   if (locator_set_name_set == 0)
16448     {
16449       errmsg ("missing locator-set name");
16450       return -99;
16451     }
16452
16453   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16454     {
16455       errmsg ("missing sw_if_index");
16456       vec_free (locator_set_name);
16457       return -99;
16458     }
16459
16460   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16461     {
16462       errmsg ("cannot use both params interface name and sw_if_index");
16463       vec_free (locator_set_name);
16464       return -99;
16465     }
16466
16467   if (priority_set == 0)
16468     {
16469       errmsg ("missing locator-set priority");
16470       vec_free (locator_set_name);
16471       return -99;
16472     }
16473
16474   if (weight_set == 0)
16475     {
16476       errmsg ("missing locator-set weight");
16477       vec_free (locator_set_name);
16478       return -99;
16479     }
16480
16481   if (vec_len (locator_set_name) > 64)
16482     {
16483       errmsg ("locator-set name too long");
16484       vec_free (locator_set_name);
16485       return -99;
16486     }
16487   vec_add1 (locator_set_name, 0);
16488
16489   /* Construct the API message */
16490   M (ONE_ADD_DEL_LOCATOR, mp);
16491
16492   mp->is_add = is_add;
16493   mp->sw_if_index = ntohl (sw_if_index);
16494   mp->priority = priority;
16495   mp->weight = weight;
16496   clib_memcpy (mp->locator_set_name, locator_set_name,
16497                vec_len (locator_set_name));
16498   vec_free (locator_set_name);
16499
16500   /* send it... */
16501   S (mp);
16502
16503   /* Wait for a reply... */
16504   W (ret);
16505   return ret;
16506 }
16507
16508 #define api_lisp_add_del_locator api_one_add_del_locator
16509
16510 uword
16511 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16512 {
16513   u32 *key_id = va_arg (*args, u32 *);
16514   u8 *s = 0;
16515
16516   if (unformat (input, "%s", &s))
16517     {
16518       if (!strcmp ((char *) s, "sha1"))
16519         key_id[0] = HMAC_SHA_1_96;
16520       else if (!strcmp ((char *) s, "sha256"))
16521         key_id[0] = HMAC_SHA_256_128;
16522       else
16523         {
16524           clib_warning ("invalid key_id: '%s'", s);
16525           key_id[0] = HMAC_NO_KEY;
16526         }
16527     }
16528   else
16529     return 0;
16530
16531   vec_free (s);
16532   return 1;
16533 }
16534
16535 static int
16536 api_one_add_del_local_eid (vat_main_t * vam)
16537 {
16538   unformat_input_t *input = vam->input;
16539   vl_api_one_add_del_local_eid_t *mp;
16540   u8 is_add = 1;
16541   u8 eid_set = 0;
16542   lisp_eid_vat_t _eid, *eid = &_eid;
16543   u8 *locator_set_name = 0;
16544   u8 locator_set_name_set = 0;
16545   u32 vni = 0;
16546   u16 key_id = 0;
16547   u8 *key = 0;
16548   int ret;
16549
16550   /* Parse args required to build the message */
16551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16552     {
16553       if (unformat (input, "del"))
16554         {
16555           is_add = 0;
16556         }
16557       else if (unformat (input, "vni %d", &vni))
16558         {
16559           ;
16560         }
16561       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16562         {
16563           eid_set = 1;
16564         }
16565       else if (unformat (input, "locator-set %s", &locator_set_name))
16566         {
16567           locator_set_name_set = 1;
16568         }
16569       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16570         ;
16571       else if (unformat (input, "secret-key %_%v%_", &key))
16572         ;
16573       else
16574         break;
16575     }
16576
16577   if (locator_set_name_set == 0)
16578     {
16579       errmsg ("missing locator-set name");
16580       return -99;
16581     }
16582
16583   if (0 == eid_set)
16584     {
16585       errmsg ("EID address not set!");
16586       vec_free (locator_set_name);
16587       return -99;
16588     }
16589
16590   if (key && (0 == key_id))
16591     {
16592       errmsg ("invalid key_id!");
16593       return -99;
16594     }
16595
16596   if (vec_len (key) > 64)
16597     {
16598       errmsg ("key too long");
16599       vec_free (key);
16600       return -99;
16601     }
16602
16603   if (vec_len (locator_set_name) > 64)
16604     {
16605       errmsg ("locator-set name too long");
16606       vec_free (locator_set_name);
16607       return -99;
16608     }
16609   vec_add1 (locator_set_name, 0);
16610
16611   /* Construct the API message */
16612   M (ONE_ADD_DEL_LOCAL_EID, mp);
16613
16614   mp->is_add = is_add;
16615   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16616   mp->eid_type = eid->type;
16617   mp->prefix_len = eid->len;
16618   mp->vni = clib_host_to_net_u32 (vni);
16619   mp->key_id = clib_host_to_net_u16 (key_id);
16620   clib_memcpy (mp->locator_set_name, locator_set_name,
16621                vec_len (locator_set_name));
16622   clib_memcpy (mp->key, key, vec_len (key));
16623
16624   vec_free (locator_set_name);
16625   vec_free (key);
16626
16627   /* send it... */
16628   S (mp);
16629
16630   /* Wait for a reply... */
16631   W (ret);
16632   return ret;
16633 }
16634
16635 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16636
16637 static int
16638 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16639 {
16640   u32 dp_table = 0, vni = 0;;
16641   unformat_input_t *input = vam->input;
16642   vl_api_gpe_add_del_fwd_entry_t *mp;
16643   u8 is_add = 1;
16644   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16645   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16646   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16647   u32 action = ~0, w;
16648   ip4_address_t rmt_rloc4, lcl_rloc4;
16649   ip6_address_t rmt_rloc6, lcl_rloc6;
16650   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16651   int ret;
16652
16653   clib_memset (&rloc, 0, sizeof (rloc));
16654
16655   /* Parse args required to build the message */
16656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16657     {
16658       if (unformat (input, "del"))
16659         is_add = 0;
16660       else if (unformat (input, "add"))
16661         is_add = 1;
16662       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16663         {
16664           rmt_eid_set = 1;
16665         }
16666       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16667         {
16668           lcl_eid_set = 1;
16669         }
16670       else if (unformat (input, "vrf %d", &dp_table))
16671         ;
16672       else if (unformat (input, "bd %d", &dp_table))
16673         ;
16674       else if (unformat (input, "vni %d", &vni))
16675         ;
16676       else if (unformat (input, "w %d", &w))
16677         {
16678           if (!curr_rloc)
16679             {
16680               errmsg ("No RLOC configured for setting priority/weight!");
16681               return -99;
16682             }
16683           curr_rloc->weight = w;
16684         }
16685       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16686                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16687         {
16688           rloc.is_ip4 = 1;
16689
16690           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16691           rloc.weight = 0;
16692           vec_add1 (lcl_locs, rloc);
16693
16694           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16695           vec_add1 (rmt_locs, rloc);
16696           /* weight saved in rmt loc */
16697           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16698         }
16699       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16700                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16701         {
16702           rloc.is_ip4 = 0;
16703           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16704           rloc.weight = 0;
16705           vec_add1 (lcl_locs, rloc);
16706
16707           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16708           vec_add1 (rmt_locs, rloc);
16709           /* weight saved in rmt loc */
16710           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16711         }
16712       else if (unformat (input, "action %d", &action))
16713         {
16714           ;
16715         }
16716       else
16717         {
16718           clib_warning ("parse error '%U'", format_unformat_error, input);
16719           return -99;
16720         }
16721     }
16722
16723   if (!rmt_eid_set)
16724     {
16725       errmsg ("remote eid addresses not set");
16726       return -99;
16727     }
16728
16729   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16730     {
16731       errmsg ("eid types don't match");
16732       return -99;
16733     }
16734
16735   if (0 == rmt_locs && (u32) ~ 0 == action)
16736     {
16737       errmsg ("action not set for negative mapping");
16738       return -99;
16739     }
16740
16741   /* Construct the API message */
16742   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16743       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16744
16745   mp->is_add = is_add;
16746   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16747   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16748   mp->eid_type = rmt_eid->type;
16749   mp->dp_table = clib_host_to_net_u32 (dp_table);
16750   mp->vni = clib_host_to_net_u32 (vni);
16751   mp->rmt_len = rmt_eid->len;
16752   mp->lcl_len = lcl_eid->len;
16753   mp->action = action;
16754
16755   if (0 != rmt_locs && 0 != lcl_locs)
16756     {
16757       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16758       clib_memcpy (mp->locs, lcl_locs,
16759                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16760
16761       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16762       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16763                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16764     }
16765   vec_free (lcl_locs);
16766   vec_free (rmt_locs);
16767
16768   /* send it... */
16769   S (mp);
16770
16771   /* Wait for a reply... */
16772   W (ret);
16773   return ret;
16774 }
16775
16776 static int
16777 api_one_add_del_map_server (vat_main_t * vam)
16778 {
16779   unformat_input_t *input = vam->input;
16780   vl_api_one_add_del_map_server_t *mp;
16781   u8 is_add = 1;
16782   u8 ipv4_set = 0;
16783   u8 ipv6_set = 0;
16784   ip4_address_t ipv4;
16785   ip6_address_t ipv6;
16786   int ret;
16787
16788   /* Parse args required to build the message */
16789   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16790     {
16791       if (unformat (input, "del"))
16792         {
16793           is_add = 0;
16794         }
16795       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16796         {
16797           ipv4_set = 1;
16798         }
16799       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16800         {
16801           ipv6_set = 1;
16802         }
16803       else
16804         break;
16805     }
16806
16807   if (ipv4_set && ipv6_set)
16808     {
16809       errmsg ("both eid v4 and v6 addresses set");
16810       return -99;
16811     }
16812
16813   if (!ipv4_set && !ipv6_set)
16814     {
16815       errmsg ("eid addresses not set");
16816       return -99;
16817     }
16818
16819   /* Construct the API message */
16820   M (ONE_ADD_DEL_MAP_SERVER, mp);
16821
16822   mp->is_add = is_add;
16823   if (ipv6_set)
16824     {
16825       mp->is_ipv6 = 1;
16826       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16827     }
16828   else
16829     {
16830       mp->is_ipv6 = 0;
16831       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16832     }
16833
16834   /* send it... */
16835   S (mp);
16836
16837   /* Wait for a reply... */
16838   W (ret);
16839   return ret;
16840 }
16841
16842 #define api_lisp_add_del_map_server api_one_add_del_map_server
16843
16844 static int
16845 api_one_add_del_map_resolver (vat_main_t * vam)
16846 {
16847   unformat_input_t *input = vam->input;
16848   vl_api_one_add_del_map_resolver_t *mp;
16849   u8 is_add = 1;
16850   u8 ipv4_set = 0;
16851   u8 ipv6_set = 0;
16852   ip4_address_t ipv4;
16853   ip6_address_t ipv6;
16854   int ret;
16855
16856   /* Parse args required to build the message */
16857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16858     {
16859       if (unformat (input, "del"))
16860         {
16861           is_add = 0;
16862         }
16863       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16864         {
16865           ipv4_set = 1;
16866         }
16867       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16868         {
16869           ipv6_set = 1;
16870         }
16871       else
16872         break;
16873     }
16874
16875   if (ipv4_set && ipv6_set)
16876     {
16877       errmsg ("both eid v4 and v6 addresses set");
16878       return -99;
16879     }
16880
16881   if (!ipv4_set && !ipv6_set)
16882     {
16883       errmsg ("eid addresses not set");
16884       return -99;
16885     }
16886
16887   /* Construct the API message */
16888   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16889
16890   mp->is_add = is_add;
16891   if (ipv6_set)
16892     {
16893       mp->is_ipv6 = 1;
16894       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16895     }
16896   else
16897     {
16898       mp->is_ipv6 = 0;
16899       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16900     }
16901
16902   /* send it... */
16903   S (mp);
16904
16905   /* Wait for a reply... */
16906   W (ret);
16907   return ret;
16908 }
16909
16910 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16911
16912 static int
16913 api_lisp_gpe_enable_disable (vat_main_t * vam)
16914 {
16915   unformat_input_t *input = vam->input;
16916   vl_api_gpe_enable_disable_t *mp;
16917   u8 is_set = 0;
16918   u8 is_en = 1;
16919   int ret;
16920
16921   /* Parse args required to build the message */
16922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16923     {
16924       if (unformat (input, "enable"))
16925         {
16926           is_set = 1;
16927           is_en = 1;
16928         }
16929       else if (unformat (input, "disable"))
16930         {
16931           is_set = 1;
16932           is_en = 0;
16933         }
16934       else
16935         break;
16936     }
16937
16938   if (is_set == 0)
16939     {
16940       errmsg ("Value not set");
16941       return -99;
16942     }
16943
16944   /* Construct the API message */
16945   M (GPE_ENABLE_DISABLE, mp);
16946
16947   mp->is_en = is_en;
16948
16949   /* send it... */
16950   S (mp);
16951
16952   /* Wait for a reply... */
16953   W (ret);
16954   return ret;
16955 }
16956
16957 static int
16958 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16959 {
16960   unformat_input_t *input = vam->input;
16961   vl_api_one_rloc_probe_enable_disable_t *mp;
16962   u8 is_set = 0;
16963   u8 is_en = 0;
16964   int ret;
16965
16966   /* Parse args required to build the message */
16967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16968     {
16969       if (unformat (input, "enable"))
16970         {
16971           is_set = 1;
16972           is_en = 1;
16973         }
16974       else if (unformat (input, "disable"))
16975         is_set = 1;
16976       else
16977         break;
16978     }
16979
16980   if (!is_set)
16981     {
16982       errmsg ("Value not set");
16983       return -99;
16984     }
16985
16986   /* Construct the API message */
16987   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16988
16989   mp->is_enabled = is_en;
16990
16991   /* send it... */
16992   S (mp);
16993
16994   /* Wait for a reply... */
16995   W (ret);
16996   return ret;
16997 }
16998
16999 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17000
17001 static int
17002 api_one_map_register_enable_disable (vat_main_t * vam)
17003 {
17004   unformat_input_t *input = vam->input;
17005   vl_api_one_map_register_enable_disable_t *mp;
17006   u8 is_set = 0;
17007   u8 is_en = 0;
17008   int ret;
17009
17010   /* Parse args required to build the message */
17011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17012     {
17013       if (unformat (input, "enable"))
17014         {
17015           is_set = 1;
17016           is_en = 1;
17017         }
17018       else if (unformat (input, "disable"))
17019         is_set = 1;
17020       else
17021         break;
17022     }
17023
17024   if (!is_set)
17025     {
17026       errmsg ("Value not set");
17027       return -99;
17028     }
17029
17030   /* Construct the API message */
17031   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17032
17033   mp->is_enabled = is_en;
17034
17035   /* send it... */
17036   S (mp);
17037
17038   /* Wait for a reply... */
17039   W (ret);
17040   return ret;
17041 }
17042
17043 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17044
17045 static int
17046 api_one_enable_disable (vat_main_t * vam)
17047 {
17048   unformat_input_t *input = vam->input;
17049   vl_api_one_enable_disable_t *mp;
17050   u8 is_set = 0;
17051   u8 is_en = 0;
17052   int ret;
17053
17054   /* Parse args required to build the message */
17055   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17056     {
17057       if (unformat (input, "enable"))
17058         {
17059           is_set = 1;
17060           is_en = 1;
17061         }
17062       else if (unformat (input, "disable"))
17063         {
17064           is_set = 1;
17065         }
17066       else
17067         break;
17068     }
17069
17070   if (!is_set)
17071     {
17072       errmsg ("Value not set");
17073       return -99;
17074     }
17075
17076   /* Construct the API message */
17077   M (ONE_ENABLE_DISABLE, mp);
17078
17079   mp->is_en = is_en;
17080
17081   /* send it... */
17082   S (mp);
17083
17084   /* Wait for a reply... */
17085   W (ret);
17086   return ret;
17087 }
17088
17089 #define api_lisp_enable_disable api_one_enable_disable
17090
17091 static int
17092 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17093 {
17094   unformat_input_t *input = vam->input;
17095   vl_api_one_enable_disable_xtr_mode_t *mp;
17096   u8 is_set = 0;
17097   u8 is_en = 0;
17098   int ret;
17099
17100   /* Parse args required to build the message */
17101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17102     {
17103       if (unformat (input, "enable"))
17104         {
17105           is_set = 1;
17106           is_en = 1;
17107         }
17108       else if (unformat (input, "disable"))
17109         {
17110           is_set = 1;
17111         }
17112       else
17113         break;
17114     }
17115
17116   if (!is_set)
17117     {
17118       errmsg ("Value not set");
17119       return -99;
17120     }
17121
17122   /* Construct the API message */
17123   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17124
17125   mp->is_en = is_en;
17126
17127   /* send it... */
17128   S (mp);
17129
17130   /* Wait for a reply... */
17131   W (ret);
17132   return ret;
17133 }
17134
17135 static int
17136 api_one_show_xtr_mode (vat_main_t * vam)
17137 {
17138   vl_api_one_show_xtr_mode_t *mp;
17139   int ret;
17140
17141   /* Construct the API message */
17142   M (ONE_SHOW_XTR_MODE, mp);
17143
17144   /* send it... */
17145   S (mp);
17146
17147   /* Wait for a reply... */
17148   W (ret);
17149   return ret;
17150 }
17151
17152 static int
17153 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17154 {
17155   unformat_input_t *input = vam->input;
17156   vl_api_one_enable_disable_pitr_mode_t *mp;
17157   u8 is_set = 0;
17158   u8 is_en = 0;
17159   int ret;
17160
17161   /* Parse args required to build the message */
17162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17163     {
17164       if (unformat (input, "enable"))
17165         {
17166           is_set = 1;
17167           is_en = 1;
17168         }
17169       else if (unformat (input, "disable"))
17170         {
17171           is_set = 1;
17172         }
17173       else
17174         break;
17175     }
17176
17177   if (!is_set)
17178     {
17179       errmsg ("Value not set");
17180       return -99;
17181     }
17182
17183   /* Construct the API message */
17184   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17185
17186   mp->is_en = is_en;
17187
17188   /* send it... */
17189   S (mp);
17190
17191   /* Wait for a reply... */
17192   W (ret);
17193   return ret;
17194 }
17195
17196 static int
17197 api_one_show_pitr_mode (vat_main_t * vam)
17198 {
17199   vl_api_one_show_pitr_mode_t *mp;
17200   int ret;
17201
17202   /* Construct the API message */
17203   M (ONE_SHOW_PITR_MODE, mp);
17204
17205   /* send it... */
17206   S (mp);
17207
17208   /* Wait for a reply... */
17209   W (ret);
17210   return ret;
17211 }
17212
17213 static int
17214 api_one_enable_disable_petr_mode (vat_main_t * vam)
17215 {
17216   unformat_input_t *input = vam->input;
17217   vl_api_one_enable_disable_petr_mode_t *mp;
17218   u8 is_set = 0;
17219   u8 is_en = 0;
17220   int ret;
17221
17222   /* Parse args required to build the message */
17223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17224     {
17225       if (unformat (input, "enable"))
17226         {
17227           is_set = 1;
17228           is_en = 1;
17229         }
17230       else if (unformat (input, "disable"))
17231         {
17232           is_set = 1;
17233         }
17234       else
17235         break;
17236     }
17237
17238   if (!is_set)
17239     {
17240       errmsg ("Value not set");
17241       return -99;
17242     }
17243
17244   /* Construct the API message */
17245   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17246
17247   mp->is_en = is_en;
17248
17249   /* send it... */
17250   S (mp);
17251
17252   /* Wait for a reply... */
17253   W (ret);
17254   return ret;
17255 }
17256
17257 static int
17258 api_one_show_petr_mode (vat_main_t * vam)
17259 {
17260   vl_api_one_show_petr_mode_t *mp;
17261   int ret;
17262
17263   /* Construct the API message */
17264   M (ONE_SHOW_PETR_MODE, mp);
17265
17266   /* send it... */
17267   S (mp);
17268
17269   /* Wait for a reply... */
17270   W (ret);
17271   return ret;
17272 }
17273
17274 static int
17275 api_show_one_map_register_state (vat_main_t * vam)
17276 {
17277   vl_api_show_one_map_register_state_t *mp;
17278   int ret;
17279
17280   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17281
17282   /* send */
17283   S (mp);
17284
17285   /* wait for reply */
17286   W (ret);
17287   return ret;
17288 }
17289
17290 #define api_show_lisp_map_register_state api_show_one_map_register_state
17291
17292 static int
17293 api_show_one_rloc_probe_state (vat_main_t * vam)
17294 {
17295   vl_api_show_one_rloc_probe_state_t *mp;
17296   int ret;
17297
17298   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17299
17300   /* send */
17301   S (mp);
17302
17303   /* wait for reply */
17304   W (ret);
17305   return ret;
17306 }
17307
17308 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17309
17310 static int
17311 api_one_add_del_ndp_entry (vat_main_t * vam)
17312 {
17313   vl_api_one_add_del_ndp_entry_t *mp;
17314   unformat_input_t *input = vam->input;
17315   u8 is_add = 1;
17316   u8 mac_set = 0;
17317   u8 bd_set = 0;
17318   u8 ip_set = 0;
17319   u8 mac[6] = { 0, };
17320   u8 ip6[16] = { 0, };
17321   u32 bd = ~0;
17322   int ret;
17323
17324   /* Parse args required to build the message */
17325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17326     {
17327       if (unformat (input, "del"))
17328         is_add = 0;
17329       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17330         mac_set = 1;
17331       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17332         ip_set = 1;
17333       else if (unformat (input, "bd %d", &bd))
17334         bd_set = 1;
17335       else
17336         {
17337           errmsg ("parse error '%U'", format_unformat_error, input);
17338           return -99;
17339         }
17340     }
17341
17342   if (!bd_set || !ip_set || (!mac_set && is_add))
17343     {
17344       errmsg ("Missing BD, IP or MAC!");
17345       return -99;
17346     }
17347
17348   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17349   mp->is_add = is_add;
17350   clib_memcpy (mp->mac, mac, 6);
17351   mp->bd = clib_host_to_net_u32 (bd);
17352   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17353
17354   /* send */
17355   S (mp);
17356
17357   /* wait for reply */
17358   W (ret);
17359   return ret;
17360 }
17361
17362 static int
17363 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17364 {
17365   vl_api_one_add_del_l2_arp_entry_t *mp;
17366   unformat_input_t *input = vam->input;
17367   u8 is_add = 1;
17368   u8 mac_set = 0;
17369   u8 bd_set = 0;
17370   u8 ip_set = 0;
17371   u8 mac[6] = { 0, };
17372   u32 ip4 = 0, bd = ~0;
17373   int ret;
17374
17375   /* Parse args required to build the message */
17376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17377     {
17378       if (unformat (input, "del"))
17379         is_add = 0;
17380       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17381         mac_set = 1;
17382       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17383         ip_set = 1;
17384       else if (unformat (input, "bd %d", &bd))
17385         bd_set = 1;
17386       else
17387         {
17388           errmsg ("parse error '%U'", format_unformat_error, input);
17389           return -99;
17390         }
17391     }
17392
17393   if (!bd_set || !ip_set || (!mac_set && is_add))
17394     {
17395       errmsg ("Missing BD, IP or MAC!");
17396       return -99;
17397     }
17398
17399   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17400   mp->is_add = is_add;
17401   clib_memcpy (mp->mac, mac, 6);
17402   mp->bd = clib_host_to_net_u32 (bd);
17403   mp->ip4 = ip4;
17404
17405   /* send */
17406   S (mp);
17407
17408   /* wait for reply */
17409   W (ret);
17410   return ret;
17411 }
17412
17413 static int
17414 api_one_ndp_bd_get (vat_main_t * vam)
17415 {
17416   vl_api_one_ndp_bd_get_t *mp;
17417   int ret;
17418
17419   M (ONE_NDP_BD_GET, mp);
17420
17421   /* send */
17422   S (mp);
17423
17424   /* wait for reply */
17425   W (ret);
17426   return ret;
17427 }
17428
17429 static int
17430 api_one_ndp_entries_get (vat_main_t * vam)
17431 {
17432   vl_api_one_ndp_entries_get_t *mp;
17433   unformat_input_t *input = vam->input;
17434   u8 bd_set = 0;
17435   u32 bd = ~0;
17436   int ret;
17437
17438   /* Parse args required to build the message */
17439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17440     {
17441       if (unformat (input, "bd %d", &bd))
17442         bd_set = 1;
17443       else
17444         {
17445           errmsg ("parse error '%U'", format_unformat_error, input);
17446           return -99;
17447         }
17448     }
17449
17450   if (!bd_set)
17451     {
17452       errmsg ("Expected bridge domain!");
17453       return -99;
17454     }
17455
17456   M (ONE_NDP_ENTRIES_GET, mp);
17457   mp->bd = clib_host_to_net_u32 (bd);
17458
17459   /* send */
17460   S (mp);
17461
17462   /* wait for reply */
17463   W (ret);
17464   return ret;
17465 }
17466
17467 static int
17468 api_one_l2_arp_bd_get (vat_main_t * vam)
17469 {
17470   vl_api_one_l2_arp_bd_get_t *mp;
17471   int ret;
17472
17473   M (ONE_L2_ARP_BD_GET, mp);
17474
17475   /* send */
17476   S (mp);
17477
17478   /* wait for reply */
17479   W (ret);
17480   return ret;
17481 }
17482
17483 static int
17484 api_one_l2_arp_entries_get (vat_main_t * vam)
17485 {
17486   vl_api_one_l2_arp_entries_get_t *mp;
17487   unformat_input_t *input = vam->input;
17488   u8 bd_set = 0;
17489   u32 bd = ~0;
17490   int ret;
17491
17492   /* Parse args required to build the message */
17493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17494     {
17495       if (unformat (input, "bd %d", &bd))
17496         bd_set = 1;
17497       else
17498         {
17499           errmsg ("parse error '%U'", format_unformat_error, input);
17500           return -99;
17501         }
17502     }
17503
17504   if (!bd_set)
17505     {
17506       errmsg ("Expected bridge domain!");
17507       return -99;
17508     }
17509
17510   M (ONE_L2_ARP_ENTRIES_GET, mp);
17511   mp->bd = clib_host_to_net_u32 (bd);
17512
17513   /* send */
17514   S (mp);
17515
17516   /* wait for reply */
17517   W (ret);
17518   return ret;
17519 }
17520
17521 static int
17522 api_one_stats_enable_disable (vat_main_t * vam)
17523 {
17524   vl_api_one_stats_enable_disable_t *mp;
17525   unformat_input_t *input = vam->input;
17526   u8 is_set = 0;
17527   u8 is_en = 0;
17528   int ret;
17529
17530   /* Parse args required to build the message */
17531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17532     {
17533       if (unformat (input, "enable"))
17534         {
17535           is_set = 1;
17536           is_en = 1;
17537         }
17538       else if (unformat (input, "disable"))
17539         {
17540           is_set = 1;
17541         }
17542       else
17543         break;
17544     }
17545
17546   if (!is_set)
17547     {
17548       errmsg ("Value not set");
17549       return -99;
17550     }
17551
17552   M (ONE_STATS_ENABLE_DISABLE, mp);
17553   mp->is_en = is_en;
17554
17555   /* send */
17556   S (mp);
17557
17558   /* wait for reply */
17559   W (ret);
17560   return ret;
17561 }
17562
17563 static int
17564 api_show_one_stats_enable_disable (vat_main_t * vam)
17565 {
17566   vl_api_show_one_stats_enable_disable_t *mp;
17567   int ret;
17568
17569   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17570
17571   /* send */
17572   S (mp);
17573
17574   /* wait for reply */
17575   W (ret);
17576   return ret;
17577 }
17578
17579 static int
17580 api_show_one_map_request_mode (vat_main_t * vam)
17581 {
17582   vl_api_show_one_map_request_mode_t *mp;
17583   int ret;
17584
17585   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17586
17587   /* send */
17588   S (mp);
17589
17590   /* wait for reply */
17591   W (ret);
17592   return ret;
17593 }
17594
17595 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17596
17597 static int
17598 api_one_map_request_mode (vat_main_t * vam)
17599 {
17600   unformat_input_t *input = vam->input;
17601   vl_api_one_map_request_mode_t *mp;
17602   u8 mode = 0;
17603   int ret;
17604
17605   /* Parse args required to build the message */
17606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17607     {
17608       if (unformat (input, "dst-only"))
17609         mode = 0;
17610       else if (unformat (input, "src-dst"))
17611         mode = 1;
17612       else
17613         {
17614           errmsg ("parse error '%U'", format_unformat_error, input);
17615           return -99;
17616         }
17617     }
17618
17619   M (ONE_MAP_REQUEST_MODE, mp);
17620
17621   mp->mode = mode;
17622
17623   /* send */
17624   S (mp);
17625
17626   /* wait for reply */
17627   W (ret);
17628   return ret;
17629 }
17630
17631 #define api_lisp_map_request_mode api_one_map_request_mode
17632
17633 /**
17634  * Enable/disable ONE proxy ITR.
17635  *
17636  * @param vam vpp API test context
17637  * @return return code
17638  */
17639 static int
17640 api_one_pitr_set_locator_set (vat_main_t * vam)
17641 {
17642   u8 ls_name_set = 0;
17643   unformat_input_t *input = vam->input;
17644   vl_api_one_pitr_set_locator_set_t *mp;
17645   u8 is_add = 1;
17646   u8 *ls_name = 0;
17647   int ret;
17648
17649   /* Parse args required to build the message */
17650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17651     {
17652       if (unformat (input, "del"))
17653         is_add = 0;
17654       else if (unformat (input, "locator-set %s", &ls_name))
17655         ls_name_set = 1;
17656       else
17657         {
17658           errmsg ("parse error '%U'", format_unformat_error, input);
17659           return -99;
17660         }
17661     }
17662
17663   if (!ls_name_set)
17664     {
17665       errmsg ("locator-set name not set!");
17666       return -99;
17667     }
17668
17669   M (ONE_PITR_SET_LOCATOR_SET, mp);
17670
17671   mp->is_add = is_add;
17672   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17673   vec_free (ls_name);
17674
17675   /* send */
17676   S (mp);
17677
17678   /* wait for reply */
17679   W (ret);
17680   return ret;
17681 }
17682
17683 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17684
17685 static int
17686 api_one_nsh_set_locator_set (vat_main_t * vam)
17687 {
17688   u8 ls_name_set = 0;
17689   unformat_input_t *input = vam->input;
17690   vl_api_one_nsh_set_locator_set_t *mp;
17691   u8 is_add = 1;
17692   u8 *ls_name = 0;
17693   int ret;
17694
17695   /* Parse args required to build the message */
17696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17697     {
17698       if (unformat (input, "del"))
17699         is_add = 0;
17700       else if (unformat (input, "ls %s", &ls_name))
17701         ls_name_set = 1;
17702       else
17703         {
17704           errmsg ("parse error '%U'", format_unformat_error, input);
17705           return -99;
17706         }
17707     }
17708
17709   if (!ls_name_set && is_add)
17710     {
17711       errmsg ("locator-set name not set!");
17712       return -99;
17713     }
17714
17715   M (ONE_NSH_SET_LOCATOR_SET, mp);
17716
17717   mp->is_add = is_add;
17718   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17719   vec_free (ls_name);
17720
17721   /* send */
17722   S (mp);
17723
17724   /* wait for reply */
17725   W (ret);
17726   return ret;
17727 }
17728
17729 static int
17730 api_show_one_pitr (vat_main_t * vam)
17731 {
17732   vl_api_show_one_pitr_t *mp;
17733   int ret;
17734
17735   if (!vam->json_output)
17736     {
17737       print (vam->ofp, "%=20s", "lisp status:");
17738     }
17739
17740   M (SHOW_ONE_PITR, mp);
17741   /* send it... */
17742   S (mp);
17743
17744   /* Wait for a reply... */
17745   W (ret);
17746   return ret;
17747 }
17748
17749 #define api_show_lisp_pitr api_show_one_pitr
17750
17751 static int
17752 api_one_use_petr (vat_main_t * vam)
17753 {
17754   unformat_input_t *input = vam->input;
17755   vl_api_one_use_petr_t *mp;
17756   u8 is_add = 0;
17757   ip_address_t ip;
17758   int ret;
17759
17760   clib_memset (&ip, 0, sizeof (ip));
17761
17762   /* Parse args required to build the message */
17763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17764     {
17765       if (unformat (input, "disable"))
17766         is_add = 0;
17767       else
17768         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17769         {
17770           is_add = 1;
17771           ip_addr_version (&ip) = IP4;
17772         }
17773       else
17774         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17775         {
17776           is_add = 1;
17777           ip_addr_version (&ip) = IP6;
17778         }
17779       else
17780         {
17781           errmsg ("parse error '%U'", format_unformat_error, input);
17782           return -99;
17783         }
17784     }
17785
17786   M (ONE_USE_PETR, mp);
17787
17788   mp->is_add = is_add;
17789   if (is_add)
17790     {
17791       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17792       if (mp->is_ip4)
17793         clib_memcpy (mp->address, &ip, 4);
17794       else
17795         clib_memcpy (mp->address, &ip, 16);
17796     }
17797
17798   /* send */
17799   S (mp);
17800
17801   /* wait for reply */
17802   W (ret);
17803   return ret;
17804 }
17805
17806 #define api_lisp_use_petr api_one_use_petr
17807
17808 static int
17809 api_show_one_nsh_mapping (vat_main_t * vam)
17810 {
17811   vl_api_show_one_use_petr_t *mp;
17812   int ret;
17813
17814   if (!vam->json_output)
17815     {
17816       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17817     }
17818
17819   M (SHOW_ONE_NSH_MAPPING, mp);
17820   /* send it... */
17821   S (mp);
17822
17823   /* Wait for a reply... */
17824   W (ret);
17825   return ret;
17826 }
17827
17828 static int
17829 api_show_one_use_petr (vat_main_t * vam)
17830 {
17831   vl_api_show_one_use_petr_t *mp;
17832   int ret;
17833
17834   if (!vam->json_output)
17835     {
17836       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17837     }
17838
17839   M (SHOW_ONE_USE_PETR, mp);
17840   /* send it... */
17841   S (mp);
17842
17843   /* Wait for a reply... */
17844   W (ret);
17845   return ret;
17846 }
17847
17848 #define api_show_lisp_use_petr api_show_one_use_petr
17849
17850 /**
17851  * Add/delete mapping between vni and vrf
17852  */
17853 static int
17854 api_one_eid_table_add_del_map (vat_main_t * vam)
17855 {
17856   unformat_input_t *input = vam->input;
17857   vl_api_one_eid_table_add_del_map_t *mp;
17858   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17859   u32 vni, vrf, bd_index;
17860   int ret;
17861
17862   /* Parse args required to build the message */
17863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17864     {
17865       if (unformat (input, "del"))
17866         is_add = 0;
17867       else if (unformat (input, "vrf %d", &vrf))
17868         vrf_set = 1;
17869       else if (unformat (input, "bd_index %d", &bd_index))
17870         bd_index_set = 1;
17871       else if (unformat (input, "vni %d", &vni))
17872         vni_set = 1;
17873       else
17874         break;
17875     }
17876
17877   if (!vni_set || (!vrf_set && !bd_index_set))
17878     {
17879       errmsg ("missing arguments!");
17880       return -99;
17881     }
17882
17883   if (vrf_set && bd_index_set)
17884     {
17885       errmsg ("error: both vrf and bd entered!");
17886       return -99;
17887     }
17888
17889   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17890
17891   mp->is_add = is_add;
17892   mp->vni = htonl (vni);
17893   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17894   mp->is_l2 = bd_index_set;
17895
17896   /* send */
17897   S (mp);
17898
17899   /* wait for reply */
17900   W (ret);
17901   return ret;
17902 }
17903
17904 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17905
17906 uword
17907 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17908 {
17909   u32 *action = va_arg (*args, u32 *);
17910   u8 *s = 0;
17911
17912   if (unformat (input, "%s", &s))
17913     {
17914       if (!strcmp ((char *) s, "no-action"))
17915         action[0] = 0;
17916       else if (!strcmp ((char *) s, "natively-forward"))
17917         action[0] = 1;
17918       else if (!strcmp ((char *) s, "send-map-request"))
17919         action[0] = 2;
17920       else if (!strcmp ((char *) s, "drop"))
17921         action[0] = 3;
17922       else
17923         {
17924           clib_warning ("invalid action: '%s'", s);
17925           action[0] = 3;
17926         }
17927     }
17928   else
17929     return 0;
17930
17931   vec_free (s);
17932   return 1;
17933 }
17934
17935 /**
17936  * Add/del remote mapping to/from ONE control plane
17937  *
17938  * @param vam vpp API test context
17939  * @return return code
17940  */
17941 static int
17942 api_one_add_del_remote_mapping (vat_main_t * vam)
17943 {
17944   unformat_input_t *input = vam->input;
17945   vl_api_one_add_del_remote_mapping_t *mp;
17946   u32 vni = 0;
17947   lisp_eid_vat_t _eid, *eid = &_eid;
17948   lisp_eid_vat_t _seid, *seid = &_seid;
17949   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17950   u32 action = ~0, p, w, data_len;
17951   ip4_address_t rloc4;
17952   ip6_address_t rloc6;
17953   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17954   int ret;
17955
17956   clib_memset (&rloc, 0, sizeof (rloc));
17957
17958   /* Parse args required to build the message */
17959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17960     {
17961       if (unformat (input, "del-all"))
17962         {
17963           del_all = 1;
17964         }
17965       else if (unformat (input, "del"))
17966         {
17967           is_add = 0;
17968         }
17969       else if (unformat (input, "add"))
17970         {
17971           is_add = 1;
17972         }
17973       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17974         {
17975           eid_set = 1;
17976         }
17977       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17978         {
17979           seid_set = 1;
17980         }
17981       else if (unformat (input, "vni %d", &vni))
17982         {
17983           ;
17984         }
17985       else if (unformat (input, "p %d w %d", &p, &w))
17986         {
17987           if (!curr_rloc)
17988             {
17989               errmsg ("No RLOC configured for setting priority/weight!");
17990               return -99;
17991             }
17992           curr_rloc->priority = p;
17993           curr_rloc->weight = w;
17994         }
17995       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17996         {
17997           rloc.is_ip4 = 1;
17998           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17999           vec_add1 (rlocs, rloc);
18000           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18001         }
18002       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18003         {
18004           rloc.is_ip4 = 0;
18005           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18006           vec_add1 (rlocs, rloc);
18007           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18008         }
18009       else if (unformat (input, "action %U",
18010                          unformat_negative_mapping_action, &action))
18011         {
18012           ;
18013         }
18014       else
18015         {
18016           clib_warning ("parse error '%U'", format_unformat_error, input);
18017           return -99;
18018         }
18019     }
18020
18021   if (0 == eid_set)
18022     {
18023       errmsg ("missing params!");
18024       return -99;
18025     }
18026
18027   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18028     {
18029       errmsg ("no action set for negative map-reply!");
18030       return -99;
18031     }
18032
18033   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18034
18035   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18036   mp->is_add = is_add;
18037   mp->vni = htonl (vni);
18038   mp->action = (u8) action;
18039   mp->is_src_dst = seid_set;
18040   mp->eid_len = eid->len;
18041   mp->seid_len = seid->len;
18042   mp->del_all = del_all;
18043   mp->eid_type = eid->type;
18044   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18045   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18046
18047   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18048   clib_memcpy (mp->rlocs, rlocs, data_len);
18049   vec_free (rlocs);
18050
18051   /* send it... */
18052   S (mp);
18053
18054   /* Wait for a reply... */
18055   W (ret);
18056   return ret;
18057 }
18058
18059 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18060
18061 /**
18062  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18063  * forwarding entries in data-plane accordingly.
18064  *
18065  * @param vam vpp API test context
18066  * @return return code
18067  */
18068 static int
18069 api_one_add_del_adjacency (vat_main_t * vam)
18070 {
18071   unformat_input_t *input = vam->input;
18072   vl_api_one_add_del_adjacency_t *mp;
18073   u32 vni = 0;
18074   ip4_address_t leid4, reid4;
18075   ip6_address_t leid6, reid6;
18076   u8 reid_mac[6] = { 0 };
18077   u8 leid_mac[6] = { 0 };
18078   u8 reid_type, leid_type;
18079   u32 leid_len = 0, reid_len = 0, len;
18080   u8 is_add = 1;
18081   int ret;
18082
18083   leid_type = reid_type = (u8) ~ 0;
18084
18085   /* Parse args required to build the message */
18086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18087     {
18088       if (unformat (input, "del"))
18089         {
18090           is_add = 0;
18091         }
18092       else if (unformat (input, "add"))
18093         {
18094           is_add = 1;
18095         }
18096       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18097                          &reid4, &len))
18098         {
18099           reid_type = 0;        /* ipv4 */
18100           reid_len = len;
18101         }
18102       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18103                          &reid6, &len))
18104         {
18105           reid_type = 1;        /* ipv6 */
18106           reid_len = len;
18107         }
18108       else if (unformat (input, "reid %U", unformat_ethernet_address,
18109                          reid_mac))
18110         {
18111           reid_type = 2;        /* mac */
18112         }
18113       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18114                          &leid4, &len))
18115         {
18116           leid_type = 0;        /* ipv4 */
18117           leid_len = len;
18118         }
18119       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18120                          &leid6, &len))
18121         {
18122           leid_type = 1;        /* ipv6 */
18123           leid_len = len;
18124         }
18125       else if (unformat (input, "leid %U", unformat_ethernet_address,
18126                          leid_mac))
18127         {
18128           leid_type = 2;        /* mac */
18129         }
18130       else if (unformat (input, "vni %d", &vni))
18131         {
18132           ;
18133         }
18134       else
18135         {
18136           errmsg ("parse error '%U'", format_unformat_error, input);
18137           return -99;
18138         }
18139     }
18140
18141   if ((u8) ~ 0 == reid_type)
18142     {
18143       errmsg ("missing params!");
18144       return -99;
18145     }
18146
18147   if (leid_type != reid_type)
18148     {
18149       errmsg ("remote and local EIDs are of different types!");
18150       return -99;
18151     }
18152
18153   M (ONE_ADD_DEL_ADJACENCY, mp);
18154   mp->is_add = is_add;
18155   mp->vni = htonl (vni);
18156   mp->leid_len = leid_len;
18157   mp->reid_len = reid_len;
18158   mp->eid_type = reid_type;
18159
18160   switch (mp->eid_type)
18161     {
18162     case 0:
18163       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18164       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18165       break;
18166     case 1:
18167       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18168       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18169       break;
18170     case 2:
18171       clib_memcpy (mp->leid, leid_mac, 6);
18172       clib_memcpy (mp->reid, reid_mac, 6);
18173       break;
18174     default:
18175       errmsg ("unknown EID type %d!", mp->eid_type);
18176       return 0;
18177     }
18178
18179   /* send it... */
18180   S (mp);
18181
18182   /* Wait for a reply... */
18183   W (ret);
18184   return ret;
18185 }
18186
18187 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18188
18189 uword
18190 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18191 {
18192   u32 *mode = va_arg (*args, u32 *);
18193
18194   if (unformat (input, "lisp"))
18195     *mode = 0;
18196   else if (unformat (input, "vxlan"))
18197     *mode = 1;
18198   else
18199     return 0;
18200
18201   return 1;
18202 }
18203
18204 static int
18205 api_gpe_get_encap_mode (vat_main_t * vam)
18206 {
18207   vl_api_gpe_get_encap_mode_t *mp;
18208   int ret;
18209
18210   /* Construct the API message */
18211   M (GPE_GET_ENCAP_MODE, mp);
18212
18213   /* send it... */
18214   S (mp);
18215
18216   /* Wait for a reply... */
18217   W (ret);
18218   return ret;
18219 }
18220
18221 static int
18222 api_gpe_set_encap_mode (vat_main_t * vam)
18223 {
18224   unformat_input_t *input = vam->input;
18225   vl_api_gpe_set_encap_mode_t *mp;
18226   int ret;
18227   u32 mode = 0;
18228
18229   /* Parse args required to build the message */
18230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18231     {
18232       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18233         ;
18234       else
18235         break;
18236     }
18237
18238   /* Construct the API message */
18239   M (GPE_SET_ENCAP_MODE, mp);
18240
18241   mp->mode = mode;
18242
18243   /* send it... */
18244   S (mp);
18245
18246   /* Wait for a reply... */
18247   W (ret);
18248   return ret;
18249 }
18250
18251 static int
18252 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18253 {
18254   unformat_input_t *input = vam->input;
18255   vl_api_gpe_add_del_iface_t *mp;
18256   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18257   u32 dp_table = 0, vni = 0;
18258   int ret;
18259
18260   /* Parse args required to build the message */
18261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18262     {
18263       if (unformat (input, "up"))
18264         {
18265           action_set = 1;
18266           is_add = 1;
18267         }
18268       else if (unformat (input, "down"))
18269         {
18270           action_set = 1;
18271           is_add = 0;
18272         }
18273       else if (unformat (input, "table_id %d", &dp_table))
18274         {
18275           dp_table_set = 1;
18276         }
18277       else if (unformat (input, "bd_id %d", &dp_table))
18278         {
18279           dp_table_set = 1;
18280           is_l2 = 1;
18281         }
18282       else if (unformat (input, "vni %d", &vni))
18283         {
18284           vni_set = 1;
18285         }
18286       else
18287         break;
18288     }
18289
18290   if (action_set == 0)
18291     {
18292       errmsg ("Action not set");
18293       return -99;
18294     }
18295   if (dp_table_set == 0 || vni_set == 0)
18296     {
18297       errmsg ("vni and dp_table must be set");
18298       return -99;
18299     }
18300
18301   /* Construct the API message */
18302   M (GPE_ADD_DEL_IFACE, mp);
18303
18304   mp->is_add = is_add;
18305   mp->dp_table = clib_host_to_net_u32 (dp_table);
18306   mp->is_l2 = is_l2;
18307   mp->vni = clib_host_to_net_u32 (vni);
18308
18309   /* send it... */
18310   S (mp);
18311
18312   /* Wait for a reply... */
18313   W (ret);
18314   return ret;
18315 }
18316
18317 static int
18318 api_one_map_register_fallback_threshold (vat_main_t * vam)
18319 {
18320   unformat_input_t *input = vam->input;
18321   vl_api_one_map_register_fallback_threshold_t *mp;
18322   u32 value = 0;
18323   u8 is_set = 0;
18324   int ret;
18325
18326   /* Parse args required to build the message */
18327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18328     {
18329       if (unformat (input, "%u", &value))
18330         is_set = 1;
18331       else
18332         {
18333           clib_warning ("parse error '%U'", format_unformat_error, input);
18334           return -99;
18335         }
18336     }
18337
18338   if (!is_set)
18339     {
18340       errmsg ("fallback threshold value is missing!");
18341       return -99;
18342     }
18343
18344   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18345   mp->value = clib_host_to_net_u32 (value);
18346
18347   /* send it... */
18348   S (mp);
18349
18350   /* Wait for a reply... */
18351   W (ret);
18352   return ret;
18353 }
18354
18355 static int
18356 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18357 {
18358   vl_api_show_one_map_register_fallback_threshold_t *mp;
18359   int ret;
18360
18361   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18362
18363   /* send it... */
18364   S (mp);
18365
18366   /* Wait for a reply... */
18367   W (ret);
18368   return ret;
18369 }
18370
18371 uword
18372 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18373 {
18374   u32 *proto = va_arg (*args, u32 *);
18375
18376   if (unformat (input, "udp"))
18377     *proto = 1;
18378   else if (unformat (input, "api"))
18379     *proto = 2;
18380   else
18381     return 0;
18382
18383   return 1;
18384 }
18385
18386 static int
18387 api_one_set_transport_protocol (vat_main_t * vam)
18388 {
18389   unformat_input_t *input = vam->input;
18390   vl_api_one_set_transport_protocol_t *mp;
18391   u8 is_set = 0;
18392   u32 protocol = 0;
18393   int ret;
18394
18395   /* Parse args required to build the message */
18396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18397     {
18398       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18399         is_set = 1;
18400       else
18401         {
18402           clib_warning ("parse error '%U'", format_unformat_error, input);
18403           return -99;
18404         }
18405     }
18406
18407   if (!is_set)
18408     {
18409       errmsg ("Transport protocol missing!");
18410       return -99;
18411     }
18412
18413   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18414   mp->protocol = (u8) protocol;
18415
18416   /* send it... */
18417   S (mp);
18418
18419   /* Wait for a reply... */
18420   W (ret);
18421   return ret;
18422 }
18423
18424 static int
18425 api_one_get_transport_protocol (vat_main_t * vam)
18426 {
18427   vl_api_one_get_transport_protocol_t *mp;
18428   int ret;
18429
18430   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18431
18432   /* send it... */
18433   S (mp);
18434
18435   /* Wait for a reply... */
18436   W (ret);
18437   return ret;
18438 }
18439
18440 static int
18441 api_one_map_register_set_ttl (vat_main_t * vam)
18442 {
18443   unformat_input_t *input = vam->input;
18444   vl_api_one_map_register_set_ttl_t *mp;
18445   u32 ttl = 0;
18446   u8 is_set = 0;
18447   int ret;
18448
18449   /* Parse args required to build the message */
18450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18451     {
18452       if (unformat (input, "%u", &ttl))
18453         is_set = 1;
18454       else
18455         {
18456           clib_warning ("parse error '%U'", format_unformat_error, input);
18457           return -99;
18458         }
18459     }
18460
18461   if (!is_set)
18462     {
18463       errmsg ("TTL value missing!");
18464       return -99;
18465     }
18466
18467   M (ONE_MAP_REGISTER_SET_TTL, mp);
18468   mp->ttl = clib_host_to_net_u32 (ttl);
18469
18470   /* send it... */
18471   S (mp);
18472
18473   /* Wait for a reply... */
18474   W (ret);
18475   return ret;
18476 }
18477
18478 static int
18479 api_show_one_map_register_ttl (vat_main_t * vam)
18480 {
18481   vl_api_show_one_map_register_ttl_t *mp;
18482   int ret;
18483
18484   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18485
18486   /* send it... */
18487   S (mp);
18488
18489   /* Wait for a reply... */
18490   W (ret);
18491   return ret;
18492 }
18493
18494 /**
18495  * Add/del map request itr rlocs from ONE control plane and updates
18496  *
18497  * @param vam vpp API test context
18498  * @return return code
18499  */
18500 static int
18501 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18502 {
18503   unformat_input_t *input = vam->input;
18504   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18505   u8 *locator_set_name = 0;
18506   u8 locator_set_name_set = 0;
18507   u8 is_add = 1;
18508   int ret;
18509
18510   /* Parse args required to build the message */
18511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18512     {
18513       if (unformat (input, "del"))
18514         {
18515           is_add = 0;
18516         }
18517       else if (unformat (input, "%_%v%_", &locator_set_name))
18518         {
18519           locator_set_name_set = 1;
18520         }
18521       else
18522         {
18523           clib_warning ("parse error '%U'", format_unformat_error, input);
18524           return -99;
18525         }
18526     }
18527
18528   if (is_add && !locator_set_name_set)
18529     {
18530       errmsg ("itr-rloc is not set!");
18531       return -99;
18532     }
18533
18534   if (is_add && vec_len (locator_set_name) > 64)
18535     {
18536       errmsg ("itr-rloc locator-set name too long");
18537       vec_free (locator_set_name);
18538       return -99;
18539     }
18540
18541   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18542   mp->is_add = is_add;
18543   if (is_add)
18544     {
18545       clib_memcpy (mp->locator_set_name, locator_set_name,
18546                    vec_len (locator_set_name));
18547     }
18548   else
18549     {
18550       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18551     }
18552   vec_free (locator_set_name);
18553
18554   /* send it... */
18555   S (mp);
18556
18557   /* Wait for a reply... */
18558   W (ret);
18559   return ret;
18560 }
18561
18562 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18563
18564 static int
18565 api_one_locator_dump (vat_main_t * vam)
18566 {
18567   unformat_input_t *input = vam->input;
18568   vl_api_one_locator_dump_t *mp;
18569   vl_api_control_ping_t *mp_ping;
18570   u8 is_index_set = 0, is_name_set = 0;
18571   u8 *ls_name = 0;
18572   u32 ls_index = ~0;
18573   int ret;
18574
18575   /* Parse args required to build the message */
18576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18577     {
18578       if (unformat (input, "ls_name %_%v%_", &ls_name))
18579         {
18580           is_name_set = 1;
18581         }
18582       else if (unformat (input, "ls_index %d", &ls_index))
18583         {
18584           is_index_set = 1;
18585         }
18586       else
18587         {
18588           errmsg ("parse error '%U'", format_unformat_error, input);
18589           return -99;
18590         }
18591     }
18592
18593   if (!is_index_set && !is_name_set)
18594     {
18595       errmsg ("error: expected one of index or name!");
18596       return -99;
18597     }
18598
18599   if (is_index_set && is_name_set)
18600     {
18601       errmsg ("error: only one param expected!");
18602       return -99;
18603     }
18604
18605   if (vec_len (ls_name) > 62)
18606     {
18607       errmsg ("error: locator set name too long!");
18608       return -99;
18609     }
18610
18611   if (!vam->json_output)
18612     {
18613       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18614     }
18615
18616   M (ONE_LOCATOR_DUMP, mp);
18617   mp->is_index_set = is_index_set;
18618
18619   if (is_index_set)
18620     mp->ls_index = clib_host_to_net_u32 (ls_index);
18621   else
18622     {
18623       vec_add1 (ls_name, 0);
18624       strncpy ((char *) mp->ls_name, (char *) ls_name,
18625                sizeof (mp->ls_name) - 1);
18626     }
18627
18628   /* send it... */
18629   S (mp);
18630
18631   /* Use a control ping for synchronization */
18632   MPING (CONTROL_PING, mp_ping);
18633   S (mp_ping);
18634
18635   /* Wait for a reply... */
18636   W (ret);
18637   return ret;
18638 }
18639
18640 #define api_lisp_locator_dump api_one_locator_dump
18641
18642 static int
18643 api_one_locator_set_dump (vat_main_t * vam)
18644 {
18645   vl_api_one_locator_set_dump_t *mp;
18646   vl_api_control_ping_t *mp_ping;
18647   unformat_input_t *input = vam->input;
18648   u8 filter = 0;
18649   int ret;
18650
18651   /* Parse args required to build the message */
18652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18653     {
18654       if (unformat (input, "local"))
18655         {
18656           filter = 1;
18657         }
18658       else if (unformat (input, "remote"))
18659         {
18660           filter = 2;
18661         }
18662       else
18663         {
18664           errmsg ("parse error '%U'", format_unformat_error, input);
18665           return -99;
18666         }
18667     }
18668
18669   if (!vam->json_output)
18670     {
18671       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18672     }
18673
18674   M (ONE_LOCATOR_SET_DUMP, mp);
18675
18676   mp->filter = filter;
18677
18678   /* send it... */
18679   S (mp);
18680
18681   /* Use a control ping for synchronization */
18682   MPING (CONTROL_PING, mp_ping);
18683   S (mp_ping);
18684
18685   /* Wait for a reply... */
18686   W (ret);
18687   return ret;
18688 }
18689
18690 #define api_lisp_locator_set_dump api_one_locator_set_dump
18691
18692 static int
18693 api_one_eid_table_map_dump (vat_main_t * vam)
18694 {
18695   u8 is_l2 = 0;
18696   u8 mode_set = 0;
18697   unformat_input_t *input = vam->input;
18698   vl_api_one_eid_table_map_dump_t *mp;
18699   vl_api_control_ping_t *mp_ping;
18700   int ret;
18701
18702   /* Parse args required to build the message */
18703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18704     {
18705       if (unformat (input, "l2"))
18706         {
18707           is_l2 = 1;
18708           mode_set = 1;
18709         }
18710       else if (unformat (input, "l3"))
18711         {
18712           is_l2 = 0;
18713           mode_set = 1;
18714         }
18715       else
18716         {
18717           errmsg ("parse error '%U'", format_unformat_error, input);
18718           return -99;
18719         }
18720     }
18721
18722   if (!mode_set)
18723     {
18724       errmsg ("expected one of 'l2' or 'l3' parameter!");
18725       return -99;
18726     }
18727
18728   if (!vam->json_output)
18729     {
18730       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18731     }
18732
18733   M (ONE_EID_TABLE_MAP_DUMP, mp);
18734   mp->is_l2 = is_l2;
18735
18736   /* send it... */
18737   S (mp);
18738
18739   /* Use a control ping for synchronization */
18740   MPING (CONTROL_PING, mp_ping);
18741   S (mp_ping);
18742
18743   /* Wait for a reply... */
18744   W (ret);
18745   return ret;
18746 }
18747
18748 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18749
18750 static int
18751 api_one_eid_table_vni_dump (vat_main_t * vam)
18752 {
18753   vl_api_one_eid_table_vni_dump_t *mp;
18754   vl_api_control_ping_t *mp_ping;
18755   int ret;
18756
18757   if (!vam->json_output)
18758     {
18759       print (vam->ofp, "VNI");
18760     }
18761
18762   M (ONE_EID_TABLE_VNI_DUMP, mp);
18763
18764   /* send it... */
18765   S (mp);
18766
18767   /* Use a control ping for synchronization */
18768   MPING (CONTROL_PING, mp_ping);
18769   S (mp_ping);
18770
18771   /* Wait for a reply... */
18772   W (ret);
18773   return ret;
18774 }
18775
18776 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18777
18778 static int
18779 api_one_eid_table_dump (vat_main_t * vam)
18780 {
18781   unformat_input_t *i = vam->input;
18782   vl_api_one_eid_table_dump_t *mp;
18783   vl_api_control_ping_t *mp_ping;
18784   struct in_addr ip4;
18785   struct in6_addr ip6;
18786   u8 mac[6];
18787   u8 eid_type = ~0, eid_set = 0;
18788   u32 prefix_length = ~0, t, vni = 0;
18789   u8 filter = 0;
18790   int ret;
18791   lisp_nsh_api_t nsh;
18792
18793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18794     {
18795       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18796         {
18797           eid_set = 1;
18798           eid_type = 0;
18799           prefix_length = t;
18800         }
18801       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18802         {
18803           eid_set = 1;
18804           eid_type = 1;
18805           prefix_length = t;
18806         }
18807       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18808         {
18809           eid_set = 1;
18810           eid_type = 2;
18811         }
18812       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18813         {
18814           eid_set = 1;
18815           eid_type = 3;
18816         }
18817       else if (unformat (i, "vni %d", &t))
18818         {
18819           vni = t;
18820         }
18821       else if (unformat (i, "local"))
18822         {
18823           filter = 1;
18824         }
18825       else if (unformat (i, "remote"))
18826         {
18827           filter = 2;
18828         }
18829       else
18830         {
18831           errmsg ("parse error '%U'", format_unformat_error, i);
18832           return -99;
18833         }
18834     }
18835
18836   if (!vam->json_output)
18837     {
18838       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18839              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18840     }
18841
18842   M (ONE_EID_TABLE_DUMP, mp);
18843
18844   mp->filter = filter;
18845   if (eid_set)
18846     {
18847       mp->eid_set = 1;
18848       mp->vni = htonl (vni);
18849       mp->eid_type = eid_type;
18850       switch (eid_type)
18851         {
18852         case 0:
18853           mp->prefix_length = prefix_length;
18854           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18855           break;
18856         case 1:
18857           mp->prefix_length = prefix_length;
18858           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18859           break;
18860         case 2:
18861           clib_memcpy (mp->eid, mac, sizeof (mac));
18862           break;
18863         case 3:
18864           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18865           break;
18866         default:
18867           errmsg ("unknown EID type %d!", eid_type);
18868           return -99;
18869         }
18870     }
18871
18872   /* send it... */
18873   S (mp);
18874
18875   /* Use a control ping for synchronization */
18876   MPING (CONTROL_PING, mp_ping);
18877   S (mp_ping);
18878
18879   /* Wait for a reply... */
18880   W (ret);
18881   return ret;
18882 }
18883
18884 #define api_lisp_eid_table_dump api_one_eid_table_dump
18885
18886 static int
18887 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18888 {
18889   unformat_input_t *i = vam->input;
18890   vl_api_gpe_fwd_entries_get_t *mp;
18891   u8 vni_set = 0;
18892   u32 vni = ~0;
18893   int ret;
18894
18895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18896     {
18897       if (unformat (i, "vni %d", &vni))
18898         {
18899           vni_set = 1;
18900         }
18901       else
18902         {
18903           errmsg ("parse error '%U'", format_unformat_error, i);
18904           return -99;
18905         }
18906     }
18907
18908   if (!vni_set)
18909     {
18910       errmsg ("vni not set!");
18911       return -99;
18912     }
18913
18914   if (!vam->json_output)
18915     {
18916       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18917              "leid", "reid");
18918     }
18919
18920   M (GPE_FWD_ENTRIES_GET, mp);
18921   mp->vni = clib_host_to_net_u32 (vni);
18922
18923   /* send it... */
18924   S (mp);
18925
18926   /* Wait for a reply... */
18927   W (ret);
18928   return ret;
18929 }
18930
18931 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18932 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18933 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18934 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18935 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18936 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18937 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18938 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18939
18940 static int
18941 api_one_adjacencies_get (vat_main_t * vam)
18942 {
18943   unformat_input_t *i = vam->input;
18944   vl_api_one_adjacencies_get_t *mp;
18945   u8 vni_set = 0;
18946   u32 vni = ~0;
18947   int ret;
18948
18949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18950     {
18951       if (unformat (i, "vni %d", &vni))
18952         {
18953           vni_set = 1;
18954         }
18955       else
18956         {
18957           errmsg ("parse error '%U'", format_unformat_error, i);
18958           return -99;
18959         }
18960     }
18961
18962   if (!vni_set)
18963     {
18964       errmsg ("vni not set!");
18965       return -99;
18966     }
18967
18968   if (!vam->json_output)
18969     {
18970       print (vam->ofp, "%s %40s", "leid", "reid");
18971     }
18972
18973   M (ONE_ADJACENCIES_GET, mp);
18974   mp->vni = clib_host_to_net_u32 (vni);
18975
18976   /* send it... */
18977   S (mp);
18978
18979   /* Wait for a reply... */
18980   W (ret);
18981   return ret;
18982 }
18983
18984 #define api_lisp_adjacencies_get api_one_adjacencies_get
18985
18986 static int
18987 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18988 {
18989   unformat_input_t *i = vam->input;
18990   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18991   int ret;
18992   u8 ip_family_set = 0, is_ip4 = 1;
18993
18994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18995     {
18996       if (unformat (i, "ip4"))
18997         {
18998           ip_family_set = 1;
18999           is_ip4 = 1;
19000         }
19001       else if (unformat (i, "ip6"))
19002         {
19003           ip_family_set = 1;
19004           is_ip4 = 0;
19005         }
19006       else
19007         {
19008           errmsg ("parse error '%U'", format_unformat_error, i);
19009           return -99;
19010         }
19011     }
19012
19013   if (!ip_family_set)
19014     {
19015       errmsg ("ip family not set!");
19016       return -99;
19017     }
19018
19019   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19020   mp->is_ip4 = is_ip4;
19021
19022   /* send it... */
19023   S (mp);
19024
19025   /* Wait for a reply... */
19026   W (ret);
19027   return ret;
19028 }
19029
19030 static int
19031 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19032 {
19033   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19034   int ret;
19035
19036   if (!vam->json_output)
19037     {
19038       print (vam->ofp, "VNIs");
19039     }
19040
19041   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19042
19043   /* send it... */
19044   S (mp);
19045
19046   /* Wait for a reply... */
19047   W (ret);
19048   return ret;
19049 }
19050
19051 static int
19052 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19053 {
19054   unformat_input_t *i = vam->input;
19055   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19056   int ret = 0;
19057   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19058   struct in_addr ip4;
19059   struct in6_addr ip6;
19060   u32 table_id = 0, nh_sw_if_index = ~0;
19061
19062   clib_memset (&ip4, 0, sizeof (ip4));
19063   clib_memset (&ip6, 0, sizeof (ip6));
19064
19065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19066     {
19067       if (unformat (i, "del"))
19068         is_add = 0;
19069       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19070                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19071         {
19072           ip_set = 1;
19073           is_ip4 = 1;
19074         }
19075       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19076                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19077         {
19078           ip_set = 1;
19079           is_ip4 = 0;
19080         }
19081       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19082         {
19083           ip_set = 1;
19084           is_ip4 = 1;
19085           nh_sw_if_index = ~0;
19086         }
19087       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19088         {
19089           ip_set = 1;
19090           is_ip4 = 0;
19091           nh_sw_if_index = ~0;
19092         }
19093       else if (unformat (i, "table %d", &table_id))
19094         ;
19095       else
19096         {
19097           errmsg ("parse error '%U'", format_unformat_error, i);
19098           return -99;
19099         }
19100     }
19101
19102   if (!ip_set)
19103     {
19104       errmsg ("nh addr not set!");
19105       return -99;
19106     }
19107
19108   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19109   mp->is_add = is_add;
19110   mp->table_id = clib_host_to_net_u32 (table_id);
19111   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19112   mp->is_ip4 = is_ip4;
19113   if (is_ip4)
19114     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19115   else
19116     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19117
19118   /* send it... */
19119   S (mp);
19120
19121   /* Wait for a reply... */
19122   W (ret);
19123   return ret;
19124 }
19125
19126 static int
19127 api_one_map_server_dump (vat_main_t * vam)
19128 {
19129   vl_api_one_map_server_dump_t *mp;
19130   vl_api_control_ping_t *mp_ping;
19131   int ret;
19132
19133   if (!vam->json_output)
19134     {
19135       print (vam->ofp, "%=20s", "Map server");
19136     }
19137
19138   M (ONE_MAP_SERVER_DUMP, mp);
19139   /* send it... */
19140   S (mp);
19141
19142   /* Use a control ping for synchronization */
19143   MPING (CONTROL_PING, mp_ping);
19144   S (mp_ping);
19145
19146   /* Wait for a reply... */
19147   W (ret);
19148   return ret;
19149 }
19150
19151 #define api_lisp_map_server_dump api_one_map_server_dump
19152
19153 static int
19154 api_one_map_resolver_dump (vat_main_t * vam)
19155 {
19156   vl_api_one_map_resolver_dump_t *mp;
19157   vl_api_control_ping_t *mp_ping;
19158   int ret;
19159
19160   if (!vam->json_output)
19161     {
19162       print (vam->ofp, "%=20s", "Map resolver");
19163     }
19164
19165   M (ONE_MAP_RESOLVER_DUMP, mp);
19166   /* send it... */
19167   S (mp);
19168
19169   /* Use a control ping for synchronization */
19170   MPING (CONTROL_PING, mp_ping);
19171   S (mp_ping);
19172
19173   /* Wait for a reply... */
19174   W (ret);
19175   return ret;
19176 }
19177
19178 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19179
19180 static int
19181 api_one_stats_flush (vat_main_t * vam)
19182 {
19183   vl_api_one_stats_flush_t *mp;
19184   int ret = 0;
19185
19186   M (ONE_STATS_FLUSH, mp);
19187   S (mp);
19188   W (ret);
19189   return ret;
19190 }
19191
19192 static int
19193 api_one_stats_dump (vat_main_t * vam)
19194 {
19195   vl_api_one_stats_dump_t *mp;
19196   vl_api_control_ping_t *mp_ping;
19197   int ret;
19198
19199   M (ONE_STATS_DUMP, mp);
19200   /* send it... */
19201   S (mp);
19202
19203   /* Use a control ping for synchronization */
19204   MPING (CONTROL_PING, mp_ping);
19205   S (mp_ping);
19206
19207   /* Wait for a reply... */
19208   W (ret);
19209   return ret;
19210 }
19211
19212 static int
19213 api_show_one_status (vat_main_t * vam)
19214 {
19215   vl_api_show_one_status_t *mp;
19216   int ret;
19217
19218   if (!vam->json_output)
19219     {
19220       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19221     }
19222
19223   M (SHOW_ONE_STATUS, mp);
19224   /* send it... */
19225   S (mp);
19226   /* Wait for a reply... */
19227   W (ret);
19228   return ret;
19229 }
19230
19231 #define api_show_lisp_status api_show_one_status
19232
19233 static int
19234 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19235 {
19236   vl_api_gpe_fwd_entry_path_dump_t *mp;
19237   vl_api_control_ping_t *mp_ping;
19238   unformat_input_t *i = vam->input;
19239   u32 fwd_entry_index = ~0;
19240   int ret;
19241
19242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19243     {
19244       if (unformat (i, "index %d", &fwd_entry_index))
19245         ;
19246       else
19247         break;
19248     }
19249
19250   if (~0 == fwd_entry_index)
19251     {
19252       errmsg ("no index specified!");
19253       return -99;
19254     }
19255
19256   if (!vam->json_output)
19257     {
19258       print (vam->ofp, "first line");
19259     }
19260
19261   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19262
19263   /* send it... */
19264   S (mp);
19265   /* Use a control ping for synchronization */
19266   MPING (CONTROL_PING, mp_ping);
19267   S (mp_ping);
19268
19269   /* Wait for a reply... */
19270   W (ret);
19271   return ret;
19272 }
19273
19274 static int
19275 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19276 {
19277   vl_api_one_get_map_request_itr_rlocs_t *mp;
19278   int ret;
19279
19280   if (!vam->json_output)
19281     {
19282       print (vam->ofp, "%=20s", "itr-rlocs:");
19283     }
19284
19285   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19286   /* send it... */
19287   S (mp);
19288   /* Wait for a reply... */
19289   W (ret);
19290   return ret;
19291 }
19292
19293 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19294
19295 static int
19296 api_af_packet_create (vat_main_t * vam)
19297 {
19298   unformat_input_t *i = vam->input;
19299   vl_api_af_packet_create_t *mp;
19300   u8 *host_if_name = 0;
19301   u8 hw_addr[6];
19302   u8 random_hw_addr = 1;
19303   int ret;
19304
19305   clib_memset (hw_addr, 0, sizeof (hw_addr));
19306
19307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19308     {
19309       if (unformat (i, "name %s", &host_if_name))
19310         vec_add1 (host_if_name, 0);
19311       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19312         random_hw_addr = 0;
19313       else
19314         break;
19315     }
19316
19317   if (!vec_len (host_if_name))
19318     {
19319       errmsg ("host-interface name must be specified");
19320       return -99;
19321     }
19322
19323   if (vec_len (host_if_name) > 64)
19324     {
19325       errmsg ("host-interface name too long");
19326       return -99;
19327     }
19328
19329   M (AF_PACKET_CREATE, mp);
19330
19331   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19332   clib_memcpy (mp->hw_addr, hw_addr, 6);
19333   mp->use_random_hw_addr = random_hw_addr;
19334   vec_free (host_if_name);
19335
19336   S (mp);
19337
19338   /* *INDENT-OFF* */
19339   W2 (ret,
19340       ({
19341         if (ret == 0)
19342           fprintf (vam->ofp ? vam->ofp : stderr,
19343                    " new sw_if_index = %d\n", vam->sw_if_index);
19344       }));
19345   /* *INDENT-ON* */
19346   return ret;
19347 }
19348
19349 static int
19350 api_af_packet_delete (vat_main_t * vam)
19351 {
19352   unformat_input_t *i = vam->input;
19353   vl_api_af_packet_delete_t *mp;
19354   u8 *host_if_name = 0;
19355   int ret;
19356
19357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19358     {
19359       if (unformat (i, "name %s", &host_if_name))
19360         vec_add1 (host_if_name, 0);
19361       else
19362         break;
19363     }
19364
19365   if (!vec_len (host_if_name))
19366     {
19367       errmsg ("host-interface name must be specified");
19368       return -99;
19369     }
19370
19371   if (vec_len (host_if_name) > 64)
19372     {
19373       errmsg ("host-interface name too long");
19374       return -99;
19375     }
19376
19377   M (AF_PACKET_DELETE, mp);
19378
19379   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19380   vec_free (host_if_name);
19381
19382   S (mp);
19383   W (ret);
19384   return ret;
19385 }
19386
19387 static void vl_api_af_packet_details_t_handler
19388   (vl_api_af_packet_details_t * mp)
19389 {
19390   vat_main_t *vam = &vat_main;
19391
19392   print (vam->ofp, "%-16s %d",
19393          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19394 }
19395
19396 static void vl_api_af_packet_details_t_handler_json
19397   (vl_api_af_packet_details_t * mp)
19398 {
19399   vat_main_t *vam = &vat_main;
19400   vat_json_node_t *node = NULL;
19401
19402   if (VAT_JSON_ARRAY != vam->json_tree.type)
19403     {
19404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19405       vat_json_init_array (&vam->json_tree);
19406     }
19407   node = vat_json_array_add (&vam->json_tree);
19408
19409   vat_json_init_object (node);
19410   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19411   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19412 }
19413
19414 static int
19415 api_af_packet_dump (vat_main_t * vam)
19416 {
19417   vl_api_af_packet_dump_t *mp;
19418   vl_api_control_ping_t *mp_ping;
19419   int ret;
19420
19421   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19422   /* Get list of tap interfaces */
19423   M (AF_PACKET_DUMP, mp);
19424   S (mp);
19425
19426   /* Use a control ping for synchronization */
19427   MPING (CONTROL_PING, mp_ping);
19428   S (mp_ping);
19429
19430   W (ret);
19431   return ret;
19432 }
19433
19434 static int
19435 api_policer_add_del (vat_main_t * vam)
19436 {
19437   unformat_input_t *i = vam->input;
19438   vl_api_policer_add_del_t *mp;
19439   u8 is_add = 1;
19440   u8 *name = 0;
19441   u32 cir = 0;
19442   u32 eir = 0;
19443   u64 cb = 0;
19444   u64 eb = 0;
19445   u8 rate_type = 0;
19446   u8 round_type = 0;
19447   u8 type = 0;
19448   u8 color_aware = 0;
19449   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19450   int ret;
19451
19452   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19453   conform_action.dscp = 0;
19454   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19455   exceed_action.dscp = 0;
19456   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19457   violate_action.dscp = 0;
19458
19459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19460     {
19461       if (unformat (i, "del"))
19462         is_add = 0;
19463       else if (unformat (i, "name %s", &name))
19464         vec_add1 (name, 0);
19465       else if (unformat (i, "cir %u", &cir))
19466         ;
19467       else if (unformat (i, "eir %u", &eir))
19468         ;
19469       else if (unformat (i, "cb %u", &cb))
19470         ;
19471       else if (unformat (i, "eb %u", &eb))
19472         ;
19473       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19474                          &rate_type))
19475         ;
19476       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19477                          &round_type))
19478         ;
19479       else if (unformat (i, "type %U", unformat_policer_type, &type))
19480         ;
19481       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19482                          &conform_action))
19483         ;
19484       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19485                          &exceed_action))
19486         ;
19487       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19488                          &violate_action))
19489         ;
19490       else if (unformat (i, "color-aware"))
19491         color_aware = 1;
19492       else
19493         break;
19494     }
19495
19496   if (!vec_len (name))
19497     {
19498       errmsg ("policer name must be specified");
19499       return -99;
19500     }
19501
19502   if (vec_len (name) > 64)
19503     {
19504       errmsg ("policer name too long");
19505       return -99;
19506     }
19507
19508   M (POLICER_ADD_DEL, mp);
19509
19510   clib_memcpy (mp->name, name, vec_len (name));
19511   vec_free (name);
19512   mp->is_add = is_add;
19513   mp->cir = ntohl (cir);
19514   mp->eir = ntohl (eir);
19515   mp->cb = clib_net_to_host_u64 (cb);
19516   mp->eb = clib_net_to_host_u64 (eb);
19517   mp->rate_type = rate_type;
19518   mp->round_type = round_type;
19519   mp->type = type;
19520   mp->conform_action_type = conform_action.action_type;
19521   mp->conform_dscp = conform_action.dscp;
19522   mp->exceed_action_type = exceed_action.action_type;
19523   mp->exceed_dscp = exceed_action.dscp;
19524   mp->violate_action_type = violate_action.action_type;
19525   mp->violate_dscp = violate_action.dscp;
19526   mp->color_aware = color_aware;
19527
19528   S (mp);
19529   W (ret);
19530   return ret;
19531 }
19532
19533 static int
19534 api_policer_dump (vat_main_t * vam)
19535 {
19536   unformat_input_t *i = vam->input;
19537   vl_api_policer_dump_t *mp;
19538   vl_api_control_ping_t *mp_ping;
19539   u8 *match_name = 0;
19540   u8 match_name_valid = 0;
19541   int ret;
19542
19543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19544     {
19545       if (unformat (i, "name %s", &match_name))
19546         {
19547           vec_add1 (match_name, 0);
19548           match_name_valid = 1;
19549         }
19550       else
19551         break;
19552     }
19553
19554   M (POLICER_DUMP, mp);
19555   mp->match_name_valid = match_name_valid;
19556   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19557   vec_free (match_name);
19558   /* send it... */
19559   S (mp);
19560
19561   /* Use a control ping for synchronization */
19562   MPING (CONTROL_PING, mp_ping);
19563   S (mp_ping);
19564
19565   /* Wait for a reply... */
19566   W (ret);
19567   return ret;
19568 }
19569
19570 static int
19571 api_policer_classify_set_interface (vat_main_t * vam)
19572 {
19573   unformat_input_t *i = vam->input;
19574   vl_api_policer_classify_set_interface_t *mp;
19575   u32 sw_if_index;
19576   int sw_if_index_set;
19577   u32 ip4_table_index = ~0;
19578   u32 ip6_table_index = ~0;
19579   u32 l2_table_index = ~0;
19580   u8 is_add = 1;
19581   int ret;
19582
19583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19584     {
19585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19586         sw_if_index_set = 1;
19587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19588         sw_if_index_set = 1;
19589       else if (unformat (i, "del"))
19590         is_add = 0;
19591       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19592         ;
19593       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19594         ;
19595       else if (unformat (i, "l2-table %d", &l2_table_index))
19596         ;
19597       else
19598         {
19599           clib_warning ("parse error '%U'", format_unformat_error, i);
19600           return -99;
19601         }
19602     }
19603
19604   if (sw_if_index_set == 0)
19605     {
19606       errmsg ("missing interface name or sw_if_index");
19607       return -99;
19608     }
19609
19610   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19611
19612   mp->sw_if_index = ntohl (sw_if_index);
19613   mp->ip4_table_index = ntohl (ip4_table_index);
19614   mp->ip6_table_index = ntohl (ip6_table_index);
19615   mp->l2_table_index = ntohl (l2_table_index);
19616   mp->is_add = is_add;
19617
19618   S (mp);
19619   W (ret);
19620   return ret;
19621 }
19622
19623 static int
19624 api_policer_classify_dump (vat_main_t * vam)
19625 {
19626   unformat_input_t *i = vam->input;
19627   vl_api_policer_classify_dump_t *mp;
19628   vl_api_control_ping_t *mp_ping;
19629   u8 type = POLICER_CLASSIFY_N_TABLES;
19630   int ret;
19631
19632   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19633     ;
19634   else
19635     {
19636       errmsg ("classify table type must be specified");
19637       return -99;
19638     }
19639
19640   if (!vam->json_output)
19641     {
19642       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19643     }
19644
19645   M (POLICER_CLASSIFY_DUMP, mp);
19646   mp->type = type;
19647   /* send it... */
19648   S (mp);
19649
19650   /* Use a control ping for synchronization */
19651   MPING (CONTROL_PING, mp_ping);
19652   S (mp_ping);
19653
19654   /* Wait for a reply... */
19655   W (ret);
19656   return ret;
19657 }
19658
19659 static int
19660 api_netmap_create (vat_main_t * vam)
19661 {
19662   unformat_input_t *i = vam->input;
19663   vl_api_netmap_create_t *mp;
19664   u8 *if_name = 0;
19665   u8 hw_addr[6];
19666   u8 random_hw_addr = 1;
19667   u8 is_pipe = 0;
19668   u8 is_master = 0;
19669   int ret;
19670
19671   clib_memset (hw_addr, 0, sizeof (hw_addr));
19672
19673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19674     {
19675       if (unformat (i, "name %s", &if_name))
19676         vec_add1 (if_name, 0);
19677       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19678         random_hw_addr = 0;
19679       else if (unformat (i, "pipe"))
19680         is_pipe = 1;
19681       else if (unformat (i, "master"))
19682         is_master = 1;
19683       else if (unformat (i, "slave"))
19684         is_master = 0;
19685       else
19686         break;
19687     }
19688
19689   if (!vec_len (if_name))
19690     {
19691       errmsg ("interface name must be specified");
19692       return -99;
19693     }
19694
19695   if (vec_len (if_name) > 64)
19696     {
19697       errmsg ("interface name too long");
19698       return -99;
19699     }
19700
19701   M (NETMAP_CREATE, mp);
19702
19703   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19704   clib_memcpy (mp->hw_addr, hw_addr, 6);
19705   mp->use_random_hw_addr = random_hw_addr;
19706   mp->is_pipe = is_pipe;
19707   mp->is_master = is_master;
19708   vec_free (if_name);
19709
19710   S (mp);
19711   W (ret);
19712   return ret;
19713 }
19714
19715 static int
19716 api_netmap_delete (vat_main_t * vam)
19717 {
19718   unformat_input_t *i = vam->input;
19719   vl_api_netmap_delete_t *mp;
19720   u8 *if_name = 0;
19721   int ret;
19722
19723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19724     {
19725       if (unformat (i, "name %s", &if_name))
19726         vec_add1 (if_name, 0);
19727       else
19728         break;
19729     }
19730
19731   if (!vec_len (if_name))
19732     {
19733       errmsg ("interface name must be specified");
19734       return -99;
19735     }
19736
19737   if (vec_len (if_name) > 64)
19738     {
19739       errmsg ("interface name too long");
19740       return -99;
19741     }
19742
19743   M (NETMAP_DELETE, mp);
19744
19745   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19746   vec_free (if_name);
19747
19748   S (mp);
19749   W (ret);
19750   return ret;
19751 }
19752
19753 static void
19754 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19755 {
19756   if (fp->afi == IP46_TYPE_IP6)
19757     print (vam->ofp,
19758            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19759            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19760            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19761            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19762            format_ip6_address, fp->next_hop);
19763   else if (fp->afi == IP46_TYPE_IP4)
19764     print (vam->ofp,
19765            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19766            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19767            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19768            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19769            format_ip4_address, fp->next_hop);
19770 }
19771
19772 static void
19773 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19774                                  vl_api_fib_path_t * fp)
19775 {
19776   struct in_addr ip4;
19777   struct in6_addr ip6;
19778
19779   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19780   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19781   vat_json_object_add_uint (node, "is_local", fp->is_local);
19782   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19783   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19784   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19785   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19786   if (fp->afi == IP46_TYPE_IP4)
19787     {
19788       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19789       vat_json_object_add_ip4 (node, "next_hop", ip4);
19790     }
19791   else if (fp->afi == IP46_TYPE_IP6)
19792     {
19793       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19794       vat_json_object_add_ip6 (node, "next_hop", ip6);
19795     }
19796 }
19797
19798 static void
19799 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19800 {
19801   vat_main_t *vam = &vat_main;
19802   int count = ntohl (mp->mt_count);
19803   vl_api_fib_path_t *fp;
19804   i32 i;
19805
19806   print (vam->ofp, "[%d]: sw_if_index %d via:",
19807          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19808   fp = mp->mt_paths;
19809   for (i = 0; i < count; i++)
19810     {
19811       vl_api_mpls_fib_path_print (vam, fp);
19812       fp++;
19813     }
19814
19815   print (vam->ofp, "");
19816 }
19817
19818 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19819 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19820
19821 static void
19822 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19823 {
19824   vat_main_t *vam = &vat_main;
19825   vat_json_node_t *node = NULL;
19826   int count = ntohl (mp->mt_count);
19827   vl_api_fib_path_t *fp;
19828   i32 i;
19829
19830   if (VAT_JSON_ARRAY != vam->json_tree.type)
19831     {
19832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19833       vat_json_init_array (&vam->json_tree);
19834     }
19835   node = vat_json_array_add (&vam->json_tree);
19836
19837   vat_json_init_object (node);
19838   vat_json_object_add_uint (node, "tunnel_index",
19839                             ntohl (mp->mt_tunnel_index));
19840   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19841
19842   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19843
19844   fp = mp->mt_paths;
19845   for (i = 0; i < count; i++)
19846     {
19847       vl_api_mpls_fib_path_json_print (node, fp);
19848       fp++;
19849     }
19850 }
19851
19852 static int
19853 api_mpls_tunnel_dump (vat_main_t * vam)
19854 {
19855   vl_api_mpls_tunnel_dump_t *mp;
19856   vl_api_control_ping_t *mp_ping;
19857   u32 sw_if_index = ~0;
19858   int ret;
19859
19860   /* Parse args required to build the message */
19861   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19862     {
19863       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19864         ;
19865     }
19866
19867   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19868
19869   M (MPLS_TUNNEL_DUMP, mp);
19870   mp->sw_if_index = htonl (sw_if_index);
19871   S (mp);
19872
19873   /* Use a control ping for synchronization */
19874   MPING (CONTROL_PING, mp_ping);
19875   S (mp_ping);
19876
19877   W (ret);
19878   return ret;
19879 }
19880
19881 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19882 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19883
19884
19885 static void
19886 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19887 {
19888   vat_main_t *vam = &vat_main;
19889   int count = ntohl (mp->count);
19890   vl_api_fib_path_t *fp;
19891   int i;
19892
19893   print (vam->ofp,
19894          "table-id %d, label %u, ess_bit %u",
19895          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19896   fp = mp->path;
19897   for (i = 0; i < count; i++)
19898     {
19899       vl_api_mpls_fib_path_print (vam, fp);
19900       fp++;
19901     }
19902 }
19903
19904 static void vl_api_mpls_fib_details_t_handler_json
19905   (vl_api_mpls_fib_details_t * mp)
19906 {
19907   vat_main_t *vam = &vat_main;
19908   int count = ntohl (mp->count);
19909   vat_json_node_t *node = NULL;
19910   vl_api_fib_path_t *fp;
19911   int i;
19912
19913   if (VAT_JSON_ARRAY != vam->json_tree.type)
19914     {
19915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19916       vat_json_init_array (&vam->json_tree);
19917     }
19918   node = vat_json_array_add (&vam->json_tree);
19919
19920   vat_json_init_object (node);
19921   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19922   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19923   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19924   vat_json_object_add_uint (node, "path_count", count);
19925   fp = mp->path;
19926   for (i = 0; i < count; i++)
19927     {
19928       vl_api_mpls_fib_path_json_print (node, fp);
19929       fp++;
19930     }
19931 }
19932
19933 static int
19934 api_mpls_fib_dump (vat_main_t * vam)
19935 {
19936   vl_api_mpls_fib_dump_t *mp;
19937   vl_api_control_ping_t *mp_ping;
19938   int ret;
19939
19940   M (MPLS_FIB_DUMP, mp);
19941   S (mp);
19942
19943   /* Use a control ping for synchronization */
19944   MPING (CONTROL_PING, mp_ping);
19945   S (mp_ping);
19946
19947   W (ret);
19948   return ret;
19949 }
19950
19951 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19952 #define vl_api_ip_fib_details_t_print vl_noop_handler
19953
19954 static void
19955 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19956 {
19957   vat_main_t *vam = &vat_main;
19958   int count = ntohl (mp->count);
19959   vl_api_fib_path_t *fp;
19960   int i;
19961
19962   print (vam->ofp,
19963          "table-id %d, prefix %U/%d stats-index %d",
19964          ntohl (mp->table_id), format_ip4_address, mp->address,
19965          mp->address_length, ntohl (mp->stats_index));
19966   fp = mp->path;
19967   for (i = 0; i < count; i++)
19968     {
19969       if (fp->afi == IP46_TYPE_IP6)
19970         print (vam->ofp,
19971                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19972                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19973                "next_hop_table %d",
19974                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19975                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19976                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19977       else if (fp->afi == IP46_TYPE_IP4)
19978         print (vam->ofp,
19979                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19980                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19981                "next_hop_table %d",
19982                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19983                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19984                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19985       fp++;
19986     }
19987 }
19988
19989 static void vl_api_ip_fib_details_t_handler_json
19990   (vl_api_ip_fib_details_t * mp)
19991 {
19992   vat_main_t *vam = &vat_main;
19993   int count = ntohl (mp->count);
19994   vat_json_node_t *node = NULL;
19995   struct in_addr ip4;
19996   struct in6_addr ip6;
19997   vl_api_fib_path_t *fp;
19998   int i;
19999
20000   if (VAT_JSON_ARRAY != vam->json_tree.type)
20001     {
20002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20003       vat_json_init_array (&vam->json_tree);
20004     }
20005   node = vat_json_array_add (&vam->json_tree);
20006
20007   vat_json_init_object (node);
20008   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20009   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20010   vat_json_object_add_ip4 (node, "prefix", ip4);
20011   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20012   vat_json_object_add_uint (node, "path_count", count);
20013   fp = mp->path;
20014   for (i = 0; i < count; i++)
20015     {
20016       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20017       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20018       vat_json_object_add_uint (node, "is_local", fp->is_local);
20019       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20020       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20021       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20022       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20023       if (fp->afi == IP46_TYPE_IP4)
20024         {
20025           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20026           vat_json_object_add_ip4 (node, "next_hop", ip4);
20027         }
20028       else if (fp->afi == IP46_TYPE_IP6)
20029         {
20030           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20031           vat_json_object_add_ip6 (node, "next_hop", ip6);
20032         }
20033     }
20034 }
20035
20036 static int
20037 api_ip_fib_dump (vat_main_t * vam)
20038 {
20039   vl_api_ip_fib_dump_t *mp;
20040   vl_api_control_ping_t *mp_ping;
20041   int ret;
20042
20043   M (IP_FIB_DUMP, mp);
20044   S (mp);
20045
20046   /* Use a control ping for synchronization */
20047   MPING (CONTROL_PING, mp_ping);
20048   S (mp_ping);
20049
20050   W (ret);
20051   return ret;
20052 }
20053
20054 static int
20055 api_ip_mfib_dump (vat_main_t * vam)
20056 {
20057   vl_api_ip_mfib_dump_t *mp;
20058   vl_api_control_ping_t *mp_ping;
20059   int ret;
20060
20061   M (IP_MFIB_DUMP, mp);
20062   S (mp);
20063
20064   /* Use a control ping for synchronization */
20065   MPING (CONTROL_PING, mp_ping);
20066   S (mp_ping);
20067
20068   W (ret);
20069   return ret;
20070 }
20071
20072 static void vl_api_ip_neighbor_details_t_handler
20073   (vl_api_ip_neighbor_details_t * mp)
20074 {
20075   vat_main_t *vam = &vat_main;
20076
20077   print (vam->ofp, "%c %U %U",
20078          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
20079          format_vl_api_mac_address, &mp->neighbor.mac_address,
20080          format_vl_api_address, &mp->neighbor.ip_address);
20081 }
20082
20083 static void vl_api_ip_neighbor_details_t_handler_json
20084   (vl_api_ip_neighbor_details_t * mp)
20085 {
20086
20087   vat_main_t *vam = &vat_main;
20088   vat_json_node_t *node;
20089   struct in_addr ip4;
20090   struct in6_addr ip6;
20091
20092   if (VAT_JSON_ARRAY != vam->json_tree.type)
20093     {
20094       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20095       vat_json_init_array (&vam->json_tree);
20096     }
20097   node = vat_json_array_add (&vam->json_tree);
20098
20099   vat_json_init_object (node);
20100   vat_json_object_add_string_copy
20101     (node, "flag",
20102      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
20103       (u8 *) "static" : (u8 *) "dynamic"));
20104
20105   vat_json_object_add_string_copy (node, "link_layer",
20106                                    format (0, "%U", format_vl_api_mac_address,
20107                                            &mp->neighbor.mac_address));
20108
20109   if (ADDRESS_IP6 == mp->neighbor.ip_address.af)
20110     {
20111       clib_memcpy (&ip6, &mp->neighbor.ip_address.un.ip6, sizeof (ip6));
20112       vat_json_object_add_ip6 (node, "ip_address", ip6);
20113     }
20114   else
20115     {
20116       clib_memcpy (&ip4, &mp->neighbor.ip_address.un.ip4, sizeof (ip4));
20117       vat_json_object_add_ip4 (node, "ip_address", ip4);
20118     }
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);
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  */