Remove historical ip4 icmp OAM code
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #define vl_print(handle, ...)
77 #define vl_printfun
78 #include <vpp/api/vpe_all_api_h.h>
79 #undef vl_printfun
80
81 #define __plugin_msg_base 0
82 #include <vlibapi/vat_helper_macros.h>
83
84 #if VPP_API_TEST_BUILTIN == 0
85 #include <netdb.h>
86
87 u32
88 vl (void *p)
89 {
90   return vec_len (p);
91 }
92
93 int
94 vat_socket_connect (vat_main_t * vam)
95 {
96   int rv;
97   vam->socket_client_main = &socket_client_main;
98   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
99                                       "vpp_api_test",
100                                       0 /* default socket rx, tx buffer */ )))
101     return rv;
102   /* vpp expects the client index in network order */
103   vam->my_client_index = htonl (socket_client_main.client_index);
104   return 0;
105 }
106 #else /* vpp built-in case, we don't do sockets... */
107 int
108 vat_socket_connect (vat_main_t * vam)
109 {
110   return 0;
111 }
112
113 int
114 vl_socket_client_read (int wait)
115 {
116   return -1;
117 };
118
119 int
120 vl_socket_client_write ()
121 {
122   return -1;
123 };
124
125 void *
126 vl_socket_client_msg_alloc (int nbytes)
127 {
128   return 0;
129 }
130 #endif
131
132
133 f64
134 vat_time_now (vat_main_t * vam)
135 {
136 #if VPP_API_TEST_BUILTIN
137   return vlib_time_now (vam->vlib_main);
138 #else
139   return clib_time_now (&vam->clib_time);
140 #endif
141 }
142
143 void
144 errmsg (char *fmt, ...)
145 {
146   vat_main_t *vam = &vat_main;
147   va_list va;
148   u8 *s;
149
150   va_start (va, fmt);
151   s = va_format (0, fmt, &va);
152   va_end (va);
153
154   vec_add1 (s, 0);
155
156 #if VPP_API_TEST_BUILTIN
157   vlib_cli_output (vam->vlib_main, (char *) s);
158 #else
159   {
160     if (vam->ifp != stdin)
161       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
162                vam->input_line_number);
163     fformat (vam->ofp, (char *) s);
164     fflush (vam->ofp);
165   }
166 #endif
167
168   vec_free (s);
169 }
170
171 #if VPP_API_TEST_BUILTIN == 0
172 static uword
173 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
174 {
175   vat_main_t *vam = va_arg (*args, vat_main_t *);
176   u32 *result = va_arg (*args, u32 *);
177   u8 *if_name;
178   uword *p;
179
180   if (!unformat (input, "%s", &if_name))
181     return 0;
182
183   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
184   if (p == 0)
185     return 0;
186   *result = p[0];
187   return 1;
188 }
189
190 static uword
191 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
192 {
193   return 0;
194 }
195
196 /* Parse an IP4 address %d.%d.%d.%d. */
197 uword
198 unformat_ip4_address (unformat_input_t * input, va_list * args)
199 {
200   u8 *result = va_arg (*args, u8 *);
201   unsigned a[4];
202
203   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
204     return 0;
205
206   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
207     return 0;
208
209   result[0] = a[0];
210   result[1] = a[1];
211   result[2] = a[2];
212   result[3] = a[3];
213
214   return 1;
215 }
216
217 uword
218 unformat_ethernet_address (unformat_input_t * input, va_list * args)
219 {
220   u8 *result = va_arg (*args, u8 *);
221   u32 i, a[6];
222
223   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
224                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
225     return 0;
226
227   /* Check range. */
228   for (i = 0; i < 6; i++)
229     if (a[i] >= (1 << 8))
230       return 0;
231
232   for (i = 0; i < 6; i++)
233     result[i] = a[i];
234
235   return 1;
236 }
237
238 /* Returns ethernet type as an int in host byte order. */
239 uword
240 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
241                                         va_list * args)
242 {
243   u16 *result = va_arg (*args, u16 *);
244   int type;
245
246   /* Numeric type. */
247   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
248     {
249       if (type >= (1 << 16))
250         return 0;
251       *result = type;
252       return 1;
253     }
254   return 0;
255 }
256
257 /* Parse an IP6 address. */
258 uword
259 unformat_ip6_address (unformat_input_t * input, va_list * args)
260 {
261   ip6_address_t *result = va_arg (*args, ip6_address_t *);
262   u16 hex_quads[8];
263   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
264   uword c, n_colon, double_colon_index;
265
266   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
267   double_colon_index = ARRAY_LEN (hex_quads);
268   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
269     {
270       hex_digit = 16;
271       if (c >= '0' && c <= '9')
272         hex_digit = c - '0';
273       else if (c >= 'a' && c <= 'f')
274         hex_digit = c + 10 - 'a';
275       else if (c >= 'A' && c <= 'F')
276         hex_digit = c + 10 - 'A';
277       else if (c == ':' && n_colon < 2)
278         n_colon++;
279       else
280         {
281           unformat_put_input (input);
282           break;
283         }
284
285       /* Too many hex quads. */
286       if (n_hex_quads >= ARRAY_LEN (hex_quads))
287         return 0;
288
289       if (hex_digit < 16)
290         {
291           hex_quad = (hex_quad << 4) | hex_digit;
292
293           /* Hex quad must fit in 16 bits. */
294           if (n_hex_digits >= 4)
295             return 0;
296
297           n_colon = 0;
298           n_hex_digits++;
299         }
300
301       /* Save position of :: */
302       if (n_colon == 2)
303         {
304           /* More than one :: ? */
305           if (double_colon_index < ARRAY_LEN (hex_quads))
306             return 0;
307           double_colon_index = n_hex_quads;
308         }
309
310       if (n_colon > 0 && n_hex_digits > 0)
311         {
312           hex_quads[n_hex_quads++] = hex_quad;
313           hex_quad = 0;
314           n_hex_digits = 0;
315         }
316     }
317
318   if (n_hex_digits > 0)
319     hex_quads[n_hex_quads++] = hex_quad;
320
321   {
322     word i;
323
324     /* Expand :: to appropriate number of zero hex quads. */
325     if (double_colon_index < ARRAY_LEN (hex_quads))
326       {
327         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
328
329         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
330           hex_quads[n_zero + i] = hex_quads[i];
331
332         for (i = 0; i < n_zero; i++)
333           hex_quads[double_colon_index + i] = 0;
334
335         n_hex_quads = ARRAY_LEN (hex_quads);
336       }
337
338     /* Too few hex quads given. */
339     if (n_hex_quads < ARRAY_LEN (hex_quads))
340       return 0;
341
342     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
343       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
344
345     return 1;
346   }
347 }
348
349 uword
350 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
351 {
352   u32 *r = va_arg (*args, u32 *);
353
354   if (0);
355 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
356   foreach_ipsec_policy_action
357 #undef _
358     else
359     return 0;
360   return 1;
361 }
362
363 u8 *
364 format_ipsec_crypto_alg (u8 * s, va_list * args)
365 {
366   u32 i = va_arg (*args, u32);
367   u8 *t = 0;
368
369   switch (i)
370     {
371 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
372       foreach_ipsec_crypto_alg
373 #undef _
374     default:
375       return format (s, "unknown");
376     }
377   return format (s, "%s", t);
378 }
379
380 u8 *
381 format_ipsec_integ_alg (u8 * s, va_list * args)
382 {
383   u32 i = va_arg (*args, u32);
384   u8 *t = 0;
385
386   switch (i)
387     {
388 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
389       foreach_ipsec_integ_alg
390 #undef _
391     default:
392       return format (s, "unknown");
393     }
394   return format (s, "%s", t);
395 }
396
397 #else /* VPP_API_TEST_BUILTIN == 1 */
398 static uword
399 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
400 {
401   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
402   vnet_main_t *vnm = vnet_get_main ();
403   u32 *result = va_arg (*args, u32 *);
404
405   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
406 }
407
408 static uword
409 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
412   vnet_main_t *vnm = vnet_get_main ();
413   u32 *result = va_arg (*args, u32 *);
414
415   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
416 }
417
418 #endif /* VPP_API_TEST_BUILTIN */
419
420 uword
421 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
422 {
423   u32 *r = va_arg (*args, u32 *);
424
425   if (0);
426 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
427   foreach_ipsec_crypto_alg
428 #undef _
429     else
430     return 0;
431   return 1;
432 }
433
434 uword
435 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
436 {
437   u32 *r = va_arg (*args, u32 *);
438
439   if (0);
440 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
441   foreach_ipsec_integ_alg
442 #undef _
443     else
444     return 0;
445   return 1;
446 }
447
448 static uword
449 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
450 {
451   u8 *r = va_arg (*args, u8 *);
452
453   if (unformat (input, "kbps"))
454     *r = SSE2_QOS_RATE_KBPS;
455   else if (unformat (input, "pps"))
456     *r = SSE2_QOS_RATE_PPS;
457   else
458     return 0;
459   return 1;
460 }
461
462 static uword
463 unformat_policer_round_type (unformat_input_t * input, va_list * args)
464 {
465   u8 *r = va_arg (*args, u8 *);
466
467   if (unformat (input, "closest"))
468     *r = SSE2_QOS_ROUND_TO_CLOSEST;
469   else if (unformat (input, "up"))
470     *r = SSE2_QOS_ROUND_TO_UP;
471   else if (unformat (input, "down"))
472     *r = SSE2_QOS_ROUND_TO_DOWN;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "1r2c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R2C;
485   else if (unformat (input, "1r3c"))
486     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
487   else if (unformat (input, "2r3c-2698"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
489   else if (unformat (input, "2r3c-4115"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
491   else if (unformat (input, "2r3c-mef5cf1"))
492     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
493   else
494     return 0;
495   return 1;
496 }
497
498 static uword
499 unformat_dscp (unformat_input_t * input, va_list * va)
500 {
501   u8 *r = va_arg (*va, u8 *);
502
503   if (0);
504 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
505   foreach_vnet_dscp
506 #undef _
507     else
508     return 0;
509   return 1;
510 }
511
512 static uword
513 unformat_policer_action_type (unformat_input_t * input, va_list * va)
514 {
515   sse2_qos_pol_action_params_st *a
516     = va_arg (*va, sse2_qos_pol_action_params_st *);
517
518   if (unformat (input, "drop"))
519     a->action_type = SSE2_QOS_ACTION_DROP;
520   else if (unformat (input, "transmit"))
521     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
522   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
523     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
524   else
525     return 0;
526   return 1;
527 }
528
529 static uword
530 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
531 {
532   u32 *r = va_arg (*va, u32 *);
533   u32 tid;
534
535   if (unformat (input, "ip4"))
536     tid = POLICER_CLASSIFY_TABLE_IP4;
537   else if (unformat (input, "ip6"))
538     tid = POLICER_CLASSIFY_TABLE_IP6;
539   else if (unformat (input, "l2"))
540     tid = POLICER_CLASSIFY_TABLE_L2;
541   else
542     return 0;
543
544   *r = tid;
545   return 1;
546 }
547
548 static uword
549 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
550 {
551   u32 *r = va_arg (*va, u32 *);
552   u32 tid;
553
554   if (unformat (input, "ip4"))
555     tid = FLOW_CLASSIFY_TABLE_IP4;
556   else if (unformat (input, "ip6"))
557     tid = FLOW_CLASSIFY_TABLE_IP6;
558   else
559     return 0;
560
561   *r = tid;
562   return 1;
563 }
564
565 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
566 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
567 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
568 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
569
570 #if (VPP_API_TEST_BUILTIN==0)
571 uword
572 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
573 {
574   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
575   mfib_itf_attribute_t attr;
576
577   old = *iflags;
578   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
579   {
580     if (unformat (input, mfib_itf_flag_long_names[attr]))
581       *iflags |= (1 << attr);
582   }
583   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
584   {
585     if (unformat (input, mfib_itf_flag_names[attr]))
586       *iflags |= (1 << attr);
587   }
588
589   return (old == *iflags ? 0 : 1);
590 }
591
592 uword
593 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
594 {
595   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
596   mfib_entry_attribute_t attr;
597
598   old = *eflags;
599   FOR_EACH_MFIB_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_flag_long_names[attr]))
602       *eflags |= (1 << attr);
603   }
604   FOR_EACH_MFIB_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_flag_names[attr]))
607       *eflags |= (1 << attr);
608   }
609
610   return (old == *eflags ? 0 : 1);
611 }
612
613 u8 *
614 format_ip4_address (u8 * s, va_list * args)
615 {
616   u8 *a = va_arg (*args, u8 *);
617   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
618 }
619
620 u8 *
621 format_ip6_address (u8 * s, va_list * args)
622 {
623   ip6_address_t *a = va_arg (*args, ip6_address_t *);
624   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
625
626   i_max_n_zero = ARRAY_LEN (a->as_u16);
627   max_n_zeros = 0;
628   i_first_zero = i_max_n_zero;
629   n_zeros = 0;
630   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
631     {
632       u32 is_zero = a->as_u16[i] == 0;
633       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
634         {
635           i_first_zero = i;
636           n_zeros = 0;
637         }
638       n_zeros += is_zero;
639       if ((!is_zero && n_zeros > max_n_zeros)
640           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
641         {
642           i_max_n_zero = i_first_zero;
643           max_n_zeros = n_zeros;
644           i_first_zero = ARRAY_LEN (a->as_u16);
645           n_zeros = 0;
646         }
647     }
648
649   last_double_colon = 0;
650   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
651     {
652       if (i == i_max_n_zero && max_n_zeros > 1)
653         {
654           s = format (s, "::");
655           i += max_n_zeros - 1;
656           last_double_colon = 1;
657         }
658       else
659         {
660           s = format (s, "%s%x",
661                       (last_double_colon || i == 0) ? "" : ":",
662                       clib_net_to_host_u16 (a->as_u16[i]));
663           last_double_colon = 0;
664         }
665     }
666
667   return s;
668 }
669
670 /* Format an IP46 address. */
671 u8 *
672 format_ip46_address (u8 * s, va_list * args)
673 {
674   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
675   ip46_type_t type = va_arg (*args, ip46_type_t);
676   int is_ip4 = 1;
677
678   switch (type)
679     {
680     case IP46_TYPE_ANY:
681       is_ip4 = ip46_address_is_ip4 (ip46);
682       break;
683     case IP46_TYPE_IP4:
684       is_ip4 = 1;
685       break;
686     case IP46_TYPE_IP6:
687       is_ip4 = 0;
688       break;
689     }
690
691   return is_ip4 ?
692     format (s, "%U", format_ip4_address, &ip46->ip4) :
693     format (s, "%U", format_ip6_address, &ip46->ip6);
694 }
695
696 u8 *
697 format_ethernet_address (u8 * s, va_list * args)
698 {
699   u8 *a = va_arg (*args, u8 *);
700
701   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
702                  a[0], a[1], a[2], a[3], a[4], a[5]);
703 }
704 #endif
705
706 static void
707 increment_v4_address (ip4_address_t * a)
708 {
709   u32 v;
710
711   v = ntohl (a->as_u32) + 1;
712   a->as_u32 = ntohl (v);
713 }
714
715 static void
716 increment_vl_v4_address (vl_api_ip4_address_t * a)
717 {
718   u32 v;
719
720   v = *(u32 *) a;
721   v = ntohl (v);
722   v++;
723   v = ntohl (v);
724   clib_memcpy (a, &v, sizeof (v));
725 }
726
727 static void
728 increment_vl_address (vl_api_address_t * a)
729 {
730   if (ADDRESS_IP4 == a->af)
731     increment_vl_v4_address (&a->un.ip4);
732 }
733
734 static void
735 increment_v6_address (ip6_address_t * a)
736 {
737   u64 v0, v1;
738
739   v0 = clib_net_to_host_u64 (a->as_u64[0]);
740   v1 = clib_net_to_host_u64 (a->as_u64[1]);
741
742   v1 += 1;
743   if (v1 == 0)
744     v0 += 1;
745   a->as_u64[0] = clib_net_to_host_u64 (v0);
746   a->as_u64[1] = clib_net_to_host_u64 (v1);
747 }
748
749 static void
750 increment_mac_address (u8 * mac)
751 {
752   u64 tmp = *((u64 *) mac);
753   tmp = clib_net_to_host_u64 (tmp);
754   tmp += 1 << 16;               /* skip unused (least significant) octets */
755   tmp = clib_host_to_net_u64 (tmp);
756
757   clib_memcpy (mac, &tmp, 6);
758 }
759
760 static void vl_api_create_loopback_reply_t_handler
761   (vl_api_create_loopback_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_reply_t_handler_json
773   (vl_api_create_loopback_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_create_loopback_instance_reply_t_handler
789   (vl_api_create_loopback_instance_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_create_loopback_instance_reply_t_handler_json
801   (vl_api_create_loopback_instance_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_af_packet_create_reply_t_handler
817   (vl_api_af_packet_create_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_af_packet_create_reply_t_handler_json
829   (vl_api_af_packet_create_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_vlan_subif_reply_t_handler
846   (vl_api_create_vlan_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_vlan_subif_reply_t_handler_json
858   (vl_api_create_vlan_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_subif_reply_t_handler
875   (vl_api_create_subif_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->sw_if_index = ntohl (mp->sw_if_index);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_subif_reply_t_handler_json
887   (vl_api_create_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
895
896   vat_json_print (vam->ofp, &node);
897   vat_json_free (&node);
898
899   vam->retval = ntohl (mp->retval);
900   vam->result_ready = 1;
901 }
902
903 static void vl_api_interface_name_renumber_reply_t_handler
904   (vl_api_interface_name_renumber_reply_t * mp)
905 {
906   vat_main_t *vam = &vat_main;
907   i32 retval = ntohl (mp->retval);
908
909   vam->retval = retval;
910   vam->regenerate_interface_table = 1;
911   vam->result_ready = 1;
912 }
913
914 static void vl_api_interface_name_renumber_reply_t_handler_json
915   (vl_api_interface_name_renumber_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   vat_json_node_t node;
919
920   vat_json_init_object (&node);
921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
922
923   vat_json_print (vam->ofp, &node);
924   vat_json_free (&node);
925
926   vam->retval = ntohl (mp->retval);
927   vam->result_ready = 1;
928 }
929
930 /*
931  * Special-case: build the interface table, maintain
932  * the next loopback sw_if_index vbl.
933  */
934 static void vl_api_sw_interface_details_t_handler
935   (vl_api_sw_interface_details_t * mp)
936 {
937   vat_main_t *vam = &vat_main;
938   u8 *s = format (0, "%s%c", mp->interface_name, 0);
939
940   hash_set_mem (vam->sw_if_index_by_interface_name, s,
941                 ntohl (mp->sw_if_index));
942
943   /* In sub interface case, fill the sub interface table entry */
944   if (mp->sw_if_index != mp->sup_sw_if_index)
945     {
946       sw_interface_subif_t *sub = NULL;
947
948       vec_add2 (vam->sw_if_subif_table, sub, 1);
949
950       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
951       strncpy ((char *) sub->interface_name, (char *) s,
952                vec_len (sub->interface_name));
953       sub->sw_if_index = ntohl (mp->sw_if_index);
954       sub->sub_id = ntohl (mp->sub_id);
955
956       sub->sub_dot1ad = mp->sub_dot1ad;
957       sub->sub_number_of_tags = mp->sub_number_of_tags;
958       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
959       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
960       sub->sub_exact_match = mp->sub_exact_match;
961       sub->sub_default = mp->sub_default;
962       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
963       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
964
965       /* vlan tag rewrite */
966       sub->vtr_op = ntohl (mp->vtr_op);
967       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
968       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
969       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
970     }
971 }
972
973 static void vl_api_sw_interface_details_t_handler_json
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   vat_json_node_t *node = NULL;
978
979   if (VAT_JSON_ARRAY != vam->json_tree.type)
980     {
981       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
982       vat_json_init_array (&vam->json_tree);
983     }
984   node = vat_json_array_add (&vam->json_tree);
985
986   vat_json_init_object (node);
987   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
988   vat_json_object_add_uint (node, "sup_sw_if_index",
989                             ntohl (mp->sup_sw_if_index));
990   vat_json_object_add_uint (node, "l2_address_length",
991                             ntohl (mp->l2_address_length));
992   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
993                              sizeof (mp->l2_address));
994   vat_json_object_add_string_copy (node, "interface_name",
995                                    mp->interface_name);
996   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
997   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
998   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
999   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1000   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1001   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1002   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1003   vat_json_object_add_uint (node, "sub_number_of_tags",
1004                             mp->sub_number_of_tags);
1005   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1006                             ntohs (mp->sub_outer_vlan_id));
1007   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1008                             ntohs (mp->sub_inner_vlan_id));
1009   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1010   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1012                             mp->sub_outer_vlan_id_any);
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1014                             mp->sub_inner_vlan_id_any);
1015   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1016   vat_json_object_add_uint (node, "vtr_push_dot1q",
1017                             ntohl (mp->vtr_push_dot1q));
1018   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1019   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1020   if (mp->sub_dot1ah)
1021     {
1022       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1023                                        format (0, "%U",
1024                                                format_ethernet_address,
1025                                                &mp->b_dmac));
1026       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1027                                        format (0, "%U",
1028                                                format_ethernet_address,
1029                                                &mp->b_smac));
1030       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1031       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1032     }
1033 }
1034
1035 #if VPP_API_TEST_BUILTIN == 0
1036 static void vl_api_sw_interface_event_t_handler
1037   (vl_api_sw_interface_event_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   if (vam->interface_event_display)
1041     errmsg ("interface flags: sw_if_index %d %s %s",
1042             ntohl (mp->sw_if_index),
1043             mp->admin_up_down ? "admin-up" : "admin-down",
1044             mp->link_up_down ? "link-up" : "link-down");
1045 }
1046 #endif
1047
1048 static void vl_api_sw_interface_event_t_handler_json
1049   (vl_api_sw_interface_event_t * mp)
1050 {
1051   /* JSON output not supported */
1052 }
1053
1054 static void
1055 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1056 {
1057   vat_main_t *vam = &vat_main;
1058   i32 retval = ntohl (mp->retval);
1059
1060   vam->retval = retval;
1061   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1062   vam->result_ready = 1;
1063 }
1064
1065 static void
1066 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070   api_main_t *am = &api_main;
1071   void *oldheap;
1072   u8 *reply;
1073
1074   vat_json_init_object (&node);
1075   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1076   vat_json_object_add_uint (&node, "reply_in_shmem",
1077                             ntohl (mp->reply_in_shmem));
1078   /* Toss the shared-memory original... */
1079   pthread_mutex_lock (&am->vlib_rp->mutex);
1080   oldheap = svm_push_data_heap (am->vlib_rp);
1081
1082   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1083   vec_free (reply);
1084
1085   svm_pop_heap (oldheap);
1086   pthread_mutex_unlock (&am->vlib_rp->mutex);
1087
1088   vat_json_print (vam->ofp, &node);
1089   vat_json_free (&node);
1090
1091   vam->retval = ntohl (mp->retval);
1092   vam->result_ready = 1;
1093 }
1094
1095 static void
1096 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1097 {
1098   vat_main_t *vam = &vat_main;
1099   i32 retval = ntohl (mp->retval);
1100   u32 length = vl_api_string_len (&mp->reply);
1101
1102   vec_reset_length (vam->cmd_reply);
1103
1104   vam->retval = retval;
1105   if (retval == 0)
1106     {
1107       vec_validate (vam->cmd_reply, length);
1108       clib_memcpy ((char *) (vam->cmd_reply),
1109                    vl_api_from_api_string (&mp->reply), length);
1110       vam->cmd_reply[length] = 0;
1111     }
1112   vam->result_ready = 1;
1113 }
1114
1115 static void
1116 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1117 {
1118   vat_main_t *vam = &vat_main;
1119   vat_json_node_t node;
1120
1121   vec_reset_length (vam->cmd_reply);
1122
1123   vat_json_init_object (&node);
1124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1125   vat_json_object_add_string_copy (&node, "reply",
1126                                    vl_api_from_api_string (&mp->reply));
1127
1128   vat_json_print (vam->ofp, &node);
1129   vat_json_free (&node);
1130
1131   vam->retval = ntohl (mp->retval);
1132   vam->result_ready = 1;
1133 }
1134
1135 static void vl_api_classify_add_del_table_reply_t_handler
1136   (vl_api_classify_add_del_table_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   i32 retval = ntohl (mp->retval);
1140   if (vam->async_mode)
1141     {
1142       vam->async_errors += (retval < 0);
1143     }
1144   else
1145     {
1146       vam->retval = retval;
1147       if (retval == 0 &&
1148           ((mp->new_table_index != 0xFFFFFFFF) ||
1149            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1150            (mp->match_n_vectors != 0xFFFFFFFF)))
1151         /*
1152          * Note: this is just barely thread-safe, depends on
1153          * the main thread spinning waiting for an answer...
1154          */
1155         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1156                 ntohl (mp->new_table_index),
1157                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1158       vam->result_ready = 1;
1159     }
1160 }
1161
1162 static void vl_api_classify_add_del_table_reply_t_handler_json
1163   (vl_api_classify_add_del_table_reply_t * mp)
1164 {
1165   vat_main_t *vam = &vat_main;
1166   vat_json_node_t node;
1167
1168   vat_json_init_object (&node);
1169   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1170   vat_json_object_add_uint (&node, "new_table_index",
1171                             ntohl (mp->new_table_index));
1172   vat_json_object_add_uint (&node, "skip_n_vectors",
1173                             ntohl (mp->skip_n_vectors));
1174   vat_json_object_add_uint (&node, "match_n_vectors",
1175                             ntohl (mp->match_n_vectors));
1176
1177   vat_json_print (vam->ofp, &node);
1178   vat_json_free (&node);
1179
1180   vam->retval = ntohl (mp->retval);
1181   vam->result_ready = 1;
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   i32 retval = ntohl (mp->retval);
1189   if (vam->async_mode)
1190     {
1191       vam->async_errors += (retval < 0);
1192     }
1193   else
1194     {
1195       vam->retval = retval;
1196       if (retval == 0)
1197         errmsg ("node index %d", ntohl (mp->node_index));
1198       vam->result_ready = 1;
1199     }
1200 }
1201
1202 static void vl_api_get_node_index_reply_t_handler_json
1203   (vl_api_get_node_index_reply_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   vat_json_node_t node;
1207
1208   vat_json_init_object (&node);
1209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1210   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1211
1212   vat_json_print (vam->ofp, &node);
1213   vat_json_free (&node);
1214
1215   vam->retval = ntohl (mp->retval);
1216   vam->result_ready = 1;
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   i32 retval = ntohl (mp->retval);
1224   if (vam->async_mode)
1225     {
1226       vam->async_errors += (retval < 0);
1227     }
1228   else
1229     {
1230       vam->retval = retval;
1231       if (retval == 0)
1232         errmsg ("next node index %d", ntohl (mp->next_index));
1233       vam->result_ready = 1;
1234     }
1235 }
1236
1237 static void vl_api_get_next_index_reply_t_handler_json
1238   (vl_api_get_next_index_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   vat_json_node_t node;
1242
1243   vat_json_init_object (&node);
1244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1245   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   i32 retval = ntohl (mp->retval);
1259   if (vam->async_mode)
1260     {
1261       vam->async_errors += (retval < 0);
1262     }
1263   else
1264     {
1265       vam->retval = retval;
1266       if (retval == 0)
1267         errmsg ("next index %d", ntohl (mp->next_index));
1268       vam->result_ready = 1;
1269     }
1270 }
1271
1272 static void vl_api_add_node_next_reply_t_handler_json
1273   (vl_api_add_node_next_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   vat_json_node_t node;
1277
1278   vat_json_init_object (&node);
1279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1280   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1281
1282   vat_json_print (vam->ofp, &node);
1283   vat_json_free (&node);
1284
1285   vam->retval = ntohl (mp->retval);
1286   vam->result_ready = 1;
1287 }
1288
1289 static void vl_api_show_version_reply_t_handler
1290   (vl_api_show_version_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (retval >= 0)
1296     {
1297       char *s;
1298       char *p = (char *) &mp->program;
1299
1300       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1301       errmsg ("        program: %s\n", s);
1302       free (s);
1303
1304       p +=
1305         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1306       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1307       errmsg ("        version: %s\n", s);
1308       free (s);
1309
1310       p +=
1311         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1312       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1313       errmsg ("     build date: %s\n", s);
1314       free (s);
1315
1316       p +=
1317         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1318       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1319       errmsg ("build directory: %s\n", s);
1320       free (s);
1321     }
1322   vam->retval = retval;
1323   vam->result_ready = 1;
1324 }
1325
1326 static void vl_api_show_version_reply_t_handler_json
1327   (vl_api_show_version_reply_t * mp)
1328 {
1329   vat_main_t *vam = &vat_main;
1330   vat_json_node_t node;
1331
1332   vat_json_init_object (&node);
1333   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1334   char *p = (char *) &mp->program;
1335   vat_json_object_add_string_copy (&node, "program",
1336                                    vl_api_from_api_string ((vl_api_string_t *)
1337                                                            p));
1338   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1339   vat_json_object_add_string_copy (&node, "version",
1340                                    vl_api_from_api_string ((vl_api_string_t *)
1341                                                            p));
1342   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1343   vat_json_object_add_string_copy (&node, "build_date",
1344                                    vl_api_from_api_string ((vl_api_string_t *)
1345                                                            p));
1346   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    vl_api_from_api_string ((vl_api_string_t *)
1349                                                            p));
1350
1351   vat_json_print (vam->ofp, &node);
1352   vat_json_free (&node);
1353
1354   vam->retval = ntohl (mp->retval);
1355   vam->result_ready = 1;
1356 }
1357
1358 static void vl_api_show_threads_reply_t_handler
1359   (vl_api_show_threads_reply_t * mp)
1360 {
1361   vat_main_t *vam = &vat_main;
1362   i32 retval = ntohl (mp->retval);
1363   int i, count = 0;
1364
1365   if (retval >= 0)
1366     count = ntohl (mp->count);
1367
1368   for (i = 0; i < count; i++)
1369     print (vam->ofp,
1370            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1371            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1372            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1373            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1374            ntohl (mp->thread_data[i].cpu_socket));
1375
1376   vam->retval = retval;
1377   vam->result_ready = 1;
1378 }
1379
1380 static void vl_api_show_threads_reply_t_handler_json
1381   (vl_api_show_threads_reply_t * mp)
1382 {
1383   vat_main_t *vam = &vat_main;
1384   vat_json_node_t node;
1385   vl_api_thread_data_t *td;
1386   i32 retval = ntohl (mp->retval);
1387   int i, count = 0;
1388
1389   if (retval >= 0)
1390     count = ntohl (mp->count);
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", retval);
1394   vat_json_object_add_uint (&node, "count", count);
1395
1396   for (i = 0; i < count; i++)
1397     {
1398       td = &mp->thread_data[i];
1399       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1400       vat_json_object_add_string_copy (&node, "name", td->name);
1401       vat_json_object_add_string_copy (&node, "type", td->type);
1402       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1403       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1404       vat_json_object_add_int (&node, "core", ntohl (td->id));
1405       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1406     }
1407
1408   vat_json_print (vam->ofp, &node);
1409   vat_json_free (&node);
1410
1411   vam->retval = retval;
1412   vam->result_ready = 1;
1413 }
1414
1415 static int
1416 api_show_threads (vat_main_t * vam)
1417 {
1418   vl_api_show_threads_t *mp;
1419   int ret;
1420
1421   print (vam->ofp,
1422          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1423          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1424
1425   M (SHOW_THREADS, mp);
1426
1427   S (mp);
1428   W (ret);
1429   return ret;
1430 }
1431
1432 static void
1433 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1434 {
1435   u32 sw_if_index = ntohl (mp->sw_if_index);
1436   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1437           mp->mac_ip ? "mac/ip binding" : "address resolution",
1438           ntohl (mp->pid), format_ip4_address, mp->ip,
1439           format_vl_api_mac_address, &mp->mac, sw_if_index);
1440 }
1441
1442 static void
1443 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1444 {
1445   /* JSON output not supported */
1446 }
1447
1448 static void
1449 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1450 {
1451   u32 sw_if_index = ntohl (mp->sw_if_index);
1452   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1453           mp->mac_ip ? "mac/ip binding" : "address resolution",
1454           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1455           format_vl_api_mac_address, mp->mac, sw_if_index);
1456 }
1457
1458 static void
1459 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1460 {
1461   /* JSON output not supported */
1462 }
1463
1464 static void
1465 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1466 {
1467   u32 n_macs = ntohl (mp->n_macs);
1468   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1469           ntohl (mp->pid), mp->client_index, n_macs);
1470   int i;
1471   for (i = 0; i < n_macs; i++)
1472     {
1473       vl_api_mac_entry_t *mac = &mp->mac[i];
1474       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1475               i + 1, ntohl (mac->sw_if_index),
1476               format_ethernet_address, mac->mac_addr, mac->action);
1477       if (i == 1000)
1478         break;
1479     }
1480 }
1481
1482 static void
1483 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1484 {
1485   /* JSON output not supported */
1486 }
1487
1488 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1489 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1490
1491 /*
1492  * Special-case: build the bridge domain table, maintain
1493  * the next bd id vbl.
1494  */
1495 static void vl_api_bridge_domain_details_t_handler
1496   (vl_api_bridge_domain_details_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1500   int i;
1501
1502   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1503          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1504
1505   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1506          ntohl (mp->bd_id), mp->learn, mp->forward,
1507          mp->flood, ntohl (mp->bvi_sw_if_index),
1508          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1509
1510   if (n_sw_ifs)
1511     {
1512       vl_api_bridge_domain_sw_if_t *sw_ifs;
1513       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1514              "Interface Name");
1515
1516       sw_ifs = mp->sw_if_details;
1517       for (i = 0; i < n_sw_ifs; i++)
1518         {
1519           u8 *sw_if_name = 0;
1520           u32 sw_if_index;
1521           hash_pair_t *p;
1522
1523           sw_if_index = ntohl (sw_ifs->sw_if_index);
1524
1525           /* *INDENT-OFF* */
1526           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1527                              ({
1528                                if ((u32) p->value[0] == sw_if_index)
1529                                  {
1530                                    sw_if_name = (u8 *)(p->key);
1531                                    break;
1532                                  }
1533                              }));
1534           /* *INDENT-ON* */
1535           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1536                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1537                  "sw_if_index not found!");
1538
1539           sw_ifs++;
1540         }
1541     }
1542 }
1543
1544 static void vl_api_bridge_domain_details_t_handler_json
1545   (vl_api_bridge_domain_details_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t *node, *array = NULL;
1549   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1550
1551   if (VAT_JSON_ARRAY != vam->json_tree.type)
1552     {
1553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1554       vat_json_init_array (&vam->json_tree);
1555     }
1556   node = vat_json_array_add (&vam->json_tree);
1557
1558   vat_json_init_object (node);
1559   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1560   vat_json_object_add_uint (node, "flood", mp->flood);
1561   vat_json_object_add_uint (node, "forward", mp->forward);
1562   vat_json_object_add_uint (node, "learn", mp->learn);
1563   vat_json_object_add_uint (node, "bvi_sw_if_index",
1564                             ntohl (mp->bvi_sw_if_index));
1565   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1566   array = vat_json_object_add (node, "sw_if");
1567   vat_json_init_array (array);
1568
1569
1570
1571   if (n_sw_ifs)
1572     {
1573       vl_api_bridge_domain_sw_if_t *sw_ifs;
1574       int i;
1575
1576       sw_ifs = mp->sw_if_details;
1577       for (i = 0; i < n_sw_ifs; i++)
1578         {
1579           node = vat_json_array_add (array);
1580           vat_json_init_object (node);
1581           vat_json_object_add_uint (node, "sw_if_index",
1582                                     ntohl (sw_ifs->sw_if_index));
1583           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1584           sw_ifs++;
1585         }
1586     }
1587 }
1588
1589 static void vl_api_control_ping_reply_t_handler
1590   (vl_api_control_ping_reply_t * mp)
1591 {
1592   vat_main_t *vam = &vat_main;
1593   i32 retval = ntohl (mp->retval);
1594   if (vam->async_mode)
1595     {
1596       vam->async_errors += (retval < 0);
1597     }
1598   else
1599     {
1600       vam->retval = retval;
1601       vam->result_ready = 1;
1602     }
1603   if (vam->socket_client_main)
1604     vam->socket_client_main->control_pings_outstanding--;
1605 }
1606
1607 static void vl_api_control_ping_reply_t_handler_json
1608   (vl_api_control_ping_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612
1613   if (VAT_JSON_NONE != vam->json_tree.type)
1614     {
1615       vat_json_print (vam->ofp, &vam->json_tree);
1616       vat_json_free (&vam->json_tree);
1617       vam->json_tree.type = VAT_JSON_NONE;
1618     }
1619   else
1620     {
1621       /* just print [] */
1622       vat_json_init_array (&vam->json_tree);
1623       vat_json_print (vam->ofp, &vam->json_tree);
1624       vam->json_tree.type = VAT_JSON_NONE;
1625     }
1626
1627   vam->retval = retval;
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632   vl_api_bridge_domain_set_mac_age_reply_t_handler
1633   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1649   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2_flags_reply_t_handler_json
1681   (vl_api_l2_flags_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1689                             ntohl (mp->resulting_feature_bitmap));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_bridge_flags_reply_t_handler
1699   (vl_api_bridge_flags_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->result_ready = 1;
1711     }
1712 }
1713
1714 static void vl_api_bridge_flags_reply_t_handler_json
1715   (vl_api_bridge_flags_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1723                             ntohl (mp->resulting_feature_bitmap));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732 static void
1733 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   i32 retval = ntohl (mp->retval);
1737   if (vam->async_mode)
1738     {
1739       vam->async_errors += (retval < 0);
1740     }
1741   else
1742     {
1743       vam->retval = retval;
1744       vam->sw_if_index = ntohl (mp->sw_if_index);
1745       vam->result_ready = 1;
1746     }
1747
1748 }
1749
1750 static void vl_api_tap_create_v2_reply_t_handler_json
1751   (vl_api_tap_create_v2_reply_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   vat_json_node_t node;
1755
1756   vat_json_init_object (&node);
1757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1758   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765
1766 }
1767
1768 static void
1769 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->result_ready = 1;
1781     }
1782 }
1783
1784 static void vl_api_tap_delete_v2_reply_t_handler_json
1785   (vl_api_tap_delete_v2_reply_t * mp)
1786 {
1787   vat_main_t *vam = &vat_main;
1788   vat_json_node_t node;
1789
1790   vat_json_init_object (&node);
1791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void
1801 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1802                                           mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   i32 retval = ntohl (mp->retval);
1806   if (vam->async_mode)
1807     {
1808       vam->async_errors += (retval < 0);
1809     }
1810   else
1811     {
1812       vam->retval = retval;
1813       vam->sw_if_index = ntohl (mp->sw_if_index);
1814       vam->result_ready = 1;
1815     }
1816 }
1817
1818 static void vl_api_virtio_pci_create_reply_t_handler_json
1819   (vl_api_virtio_pci_create_reply_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822   vat_json_node_t node;
1823
1824   vat_json_init_object (&node);
1825   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1826   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1827
1828   vat_json_print (vam->ofp, &node);
1829   vat_json_free (&node);
1830
1831   vam->retval = ntohl (mp->retval);
1832   vam->result_ready = 1;
1833
1834 }
1835
1836 static void
1837 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1838                                           mp)
1839 {
1840   vat_main_t *vam = &vat_main;
1841   i32 retval = ntohl (mp->retval);
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->result_ready = 1;
1850     }
1851 }
1852
1853 static void vl_api_virtio_pci_delete_reply_t_handler_json
1854   (vl_api_virtio_pci_delete_reply_t * mp)
1855 {
1856   vat_main_t *vam = &vat_main;
1857   vat_json_node_t node;
1858
1859   vat_json_init_object (&node);
1860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1861
1862   vat_json_print (vam->ofp, &node);
1863   vat_json_free (&node);
1864
1865   vam->retval = ntohl (mp->retval);
1866   vam->result_ready = 1;
1867 }
1868
1869 static void
1870 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1871 {
1872   vat_main_t *vam = &vat_main;
1873   i32 retval = ntohl (mp->retval);
1874
1875   if (vam->async_mode)
1876     {
1877       vam->async_errors += (retval < 0);
1878     }
1879   else
1880     {
1881       vam->retval = retval;
1882       vam->sw_if_index = ntohl (mp->sw_if_index);
1883       vam->result_ready = 1;
1884     }
1885 }
1886
1887 static void vl_api_bond_create_reply_t_handler_json
1888   (vl_api_bond_create_reply_t * mp)
1889 {
1890   vat_main_t *vam = &vat_main;
1891   vat_json_node_t node;
1892
1893   vat_json_init_object (&node);
1894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1895   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_delete_reply_t_handler_json
1922   (vl_api_bond_delete_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1939 {
1940   vat_main_t *vam = &vat_main;
1941   i32 retval = ntohl (mp->retval);
1942
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_bond_enslave_reply_t_handler_json
1955   (vl_api_bond_enslave_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962
1963   vat_json_print (vam->ofp, &node);
1964   vat_json_free (&node);
1965
1966   vam->retval = ntohl (mp->retval);
1967   vam->result_ready = 1;
1968 }
1969
1970 static void
1971 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1972                                           mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976
1977   if (vam->async_mode)
1978     {
1979       vam->async_errors += (retval < 0);
1980     }
1981   else
1982     {
1983       vam->retval = retval;
1984       vam->result_ready = 1;
1985     }
1986 }
1987
1988 static void vl_api_bond_detach_slave_reply_t_handler_json
1989   (vl_api_bond_detach_slave_reply_t * mp)
1990 {
1991   vat_main_t *vam = &vat_main;
1992   vat_json_node_t node;
1993
1994   vat_json_init_object (&node);
1995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1996
1997   vat_json_print (vam->ofp, &node);
1998   vat_json_free (&node);
1999
2000   vam->retval = ntohl (mp->retval);
2001   vam->result_ready = 1;
2002 }
2003
2004 static void vl_api_sw_interface_bond_details_t_handler
2005   (vl_api_sw_interface_bond_details_t * mp)
2006 {
2007   vat_main_t *vam = &vat_main;
2008
2009   print (vam->ofp,
2010          "%-16s %-12d %-12U %-13U %-14u %-14u",
2011          mp->interface_name, ntohl (mp->sw_if_index),
2012          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2013          ntohl (mp->active_slaves), ntohl (mp->slaves));
2014 }
2015
2016 static void vl_api_sw_interface_bond_details_t_handler_json
2017   (vl_api_sw_interface_bond_details_t * mp)
2018 {
2019   vat_main_t *vam = &vat_main;
2020   vat_json_node_t *node = NULL;
2021
2022   if (VAT_JSON_ARRAY != vam->json_tree.type)
2023     {
2024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2025       vat_json_init_array (&vam->json_tree);
2026     }
2027   node = vat_json_array_add (&vam->json_tree);
2028
2029   vat_json_init_object (node);
2030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2031   vat_json_object_add_string_copy (node, "interface_name",
2032                                    mp->interface_name);
2033   vat_json_object_add_uint (node, "mode", mp->mode);
2034   vat_json_object_add_uint (node, "load_balance", mp->lb);
2035   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2036   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2037 }
2038
2039 static int
2040 api_sw_interface_bond_dump (vat_main_t * vam)
2041 {
2042   vl_api_sw_interface_bond_dump_t *mp;
2043   vl_api_control_ping_t *mp_ping;
2044   int ret;
2045
2046   print (vam->ofp,
2047          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2048          "interface name", "sw_if_index", "mode", "load balance",
2049          "active slaves", "slaves");
2050
2051   /* Get list of bond interfaces */
2052   M (SW_INTERFACE_BOND_DUMP, mp);
2053   S (mp);
2054
2055   /* Use a control ping for synchronization */
2056   MPING (CONTROL_PING, mp_ping);
2057   S (mp_ping);
2058
2059   W (ret);
2060   return ret;
2061 }
2062
2063 static void vl_api_sw_interface_slave_details_t_handler
2064   (vl_api_sw_interface_slave_details_t * mp)
2065 {
2066   vat_main_t *vam = &vat_main;
2067
2068   print (vam->ofp,
2069          "%-25s %-12d %-12d %d", mp->interface_name,
2070          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2071 }
2072
2073 static void vl_api_sw_interface_slave_details_t_handler_json
2074   (vl_api_sw_interface_slave_details_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077   vat_json_node_t *node = NULL;
2078
2079   if (VAT_JSON_ARRAY != vam->json_tree.type)
2080     {
2081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2082       vat_json_init_array (&vam->json_tree);
2083     }
2084   node = vat_json_array_add (&vam->json_tree);
2085
2086   vat_json_init_object (node);
2087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2088   vat_json_object_add_string_copy (node, "interface_name",
2089                                    mp->interface_name);
2090   vat_json_object_add_uint (node, "passive", mp->is_passive);
2091   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2092 }
2093
2094 static int
2095 api_sw_interface_slave_dump (vat_main_t * vam)
2096 {
2097   unformat_input_t *i = vam->input;
2098   vl_api_sw_interface_slave_dump_t *mp;
2099   vl_api_control_ping_t *mp_ping;
2100   u32 sw_if_index = ~0;
2101   u8 sw_if_index_set = 0;
2102   int ret;
2103
2104   /* Parse args required to build the message */
2105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2106     {
2107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2108         sw_if_index_set = 1;
2109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2110         sw_if_index_set = 1;
2111       else
2112         break;
2113     }
2114
2115   if (sw_if_index_set == 0)
2116     {
2117       errmsg ("missing vpp interface name. ");
2118       return -99;
2119     }
2120
2121   print (vam->ofp,
2122          "\n%-25s %-12s %-12s %s",
2123          "slave interface name", "sw_if_index", "passive", "long_timeout");
2124
2125   /* Get list of bond interfaces */
2126   M (SW_INTERFACE_SLAVE_DUMP, mp);
2127   mp->sw_if_index = ntohl (sw_if_index);
2128   S (mp);
2129
2130   /* Use a control ping for synchronization */
2131   MPING (CONTROL_PING, mp_ping);
2132   S (mp_ping);
2133
2134   W (ret);
2135   return ret;
2136 }
2137
2138 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2139   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2140 {
2141   vat_main_t *vam = &vat_main;
2142   i32 retval = ntohl (mp->retval);
2143   if (vam->async_mode)
2144     {
2145       vam->async_errors += (retval < 0);
2146     }
2147   else
2148     {
2149       vam->retval = retval;
2150       vam->sw_if_index = ntohl (mp->sw_if_index);
2151       vam->result_ready = 1;
2152     }
2153   vam->regenerate_interface_table = 1;
2154 }
2155
2156 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2157   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2158 {
2159   vat_main_t *vam = &vat_main;
2160   vat_json_node_t node;
2161
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2165                             ntohl (mp->sw_if_index));
2166
2167   vat_json_print (vam->ofp, &node);
2168   vat_json_free (&node);
2169
2170   vam->retval = ntohl (mp->retval);
2171   vam->result_ready = 1;
2172 }
2173
2174 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2175   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2176 {
2177   vat_main_t *vam = &vat_main;
2178   i32 retval = ntohl (mp->retval);
2179   if (vam->async_mode)
2180     {
2181       vam->async_errors += (retval < 0);
2182     }
2183   else
2184     {
2185       vam->retval = retval;
2186       vam->sw_if_index = ntohl (mp->sw_if_index);
2187       vam->result_ready = 1;
2188     }
2189 }
2190
2191 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2192   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2193 {
2194   vat_main_t *vam = &vat_main;
2195   vat_json_node_t node;
2196
2197   vat_json_init_object (&node);
2198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2199   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2200
2201   vat_json_print (vam->ofp, &node);
2202   vat_json_free (&node);
2203
2204   vam->retval = ntohl (mp->retval);
2205   vam->result_ready = 1;
2206 }
2207
2208 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2209   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   i32 retval = ntohl (mp->retval);
2213   if (vam->async_mode)
2214     {
2215       vam->async_errors += (retval < 0);
2216     }
2217   else
2218     {
2219       vam->retval = retval;
2220       vam->result_ready = 1;
2221     }
2222 }
2223
2224 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2225   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2226 {
2227   vat_main_t *vam = &vat_main;
2228   vat_json_node_t node;
2229
2230   vat_json_init_object (&node);
2231   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2232   vat_json_object_add_uint (&node, "fwd_entry_index",
2233                             clib_net_to_host_u32 (mp->fwd_entry_index));
2234
2235   vat_json_print (vam->ofp, &node);
2236   vat_json_free (&node);
2237
2238   vam->retval = ntohl (mp->retval);
2239   vam->result_ready = 1;
2240 }
2241
2242 u8 *
2243 format_lisp_transport_protocol (u8 * s, va_list * args)
2244 {
2245   u32 proto = va_arg (*args, u32);
2246
2247   switch (proto)
2248     {
2249     case 1:
2250       return format (s, "udp");
2251     case 2:
2252       return format (s, "api");
2253     default:
2254       return 0;
2255     }
2256   return 0;
2257 }
2258
2259 static void vl_api_one_get_transport_protocol_reply_t_handler
2260   (vl_api_one_get_transport_protocol_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   i32 retval = ntohl (mp->retval);
2264   if (vam->async_mode)
2265     {
2266       vam->async_errors += (retval < 0);
2267     }
2268   else
2269     {
2270       u32 proto = mp->protocol;
2271       print (vam->ofp, "Transport protocol: %U",
2272              format_lisp_transport_protocol, proto);
2273       vam->retval = retval;
2274       vam->result_ready = 1;
2275     }
2276 }
2277
2278 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2279   (vl_api_one_get_transport_protocol_reply_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   vat_json_node_t node;
2283   u8 *s;
2284
2285   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2286   vec_add1 (s, 0);
2287
2288   vat_json_init_object (&node);
2289   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2290   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2291
2292   vec_free (s);
2293   vat_json_print (vam->ofp, &node);
2294   vat_json_free (&node);
2295
2296   vam->retval = ntohl (mp->retval);
2297   vam->result_ready = 1;
2298 }
2299
2300 static void vl_api_one_add_del_locator_set_reply_t_handler
2301   (vl_api_one_add_del_locator_set_reply_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   i32 retval = ntohl (mp->retval);
2305   if (vam->async_mode)
2306     {
2307       vam->async_errors += (retval < 0);
2308     }
2309   else
2310     {
2311       vam->retval = retval;
2312       vam->result_ready = 1;
2313     }
2314 }
2315
2316 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2317   (vl_api_one_add_del_locator_set_reply_t * mp)
2318 {
2319   vat_main_t *vam = &vat_main;
2320   vat_json_node_t node;
2321
2322   vat_json_init_object (&node);
2323   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2324   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2325
2326   vat_json_print (vam->ofp, &node);
2327   vat_json_free (&node);
2328
2329   vam->retval = ntohl (mp->retval);
2330   vam->result_ready = 1;
2331 }
2332
2333 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2334   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2335 {
2336   vat_main_t *vam = &vat_main;
2337   i32 retval = ntohl (mp->retval);
2338   if (vam->async_mode)
2339     {
2340       vam->async_errors += (retval < 0);
2341     }
2342   else
2343     {
2344       vam->retval = retval;
2345       vam->sw_if_index = ntohl (mp->sw_if_index);
2346       vam->result_ready = 1;
2347     }
2348   vam->regenerate_interface_table = 1;
2349 }
2350
2351 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2352   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   vat_json_node_t node;
2356
2357   vat_json_init_object (&node);
2358   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2359   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2360
2361   vat_json_print (vam->ofp, &node);
2362   vat_json_free (&node);
2363
2364   vam->retval = ntohl (mp->retval);
2365   vam->result_ready = 1;
2366 }
2367
2368 static void vl_api_vxlan_offload_rx_reply_t_handler
2369   (vl_api_vxlan_offload_rx_reply_t * mp)
2370 {
2371   vat_main_t *vam = &vat_main;
2372   i32 retval = ntohl (mp->retval);
2373   if (vam->async_mode)
2374     {
2375       vam->async_errors += (retval < 0);
2376     }
2377   else
2378     {
2379       vam->retval = retval;
2380       vam->result_ready = 1;
2381     }
2382 }
2383
2384 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2385   (vl_api_vxlan_offload_rx_reply_t * mp)
2386 {
2387   vat_main_t *vam = &vat_main;
2388   vat_json_node_t node;
2389
2390   vat_json_init_object (&node);
2391   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2392
2393   vat_json_print (vam->ofp, &node);
2394   vat_json_free (&node);
2395
2396   vam->retval = ntohl (mp->retval);
2397   vam->result_ready = 1;
2398 }
2399
2400 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2401   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2402 {
2403   vat_main_t *vam = &vat_main;
2404   i32 retval = ntohl (mp->retval);
2405   if (vam->async_mode)
2406     {
2407       vam->async_errors += (retval < 0);
2408     }
2409   else
2410     {
2411       vam->retval = retval;
2412       vam->sw_if_index = ntohl (mp->sw_if_index);
2413       vam->result_ready = 1;
2414     }
2415 }
2416
2417 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2418   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   vat_json_node_t node;
2422
2423   vat_json_init_object (&node);
2424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2426
2427   vat_json_print (vam->ofp, &node);
2428   vat_json_free (&node);
2429
2430   vam->retval = ntohl (mp->retval);
2431   vam->result_ready = 1;
2432 }
2433
2434 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2435   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438   i32 retval = ntohl (mp->retval);
2439   if (vam->async_mode)
2440     {
2441       vam->async_errors += (retval < 0);
2442     }
2443   else
2444     {
2445       vam->retval = retval;
2446       vam->sw_if_index = ntohl (mp->sw_if_index);
2447       vam->result_ready = 1;
2448     }
2449   vam->regenerate_interface_table = 1;
2450 }
2451
2452 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2453   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2454 {
2455   vat_main_t *vam = &vat_main;
2456   vat_json_node_t node;
2457
2458   vat_json_init_object (&node);
2459   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2460   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2461
2462   vat_json_print (vam->ofp, &node);
2463   vat_json_free (&node);
2464
2465   vam->retval = ntohl (mp->retval);
2466   vam->result_ready = 1;
2467 }
2468
2469 static void vl_api_gre_tunnel_add_del_reply_t_handler
2470   (vl_api_gre_tunnel_add_del_reply_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   i32 retval = ntohl (mp->retval);
2474   if (vam->async_mode)
2475     {
2476       vam->async_errors += (retval < 0);
2477     }
2478   else
2479     {
2480       vam->retval = retval;
2481       vam->sw_if_index = ntohl (mp->sw_if_index);
2482       vam->result_ready = 1;
2483     }
2484 }
2485
2486 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2487   (vl_api_gre_tunnel_add_del_reply_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   vat_json_node_t node;
2491
2492   vat_json_init_object (&node);
2493   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2494   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2495
2496   vat_json_print (vam->ofp, &node);
2497   vat_json_free (&node);
2498
2499   vam->retval = ntohl (mp->retval);
2500   vam->result_ready = 1;
2501 }
2502
2503 static void vl_api_create_vhost_user_if_reply_t_handler
2504   (vl_api_create_vhost_user_if_reply_t * mp)
2505 {
2506   vat_main_t *vam = &vat_main;
2507   i32 retval = ntohl (mp->retval);
2508   if (vam->async_mode)
2509     {
2510       vam->async_errors += (retval < 0);
2511     }
2512   else
2513     {
2514       vam->retval = retval;
2515       vam->sw_if_index = ntohl (mp->sw_if_index);
2516       vam->result_ready = 1;
2517     }
2518   vam->regenerate_interface_table = 1;
2519 }
2520
2521 static void vl_api_create_vhost_user_if_reply_t_handler_json
2522   (vl_api_create_vhost_user_if_reply_t * mp)
2523 {
2524   vat_main_t *vam = &vat_main;
2525   vat_json_node_t node;
2526
2527   vat_json_init_object (&node);
2528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2529   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2530
2531   vat_json_print (vam->ofp, &node);
2532   vat_json_free (&node);
2533
2534   vam->retval = ntohl (mp->retval);
2535   vam->result_ready = 1;
2536 }
2537
2538 static void vl_api_dns_resolve_name_reply_t_handler
2539   (vl_api_dns_resolve_name_reply_t * mp)
2540 {
2541   vat_main_t *vam = &vat_main;
2542   i32 retval = ntohl (mp->retval);
2543   if (vam->async_mode)
2544     {
2545       vam->async_errors += (retval < 0);
2546     }
2547   else
2548     {
2549       vam->retval = retval;
2550       vam->result_ready = 1;
2551
2552       if (retval == 0)
2553         {
2554           if (mp->ip4_set)
2555             clib_warning ("ip4 address %U", format_ip4_address,
2556                           (ip4_address_t *) mp->ip4_address);
2557           if (mp->ip6_set)
2558             clib_warning ("ip6 address %U", format_ip6_address,
2559                           (ip6_address_t *) mp->ip6_address);
2560         }
2561       else
2562         clib_warning ("retval %d", retval);
2563     }
2564 }
2565
2566 static void vl_api_dns_resolve_name_reply_t_handler_json
2567   (vl_api_dns_resolve_name_reply_t * mp)
2568 {
2569   clib_warning ("not implemented");
2570 }
2571
2572 static void vl_api_dns_resolve_ip_reply_t_handler
2573   (vl_api_dns_resolve_ip_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   i32 retval = ntohl (mp->retval);
2577   if (vam->async_mode)
2578     {
2579       vam->async_errors += (retval < 0);
2580     }
2581   else
2582     {
2583       vam->retval = retval;
2584       vam->result_ready = 1;
2585
2586       if (retval == 0)
2587         {
2588           clib_warning ("canonical name %s", mp->name);
2589         }
2590       else
2591         clib_warning ("retval %d", retval);
2592     }
2593 }
2594
2595 static void vl_api_dns_resolve_ip_reply_t_handler_json
2596   (vl_api_dns_resolve_ip_reply_t * mp)
2597 {
2598   clib_warning ("not implemented");
2599 }
2600
2601
2602 static void vl_api_ip_address_details_t_handler
2603   (vl_api_ip_address_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   static ip_address_details_t empty_ip_address_details = { {0} };
2607   ip_address_details_t *address = NULL;
2608   ip_details_t *current_ip_details = NULL;
2609   ip_details_t *details = NULL;
2610
2611   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2612
2613   if (!details || vam->current_sw_if_index >= vec_len (details)
2614       || !details[vam->current_sw_if_index].present)
2615     {
2616       errmsg ("ip address details arrived but not stored");
2617       errmsg ("ip_dump should be called first");
2618       return;
2619     }
2620
2621   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2622
2623 #define addresses (current_ip_details->addr)
2624
2625   vec_validate_init_empty (addresses, vec_len (addresses),
2626                            empty_ip_address_details);
2627
2628   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2629
2630   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2631   address->prefix_length = mp->prefix_length;
2632 #undef addresses
2633 }
2634
2635 static void vl_api_ip_address_details_t_handler_json
2636   (vl_api_ip_address_details_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   vat_json_node_t *node = NULL;
2640   struct in6_addr ip6;
2641   struct in_addr ip4;
2642
2643   if (VAT_JSON_ARRAY != vam->json_tree.type)
2644     {
2645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2646       vat_json_init_array (&vam->json_tree);
2647     }
2648   node = vat_json_array_add (&vam->json_tree);
2649
2650   vat_json_init_object (node);
2651   if (vam->is_ipv6)
2652     {
2653       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2654       vat_json_object_add_ip6 (node, "ip", ip6);
2655     }
2656   else
2657     {
2658       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2659       vat_json_object_add_ip4 (node, "ip", ip4);
2660     }
2661   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2662 }
2663
2664 static void
2665 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   static ip_details_t empty_ip_details = { 0 };
2669   ip_details_t *ip = NULL;
2670   u32 sw_if_index = ~0;
2671
2672   sw_if_index = ntohl (mp->sw_if_index);
2673
2674   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2675                            sw_if_index, empty_ip_details);
2676
2677   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2678                          sw_if_index);
2679
2680   ip->present = 1;
2681 }
2682
2683 static void
2684 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2685 {
2686   vat_main_t *vam = &vat_main;
2687
2688   if (VAT_JSON_ARRAY != vam->json_tree.type)
2689     {
2690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2691       vat_json_init_array (&vam->json_tree);
2692     }
2693   vat_json_array_add_uint (&vam->json_tree,
2694                            clib_net_to_host_u32 (mp->sw_if_index));
2695 }
2696
2697 static void
2698 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2699 {
2700   u8 *s, i;
2701
2702   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2703               "host_mac %U router_addr %U",
2704               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2705               mp->lease.hostname,
2706               format_ip4_address, mp->lease.host_address,
2707               format_ethernet_address, mp->lease.host_mac,
2708               format_ip4_address, mp->lease.router_address);
2709
2710   for (i = 0; i < mp->lease.count; i++)
2711     s =
2712       format (s, " domain_server_addr %U", format_ip4_address,
2713               mp->lease.domain_server[i].address);
2714
2715   errmsg ((char *) s);
2716   vec_free (s);
2717 }
2718
2719 static void vl_api_dhcp_compl_event_t_handler_json
2720   (vl_api_dhcp_compl_event_t * mp)
2721 {
2722   /* JSON output not supported */
2723 }
2724
2725 static void vl_api_get_first_msg_id_reply_t_handler
2726   (vl_api_get_first_msg_id_reply_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   i32 retval = ntohl (mp->retval);
2730
2731   if (vam->async_mode)
2732     {
2733       vam->async_errors += (retval < 0);
2734     }
2735   else
2736     {
2737       vam->retval = retval;
2738       vam->result_ready = 1;
2739     }
2740   if (retval >= 0)
2741     {
2742       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2743     }
2744 }
2745
2746 static void vl_api_get_first_msg_id_reply_t_handler_json
2747   (vl_api_get_first_msg_id_reply_t * mp)
2748 {
2749   vat_main_t *vam = &vat_main;
2750   vat_json_node_t node;
2751
2752   vat_json_init_object (&node);
2753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2754   vat_json_object_add_uint (&node, "first_msg_id",
2755                             (uint) ntohs (mp->first_msg_id));
2756
2757   vat_json_print (vam->ofp, &node);
2758   vat_json_free (&node);
2759
2760   vam->retval = ntohl (mp->retval);
2761   vam->result_ready = 1;
2762 }
2763
2764 static void vl_api_get_node_graph_reply_t_handler
2765   (vl_api_get_node_graph_reply_t * mp)
2766 {
2767   vat_main_t *vam = &vat_main;
2768   api_main_t *am = &api_main;
2769   i32 retval = ntohl (mp->retval);
2770   u8 *pvt_copy, *reply;
2771   void *oldheap;
2772   vlib_node_t *node;
2773   int i;
2774
2775   if (vam->async_mode)
2776     {
2777       vam->async_errors += (retval < 0);
2778     }
2779   else
2780     {
2781       vam->retval = retval;
2782       vam->result_ready = 1;
2783     }
2784
2785   /* "Should never happen..." */
2786   if (retval != 0)
2787     return;
2788
2789   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2790   pvt_copy = vec_dup (reply);
2791
2792   /* Toss the shared-memory original... */
2793   pthread_mutex_lock (&am->vlib_rp->mutex);
2794   oldheap = svm_push_data_heap (am->vlib_rp);
2795
2796   vec_free (reply);
2797
2798   svm_pop_heap (oldheap);
2799   pthread_mutex_unlock (&am->vlib_rp->mutex);
2800
2801   if (vam->graph_nodes)
2802     {
2803       hash_free (vam->graph_node_index_by_name);
2804
2805       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2806         {
2807           node = vam->graph_nodes[0][i];
2808           vec_free (node->name);
2809           vec_free (node->next_nodes);
2810           vec_free (node);
2811         }
2812       vec_free (vam->graph_nodes[0]);
2813       vec_free (vam->graph_nodes);
2814     }
2815
2816   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2817   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2818   vec_free (pvt_copy);
2819
2820   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2821     {
2822       node = vam->graph_nodes[0][i];
2823       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2824     }
2825 }
2826
2827 static void vl_api_get_node_graph_reply_t_handler_json
2828   (vl_api_get_node_graph_reply_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   api_main_t *am = &api_main;
2832   void *oldheap;
2833   vat_json_node_t node;
2834   u8 *reply;
2835
2836   /* $$$$ make this real? */
2837   vat_json_init_object (&node);
2838   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2839   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2840
2841   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2842
2843   /* Toss the shared-memory original... */
2844   pthread_mutex_lock (&am->vlib_rp->mutex);
2845   oldheap = svm_push_data_heap (am->vlib_rp);
2846
2847   vec_free (reply);
2848
2849   svm_pop_heap (oldheap);
2850   pthread_mutex_unlock (&am->vlib_rp->mutex);
2851
2852   vat_json_print (vam->ofp, &node);
2853   vat_json_free (&node);
2854
2855   vam->retval = ntohl (mp->retval);
2856   vam->result_ready = 1;
2857 }
2858
2859 static void
2860 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   u8 *s = 0;
2864
2865   if (mp->local)
2866     {
2867       s = format (s, "%=16d%=16d%=16d",
2868                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2869     }
2870   else
2871     {
2872       s = format (s, "%=16U%=16d%=16d",
2873                   mp->is_ipv6 ? format_ip6_address :
2874                   format_ip4_address,
2875                   mp->ip_address, mp->priority, mp->weight);
2876     }
2877
2878   print (vam->ofp, "%v", s);
2879   vec_free (s);
2880 }
2881
2882 static void
2883 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886   vat_json_node_t *node = NULL;
2887   struct in6_addr ip6;
2888   struct in_addr ip4;
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896   vat_json_init_object (node);
2897
2898   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2899   vat_json_object_add_uint (node, "priority", mp->priority);
2900   vat_json_object_add_uint (node, "weight", mp->weight);
2901
2902   if (mp->local)
2903     vat_json_object_add_uint (node, "sw_if_index",
2904                               clib_net_to_host_u32 (mp->sw_if_index));
2905   else
2906     {
2907       if (mp->is_ipv6)
2908         {
2909           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2910           vat_json_object_add_ip6 (node, "address", ip6);
2911         }
2912       else
2913         {
2914           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2915           vat_json_object_add_ip4 (node, "address", ip4);
2916         }
2917     }
2918 }
2919
2920 static void
2921 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2922                                           mp)
2923 {
2924   vat_main_t *vam = &vat_main;
2925   u8 *ls_name = 0;
2926
2927   ls_name = format (0, "%s", mp->ls_name);
2928
2929   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2930          ls_name);
2931   vec_free (ls_name);
2932 }
2933
2934 static void
2935   vl_api_one_locator_set_details_t_handler_json
2936   (vl_api_one_locator_set_details_t * mp)
2937 {
2938   vat_main_t *vam = &vat_main;
2939   vat_json_node_t *node = 0;
2940   u8 *ls_name = 0;
2941
2942   ls_name = format (0, "%s", mp->ls_name);
2943   vec_add1 (ls_name, 0);
2944
2945   if (VAT_JSON_ARRAY != vam->json_tree.type)
2946     {
2947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2948       vat_json_init_array (&vam->json_tree);
2949     }
2950   node = vat_json_array_add (&vam->json_tree);
2951
2952   vat_json_init_object (node);
2953   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2954   vat_json_object_add_uint (node, "ls_index",
2955                             clib_net_to_host_u32 (mp->ls_index));
2956   vec_free (ls_name);
2957 }
2958
2959 typedef struct
2960 {
2961   u32 spi;
2962   u8 si;
2963 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2964
2965 uword
2966 unformat_nsh_address (unformat_input_t * input, va_list * args)
2967 {
2968   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2969   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2970 }
2971
2972 u8 *
2973 format_nsh_address_vat (u8 * s, va_list * args)
2974 {
2975   nsh_t *a = va_arg (*args, nsh_t *);
2976   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2977 }
2978
2979 static u8 *
2980 format_lisp_flat_eid (u8 * s, va_list * args)
2981 {
2982   u32 type = va_arg (*args, u32);
2983   u8 *eid = va_arg (*args, u8 *);
2984   u32 eid_len = va_arg (*args, u32);
2985
2986   switch (type)
2987     {
2988     case 0:
2989       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2990     case 1:
2991       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2992     case 2:
2993       return format (s, "%U", format_ethernet_address, eid);
2994     case 3:
2995       return format (s, "%U", format_nsh_address_vat, eid);
2996     }
2997   return 0;
2998 }
2999
3000 static u8 *
3001 format_lisp_eid_vat (u8 * s, va_list * args)
3002 {
3003   u32 type = va_arg (*args, u32);
3004   u8 *eid = va_arg (*args, u8 *);
3005   u32 eid_len = va_arg (*args, u32);
3006   u8 *seid = va_arg (*args, u8 *);
3007   u32 seid_len = va_arg (*args, u32);
3008   u32 is_src_dst = va_arg (*args, u32);
3009
3010   if (is_src_dst)
3011     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3012
3013   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3014
3015   return s;
3016 }
3017
3018 static void
3019 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3020 {
3021   vat_main_t *vam = &vat_main;
3022   u8 *s = 0, *eid = 0;
3023
3024   if (~0 == mp->locator_set_index)
3025     s = format (0, "action: %d", mp->action);
3026   else
3027     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3028
3029   eid = format (0, "%U", format_lisp_eid_vat,
3030                 mp->eid_type,
3031                 mp->eid,
3032                 mp->eid_prefix_len,
3033                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3034   vec_add1 (eid, 0);
3035
3036   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3037          clib_net_to_host_u32 (mp->vni),
3038          eid,
3039          mp->is_local ? "local" : "remote",
3040          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3041          clib_net_to_host_u16 (mp->key_id), mp->key);
3042
3043   vec_free (s);
3044   vec_free (eid);
3045 }
3046
3047 static void
3048 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3049                                              * mp)
3050 {
3051   vat_main_t *vam = &vat_main;
3052   vat_json_node_t *node = 0;
3053   u8 *eid = 0;
3054
3055   if (VAT_JSON_ARRAY != vam->json_tree.type)
3056     {
3057       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3058       vat_json_init_array (&vam->json_tree);
3059     }
3060   node = vat_json_array_add (&vam->json_tree);
3061
3062   vat_json_init_object (node);
3063   if (~0 == mp->locator_set_index)
3064     vat_json_object_add_uint (node, "action", mp->action);
3065   else
3066     vat_json_object_add_uint (node, "locator_set_index",
3067                               clib_net_to_host_u32 (mp->locator_set_index));
3068
3069   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3070   if (mp->eid_type == 3)
3071     {
3072       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3073       vat_json_init_object (nsh_json);
3074       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3075       vat_json_object_add_uint (nsh_json, "spi",
3076                                 clib_net_to_host_u32 (nsh->spi));
3077       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3078     }
3079   else
3080     {
3081       eid = format (0, "%U", format_lisp_eid_vat,
3082                     mp->eid_type,
3083                     mp->eid,
3084                     mp->eid_prefix_len,
3085                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3086       vec_add1 (eid, 0);
3087       vat_json_object_add_string_copy (node, "eid", eid);
3088       vec_free (eid);
3089     }
3090   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3091   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3092   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3093
3094   if (mp->key_id)
3095     {
3096       vat_json_object_add_uint (node, "key_id",
3097                                 clib_net_to_host_u16 (mp->key_id));
3098       vat_json_object_add_string_copy (node, "key", mp->key);
3099     }
3100 }
3101
3102 static void
3103 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3104 {
3105   vat_main_t *vam = &vat_main;
3106   u8 *seid = 0, *deid = 0;
3107   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3108
3109   deid = format (0, "%U", format_lisp_eid_vat,
3110                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3111
3112   seid = format (0, "%U", format_lisp_eid_vat,
3113                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3114
3115   vec_add1 (deid, 0);
3116   vec_add1 (seid, 0);
3117
3118   if (mp->is_ip4)
3119     format_ip_address_fcn = format_ip4_address;
3120   else
3121     format_ip_address_fcn = format_ip6_address;
3122
3123
3124   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3125          clib_net_to_host_u32 (mp->vni),
3126          seid, deid,
3127          format_ip_address_fcn, mp->lloc,
3128          format_ip_address_fcn, mp->rloc,
3129          clib_net_to_host_u32 (mp->pkt_count),
3130          clib_net_to_host_u32 (mp->bytes));
3131
3132   vec_free (deid);
3133   vec_free (seid);
3134 }
3135
3136 static void
3137 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3138 {
3139   struct in6_addr ip6;
3140   struct in_addr ip4;
3141   vat_main_t *vam = &vat_main;
3142   vat_json_node_t *node = 0;
3143   u8 *deid = 0, *seid = 0;
3144
3145   if (VAT_JSON_ARRAY != vam->json_tree.type)
3146     {
3147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3148       vat_json_init_array (&vam->json_tree);
3149     }
3150   node = vat_json_array_add (&vam->json_tree);
3151
3152   vat_json_init_object (node);
3153   deid = format (0, "%U", format_lisp_eid_vat,
3154                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3155
3156   seid = format (0, "%U", format_lisp_eid_vat,
3157                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3158
3159   vec_add1 (deid, 0);
3160   vec_add1 (seid, 0);
3161
3162   vat_json_object_add_string_copy (node, "seid", seid);
3163   vat_json_object_add_string_copy (node, "deid", deid);
3164   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3165
3166   if (mp->is_ip4)
3167     {
3168       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3169       vat_json_object_add_ip4 (node, "lloc", ip4);
3170       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3171       vat_json_object_add_ip4 (node, "rloc", ip4);
3172     }
3173   else
3174     {
3175       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3176       vat_json_object_add_ip6 (node, "lloc", ip6);
3177       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3178       vat_json_object_add_ip6 (node, "rloc", ip6);
3179     }
3180   vat_json_object_add_uint (node, "pkt_count",
3181                             clib_net_to_host_u32 (mp->pkt_count));
3182   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3183
3184   vec_free (deid);
3185   vec_free (seid);
3186 }
3187
3188 static void
3189   vl_api_one_eid_table_map_details_t_handler
3190   (vl_api_one_eid_table_map_details_t * mp)
3191 {
3192   vat_main_t *vam = &vat_main;
3193
3194   u8 *line = format (0, "%=10d%=10d",
3195                      clib_net_to_host_u32 (mp->vni),
3196                      clib_net_to_host_u32 (mp->dp_table));
3197   print (vam->ofp, "%v", line);
3198   vec_free (line);
3199 }
3200
3201 static void
3202   vl_api_one_eid_table_map_details_t_handler_json
3203   (vl_api_one_eid_table_map_details_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   vat_json_node_t *node = NULL;
3207
3208   if (VAT_JSON_ARRAY != vam->json_tree.type)
3209     {
3210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3211       vat_json_init_array (&vam->json_tree);
3212     }
3213   node = vat_json_array_add (&vam->json_tree);
3214   vat_json_init_object (node);
3215   vat_json_object_add_uint (node, "dp_table",
3216                             clib_net_to_host_u32 (mp->dp_table));
3217   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3218 }
3219
3220 static void
3221   vl_api_one_eid_table_vni_details_t_handler
3222   (vl_api_one_eid_table_vni_details_t * mp)
3223 {
3224   vat_main_t *vam = &vat_main;
3225
3226   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3227   print (vam->ofp, "%v", line);
3228   vec_free (line);
3229 }
3230
3231 static void
3232   vl_api_one_eid_table_vni_details_t_handler_json
3233   (vl_api_one_eid_table_vni_details_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236   vat_json_node_t *node = NULL;
3237
3238   if (VAT_JSON_ARRAY != vam->json_tree.type)
3239     {
3240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3241       vat_json_init_array (&vam->json_tree);
3242     }
3243   node = vat_json_array_add (&vam->json_tree);
3244   vat_json_init_object (node);
3245   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3246 }
3247
3248 static void
3249   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3250   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   int retval = clib_net_to_host_u32 (mp->retval);
3254
3255   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3256   print (vam->ofp, "fallback threshold value: %d", mp->value);
3257
3258   vam->retval = retval;
3259   vam->result_ready = 1;
3260 }
3261
3262 static void
3263   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3264   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3265 {
3266   vat_main_t *vam = &vat_main;
3267   vat_json_node_t _node, *node = &_node;
3268   int retval = clib_net_to_host_u32 (mp->retval);
3269
3270   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3271   vat_json_init_object (node);
3272   vat_json_object_add_uint (node, "value", mp->value);
3273
3274   vat_json_print (vam->ofp, node);
3275   vat_json_free (node);
3276
3277   vam->retval = retval;
3278   vam->result_ready = 1;
3279 }
3280
3281 static void
3282   vl_api_show_one_map_register_state_reply_t_handler
3283   (vl_api_show_one_map_register_state_reply_t * mp)
3284 {
3285   vat_main_t *vam = &vat_main;
3286   int retval = clib_net_to_host_u32 (mp->retval);
3287
3288   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3289
3290   vam->retval = retval;
3291   vam->result_ready = 1;
3292 }
3293
3294 static void
3295   vl_api_show_one_map_register_state_reply_t_handler_json
3296   (vl_api_show_one_map_register_state_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   vat_json_node_t _node, *node = &_node;
3300   int retval = clib_net_to_host_u32 (mp->retval);
3301
3302   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3303
3304   vat_json_init_object (node);
3305   vat_json_object_add_string_copy (node, "state", s);
3306
3307   vat_json_print (vam->ofp, node);
3308   vat_json_free (node);
3309
3310   vam->retval = retval;
3311   vam->result_ready = 1;
3312   vec_free (s);
3313 }
3314
3315 static void
3316   vl_api_show_one_rloc_probe_state_reply_t_handler
3317   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   int retval = clib_net_to_host_u32 (mp->retval);
3321
3322   if (retval)
3323     goto end;
3324
3325   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3326 end:
3327   vam->retval = retval;
3328   vam->result_ready = 1;
3329 }
3330
3331 static void
3332   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3333   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3334 {
3335   vat_main_t *vam = &vat_main;
3336   vat_json_node_t _node, *node = &_node;
3337   int retval = clib_net_to_host_u32 (mp->retval);
3338
3339   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3340   vat_json_init_object (node);
3341   vat_json_object_add_string_copy (node, "state", s);
3342
3343   vat_json_print (vam->ofp, node);
3344   vat_json_free (node);
3345
3346   vam->retval = retval;
3347   vam->result_ready = 1;
3348   vec_free (s);
3349 }
3350
3351 static void
3352   vl_api_show_one_stats_enable_disable_reply_t_handler
3353   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3354 {
3355   vat_main_t *vam = &vat_main;
3356   int retval = clib_net_to_host_u32 (mp->retval);
3357
3358   if (retval)
3359     goto end;
3360
3361   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3362 end:
3363   vam->retval = retval;
3364   vam->result_ready = 1;
3365 }
3366
3367 static void
3368   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3369   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372   vat_json_node_t _node, *node = &_node;
3373   int retval = clib_net_to_host_u32 (mp->retval);
3374
3375   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3376   vat_json_init_object (node);
3377   vat_json_object_add_string_copy (node, "state", s);
3378
3379   vat_json_print (vam->ofp, node);
3380   vat_json_free (node);
3381
3382   vam->retval = retval;
3383   vam->result_ready = 1;
3384   vec_free (s);
3385 }
3386
3387 static void
3388 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3389 {
3390   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3391   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3392   e->vni = clib_net_to_host_u32 (e->vni);
3393 }
3394
3395 static void
3396   gpe_fwd_entries_get_reply_t_net_to_host
3397   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3398 {
3399   u32 i;
3400
3401   mp->count = clib_net_to_host_u32 (mp->count);
3402   for (i = 0; i < mp->count; i++)
3403     {
3404       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3405     }
3406 }
3407
3408 static u8 *
3409 format_gpe_encap_mode (u8 * s, va_list * args)
3410 {
3411   u32 mode = va_arg (*args, u32);
3412
3413   switch (mode)
3414     {
3415     case 0:
3416       return format (s, "lisp");
3417     case 1:
3418       return format (s, "vxlan");
3419     }
3420   return 0;
3421 }
3422
3423 static void
3424   vl_api_gpe_get_encap_mode_reply_t_handler
3425   (vl_api_gpe_get_encap_mode_reply_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428
3429   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3430   vam->retval = ntohl (mp->retval);
3431   vam->result_ready = 1;
3432 }
3433
3434 static void
3435   vl_api_gpe_get_encap_mode_reply_t_handler_json
3436   (vl_api_gpe_get_encap_mode_reply_t * mp)
3437 {
3438   vat_main_t *vam = &vat_main;
3439   vat_json_node_t node;
3440
3441   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3442   vec_add1 (encap_mode, 0);
3443
3444   vat_json_init_object (&node);
3445   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3446
3447   vec_free (encap_mode);
3448   vat_json_print (vam->ofp, &node);
3449   vat_json_free (&node);
3450
3451   vam->retval = ntohl (mp->retval);
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456   vl_api_gpe_fwd_entry_path_details_t_handler
3457   (vl_api_gpe_fwd_entry_path_details_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3461
3462   if (mp->lcl_loc.is_ip4)
3463     format_ip_address_fcn = format_ip4_address;
3464   else
3465     format_ip_address_fcn = format_ip6_address;
3466
3467   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3468          format_ip_address_fcn, &mp->lcl_loc,
3469          format_ip_address_fcn, &mp->rmt_loc);
3470 }
3471
3472 static void
3473 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3474 {
3475   struct in6_addr ip6;
3476   struct in_addr ip4;
3477
3478   if (loc->is_ip4)
3479     {
3480       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3481       vat_json_object_add_ip4 (n, "address", ip4);
3482     }
3483   else
3484     {
3485       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3486       vat_json_object_add_ip6 (n, "address", ip6);
3487     }
3488   vat_json_object_add_uint (n, "weight", loc->weight);
3489 }
3490
3491 static void
3492   vl_api_gpe_fwd_entry_path_details_t_handler_json
3493   (vl_api_gpe_fwd_entry_path_details_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496   vat_json_node_t *node = NULL;
3497   vat_json_node_t *loc_node;
3498
3499   if (VAT_JSON_ARRAY != vam->json_tree.type)
3500     {
3501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3502       vat_json_init_array (&vam->json_tree);
3503     }
3504   node = vat_json_array_add (&vam->json_tree);
3505   vat_json_init_object (node);
3506
3507   loc_node = vat_json_object_add (node, "local_locator");
3508   vat_json_init_object (loc_node);
3509   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3510
3511   loc_node = vat_json_object_add (node, "remote_locator");
3512   vat_json_init_object (loc_node);
3513   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3514 }
3515
3516 static void
3517   vl_api_gpe_fwd_entries_get_reply_t_handler
3518   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   u32 i;
3522   int retval = clib_net_to_host_u32 (mp->retval);
3523   vl_api_gpe_fwd_entry_t *e;
3524
3525   if (retval)
3526     goto end;
3527
3528   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3529
3530   for (i = 0; i < mp->count; i++)
3531     {
3532       e = &mp->entries[i];
3533       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3534              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3535              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3536     }
3537
3538 end:
3539   vam->retval = retval;
3540   vam->result_ready = 1;
3541 }
3542
3543 static void
3544   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3545   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3546 {
3547   u8 *s = 0;
3548   vat_main_t *vam = &vat_main;
3549   vat_json_node_t *e = 0, root;
3550   u32 i;
3551   int retval = clib_net_to_host_u32 (mp->retval);
3552   vl_api_gpe_fwd_entry_t *fwd;
3553
3554   if (retval)
3555     goto end;
3556
3557   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3558   vat_json_init_array (&root);
3559
3560   for (i = 0; i < mp->count; i++)
3561     {
3562       e = vat_json_array_add (&root);
3563       fwd = &mp->entries[i];
3564
3565       vat_json_init_object (e);
3566       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3567       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3568       vat_json_object_add_int (e, "vni", fwd->vni);
3569       vat_json_object_add_int (e, "action", fwd->action);
3570
3571       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3572                   fwd->leid_prefix_len);
3573       vec_add1 (s, 0);
3574       vat_json_object_add_string_copy (e, "leid", s);
3575       vec_free (s);
3576
3577       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3578                   fwd->reid_prefix_len);
3579       vec_add1 (s, 0);
3580       vat_json_object_add_string_copy (e, "reid", s);
3581       vec_free (s);
3582     }
3583
3584   vat_json_print (vam->ofp, &root);
3585   vat_json_free (&root);
3586
3587 end:
3588   vam->retval = retval;
3589   vam->result_ready = 1;
3590 }
3591
3592 static void
3593   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3594   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3595 {
3596   vat_main_t *vam = &vat_main;
3597   u32 i, n;
3598   int retval = clib_net_to_host_u32 (mp->retval);
3599   vl_api_gpe_native_fwd_rpath_t *r;
3600
3601   if (retval)
3602     goto end;
3603
3604   n = clib_net_to_host_u32 (mp->count);
3605
3606   for (i = 0; i < n; i++)
3607     {
3608       r = &mp->entries[i];
3609       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3610              clib_net_to_host_u32 (r->fib_index),
3611              clib_net_to_host_u32 (r->nh_sw_if_index),
3612              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3613     }
3614
3615 end:
3616   vam->retval = retval;
3617   vam->result_ready = 1;
3618 }
3619
3620 static void
3621   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3622   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3623 {
3624   vat_main_t *vam = &vat_main;
3625   vat_json_node_t root, *e;
3626   u32 i, n;
3627   int retval = clib_net_to_host_u32 (mp->retval);
3628   vl_api_gpe_native_fwd_rpath_t *r;
3629   u8 *s;
3630
3631   if (retval)
3632     goto end;
3633
3634   n = clib_net_to_host_u32 (mp->count);
3635   vat_json_init_array (&root);
3636
3637   for (i = 0; i < n; i++)
3638     {
3639       e = vat_json_array_add (&root);
3640       vat_json_init_object (e);
3641       r = &mp->entries[i];
3642       s =
3643         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3644                 r->nh_addr);
3645       vec_add1 (s, 0);
3646       vat_json_object_add_string_copy (e, "ip4", s);
3647       vec_free (s);
3648
3649       vat_json_object_add_uint (e, "fib_index",
3650                                 clib_net_to_host_u32 (r->fib_index));
3651       vat_json_object_add_uint (e, "nh_sw_if_index",
3652                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3653     }
3654
3655   vat_json_print (vam->ofp, &root);
3656   vat_json_free (&root);
3657
3658 end:
3659   vam->retval = retval;
3660   vam->result_ready = 1;
3661 }
3662
3663 static void
3664   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3665   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3666 {
3667   vat_main_t *vam = &vat_main;
3668   u32 i, n;
3669   int retval = clib_net_to_host_u32 (mp->retval);
3670
3671   if (retval)
3672     goto end;
3673
3674   n = clib_net_to_host_u32 (mp->count);
3675
3676   for (i = 0; i < n; i++)
3677     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3678
3679 end:
3680   vam->retval = retval;
3681   vam->result_ready = 1;
3682 }
3683
3684 static void
3685   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3686   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   vat_json_node_t root;
3690   u32 i, n;
3691   int retval = clib_net_to_host_u32 (mp->retval);
3692
3693   if (retval)
3694     goto end;
3695
3696   n = clib_net_to_host_u32 (mp->count);
3697   vat_json_init_array (&root);
3698
3699   for (i = 0; i < n; i++)
3700     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3701
3702   vat_json_print (vam->ofp, &root);
3703   vat_json_free (&root);
3704
3705 end:
3706   vam->retval = retval;
3707   vam->result_ready = 1;
3708 }
3709
3710 static void
3711   vl_api_one_ndp_entries_get_reply_t_handler
3712   (vl_api_one_ndp_entries_get_reply_t * mp)
3713 {
3714   vat_main_t *vam = &vat_main;
3715   u32 i, n;
3716   int retval = clib_net_to_host_u32 (mp->retval);
3717
3718   if (retval)
3719     goto end;
3720
3721   n = clib_net_to_host_u32 (mp->count);
3722
3723   for (i = 0; i < n; i++)
3724     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3725            format_ethernet_address, mp->entries[i].mac);
3726
3727 end:
3728   vam->retval = retval;
3729   vam->result_ready = 1;
3730 }
3731
3732 static void
3733   vl_api_one_ndp_entries_get_reply_t_handler_json
3734   (vl_api_one_ndp_entries_get_reply_t * mp)
3735 {
3736   u8 *s = 0;
3737   vat_main_t *vam = &vat_main;
3738   vat_json_node_t *e = 0, root;
3739   u32 i, n;
3740   int retval = clib_net_to_host_u32 (mp->retval);
3741   vl_api_one_ndp_entry_t *arp_entry;
3742
3743   if (retval)
3744     goto end;
3745
3746   n = clib_net_to_host_u32 (mp->count);
3747   vat_json_init_array (&root);
3748
3749   for (i = 0; i < n; i++)
3750     {
3751       e = vat_json_array_add (&root);
3752       arp_entry = &mp->entries[i];
3753
3754       vat_json_init_object (e);
3755       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3756       vec_add1 (s, 0);
3757
3758       vat_json_object_add_string_copy (e, "mac", s);
3759       vec_free (s);
3760
3761       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3762       vec_add1 (s, 0);
3763       vat_json_object_add_string_copy (e, "ip6", s);
3764       vec_free (s);
3765     }
3766
3767   vat_json_print (vam->ofp, &root);
3768   vat_json_free (&root);
3769
3770 end:
3771   vam->retval = retval;
3772   vam->result_ready = 1;
3773 }
3774
3775 static void
3776   vl_api_one_l2_arp_entries_get_reply_t_handler
3777   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3778 {
3779   vat_main_t *vam = &vat_main;
3780   u32 i, n;
3781   int retval = clib_net_to_host_u32 (mp->retval);
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787
3788   for (i = 0; i < n; i++)
3789     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3790            format_ethernet_address, mp->entries[i].mac);
3791
3792 end:
3793   vam->retval = retval;
3794   vam->result_ready = 1;
3795 }
3796
3797 static void
3798   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3799   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3800 {
3801   u8 *s = 0;
3802   vat_main_t *vam = &vat_main;
3803   vat_json_node_t *e = 0, root;
3804   u32 i, n;
3805   int retval = clib_net_to_host_u32 (mp->retval);
3806   vl_api_one_l2_arp_entry_t *arp_entry;
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812   vat_json_init_array (&root);
3813
3814   for (i = 0; i < n; i++)
3815     {
3816       e = vat_json_array_add (&root);
3817       arp_entry = &mp->entries[i];
3818
3819       vat_json_init_object (e);
3820       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3821       vec_add1 (s, 0);
3822
3823       vat_json_object_add_string_copy (e, "mac", s);
3824       vec_free (s);
3825
3826       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3827       vec_add1 (s, 0);
3828       vat_json_object_add_string_copy (e, "ip4", s);
3829       vec_free (s);
3830     }
3831
3832   vat_json_print (vam->ofp, &root);
3833   vat_json_free (&root);
3834
3835 end:
3836   vam->retval = retval;
3837   vam->result_ready = 1;
3838 }
3839
3840 static void
3841 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3842 {
3843   vat_main_t *vam = &vat_main;
3844   u32 i, n;
3845   int retval = clib_net_to_host_u32 (mp->retval);
3846
3847   if (retval)
3848     goto end;
3849
3850   n = clib_net_to_host_u32 (mp->count);
3851
3852   for (i = 0; i < n; i++)
3853     {
3854       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3855     }
3856
3857 end:
3858   vam->retval = retval;
3859   vam->result_ready = 1;
3860 }
3861
3862 static void
3863   vl_api_one_ndp_bd_get_reply_t_handler_json
3864   (vl_api_one_ndp_bd_get_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
3867   vat_json_node_t root;
3868   u32 i, n;
3869   int retval = clib_net_to_host_u32 (mp->retval);
3870
3871   if (retval)
3872     goto end;
3873
3874   n = clib_net_to_host_u32 (mp->count);
3875   vat_json_init_array (&root);
3876
3877   for (i = 0; i < n; i++)
3878     {
3879       vat_json_array_add_uint (&root,
3880                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3881     }
3882
3883   vat_json_print (vam->ofp, &root);
3884   vat_json_free (&root);
3885
3886 end:
3887   vam->retval = retval;
3888   vam->result_ready = 1;
3889 }
3890
3891 static void
3892   vl_api_one_l2_arp_bd_get_reply_t_handler
3893   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3894 {
3895   vat_main_t *vam = &vat_main;
3896   u32 i, n;
3897   int retval = clib_net_to_host_u32 (mp->retval);
3898
3899   if (retval)
3900     goto end;
3901
3902   n = clib_net_to_host_u32 (mp->count);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3907     }
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3916   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   vat_json_node_t root;
3920   u32 i, n;
3921   int retval = clib_net_to_host_u32 (mp->retval);
3922
3923   if (retval)
3924     goto end;
3925
3926   n = clib_net_to_host_u32 (mp->count);
3927   vat_json_init_array (&root);
3928
3929   for (i = 0; i < n; i++)
3930     {
3931       vat_json_array_add_uint (&root,
3932                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3933     }
3934
3935   vat_json_print (vam->ofp, &root);
3936   vat_json_free (&root);
3937
3938 end:
3939   vam->retval = retval;
3940   vam->result_ready = 1;
3941 }
3942
3943 static void
3944   vl_api_one_adjacencies_get_reply_t_handler
3945   (vl_api_one_adjacencies_get_reply_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948   u32 i, n;
3949   int retval = clib_net_to_host_u32 (mp->retval);
3950   vl_api_one_adjacency_t *a;
3951
3952   if (retval)
3953     goto end;
3954
3955   n = clib_net_to_host_u32 (mp->count);
3956
3957   for (i = 0; i < n; i++)
3958     {
3959       a = &mp->adjacencies[i];
3960       print (vam->ofp, "%U %40U",
3961              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3962              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3963     }
3964
3965 end:
3966   vam->retval = retval;
3967   vam->result_ready = 1;
3968 }
3969
3970 static void
3971   vl_api_one_adjacencies_get_reply_t_handler_json
3972   (vl_api_one_adjacencies_get_reply_t * mp)
3973 {
3974   u8 *s = 0;
3975   vat_main_t *vam = &vat_main;
3976   vat_json_node_t *e = 0, root;
3977   u32 i, n;
3978   int retval = clib_net_to_host_u32 (mp->retval);
3979   vl_api_one_adjacency_t *a;
3980
3981   if (retval)
3982     goto end;
3983
3984   n = clib_net_to_host_u32 (mp->count);
3985   vat_json_init_array (&root);
3986
3987   for (i = 0; i < n; i++)
3988     {
3989       e = vat_json_array_add (&root);
3990       a = &mp->adjacencies[i];
3991
3992       vat_json_init_object (e);
3993       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3994                   a->leid_prefix_len);
3995       vec_add1 (s, 0);
3996       vat_json_object_add_string_copy (e, "leid", s);
3997       vec_free (s);
3998
3999       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4000                   a->reid_prefix_len);
4001       vec_add1 (s, 0);
4002       vat_json_object_add_string_copy (e, "reid", s);
4003       vec_free (s);
4004     }
4005
4006   vat_json_print (vam->ofp, &root);
4007   vat_json_free (&root);
4008
4009 end:
4010   vam->retval = retval;
4011   vam->result_ready = 1;
4012 }
4013
4014 static void
4015 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4016 {
4017   vat_main_t *vam = &vat_main;
4018
4019   print (vam->ofp, "%=20U",
4020          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4021          mp->ip_address);
4022 }
4023
4024 static void
4025   vl_api_one_map_server_details_t_handler_json
4026   (vl_api_one_map_server_details_t * mp)
4027 {
4028   vat_main_t *vam = &vat_main;
4029   vat_json_node_t *node = NULL;
4030   struct in6_addr ip6;
4031   struct in_addr ip4;
4032
4033   if (VAT_JSON_ARRAY != vam->json_tree.type)
4034     {
4035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4036       vat_json_init_array (&vam->json_tree);
4037     }
4038   node = vat_json_array_add (&vam->json_tree);
4039
4040   vat_json_init_object (node);
4041   if (mp->is_ipv6)
4042     {
4043       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4044       vat_json_object_add_ip6 (node, "map-server", ip6);
4045     }
4046   else
4047     {
4048       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4049       vat_json_object_add_ip4 (node, "map-server", ip4);
4050     }
4051 }
4052
4053 static void
4054 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4055                                            * mp)
4056 {
4057   vat_main_t *vam = &vat_main;
4058
4059   print (vam->ofp, "%=20U",
4060          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4061          mp->ip_address);
4062 }
4063
4064 static void
4065   vl_api_one_map_resolver_details_t_handler_json
4066   (vl_api_one_map_resolver_details_t * mp)
4067 {
4068   vat_main_t *vam = &vat_main;
4069   vat_json_node_t *node = NULL;
4070   struct in6_addr ip6;
4071   struct in_addr ip4;
4072
4073   if (VAT_JSON_ARRAY != vam->json_tree.type)
4074     {
4075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4076       vat_json_init_array (&vam->json_tree);
4077     }
4078   node = vat_json_array_add (&vam->json_tree);
4079
4080   vat_json_init_object (node);
4081   if (mp->is_ipv6)
4082     {
4083       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4084       vat_json_object_add_ip6 (node, "map resolver", ip6);
4085     }
4086   else
4087     {
4088       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4089       vat_json_object_add_ip4 (node, "map resolver", ip4);
4090     }
4091 }
4092
4093 static void
4094 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4095 {
4096   vat_main_t *vam = &vat_main;
4097   i32 retval = ntohl (mp->retval);
4098
4099   if (0 <= retval)
4100     {
4101       print (vam->ofp, "feature: %s\ngpe: %s",
4102              mp->feature_status ? "enabled" : "disabled",
4103              mp->gpe_status ? "enabled" : "disabled");
4104     }
4105
4106   vam->retval = retval;
4107   vam->result_ready = 1;
4108 }
4109
4110 static void
4111   vl_api_show_one_status_reply_t_handler_json
4112   (vl_api_show_one_status_reply_t * mp)
4113 {
4114   vat_main_t *vam = &vat_main;
4115   vat_json_node_t node;
4116   u8 *gpe_status = NULL;
4117   u8 *feature_status = NULL;
4118
4119   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4120   feature_status = format (0, "%s",
4121                            mp->feature_status ? "enabled" : "disabled");
4122   vec_add1 (gpe_status, 0);
4123   vec_add1 (feature_status, 0);
4124
4125   vat_json_init_object (&node);
4126   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4127   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4128
4129   vec_free (gpe_status);
4130   vec_free (feature_status);
4131
4132   vat_json_print (vam->ofp, &node);
4133   vat_json_free (&node);
4134
4135   vam->retval = ntohl (mp->retval);
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4141   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   i32 retval = ntohl (mp->retval);
4145
4146   if (retval >= 0)
4147     {
4148       print (vam->ofp, "%=20s", mp->locator_set_name);
4149     }
4150
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4157   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t *node = NULL;
4161
4162   if (VAT_JSON_ARRAY != vam->json_tree.type)
4163     {
4164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4165       vat_json_init_array (&vam->json_tree);
4166     }
4167   node = vat_json_array_add (&vam->json_tree);
4168
4169   vat_json_init_object (node);
4170   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4171
4172   vat_json_print (vam->ofp, node);
4173   vat_json_free (node);
4174
4175   vam->retval = ntohl (mp->retval);
4176   vam->result_ready = 1;
4177 }
4178
4179 static u8 *
4180 format_lisp_map_request_mode (u8 * s, va_list * args)
4181 {
4182   u32 mode = va_arg (*args, u32);
4183
4184   switch (mode)
4185     {
4186     case 0:
4187       return format (0, "dst-only");
4188     case 1:
4189       return format (0, "src-dst");
4190     }
4191   return 0;
4192 }
4193
4194 static void
4195   vl_api_show_one_map_request_mode_reply_t_handler
4196   (vl_api_show_one_map_request_mode_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   i32 retval = ntohl (mp->retval);
4200
4201   if (0 <= retval)
4202     {
4203       u32 mode = mp->mode;
4204       print (vam->ofp, "map_request_mode: %U",
4205              format_lisp_map_request_mode, mode);
4206     }
4207
4208   vam->retval = retval;
4209   vam->result_ready = 1;
4210 }
4211
4212 static void
4213   vl_api_show_one_map_request_mode_reply_t_handler_json
4214   (vl_api_show_one_map_request_mode_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   vat_json_node_t node;
4218   u8 *s = 0;
4219   u32 mode;
4220
4221   mode = mp->mode;
4222   s = format (0, "%U", format_lisp_map_request_mode, mode);
4223   vec_add1 (s, 0);
4224
4225   vat_json_init_object (&node);
4226   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4227   vat_json_print (vam->ofp, &node);
4228   vat_json_free (&node);
4229
4230   vec_free (s);
4231   vam->retval = ntohl (mp->retval);
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_one_show_xtr_mode_reply_t_handler
4237   (vl_api_one_show_xtr_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   i32 retval = ntohl (mp->retval);
4241
4242   if (0 <= retval)
4243     {
4244       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4245     }
4246
4247   vam->retval = retval;
4248   vam->result_ready = 1;
4249 }
4250
4251 static void
4252   vl_api_one_show_xtr_mode_reply_t_handler_json
4253   (vl_api_one_show_xtr_mode_reply_t * mp)
4254 {
4255   vat_main_t *vam = &vat_main;
4256   vat_json_node_t node;
4257   u8 *status = 0;
4258
4259   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4260   vec_add1 (status, 0);
4261
4262   vat_json_init_object (&node);
4263   vat_json_object_add_string_copy (&node, "status", status);
4264
4265   vec_free (status);
4266
4267   vat_json_print (vam->ofp, &node);
4268   vat_json_free (&node);
4269
4270   vam->retval = ntohl (mp->retval);
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_pitr_mode_reply_t_handler
4276   (vl_api_one_show_pitr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   i32 retval = ntohl (mp->retval);
4280
4281   if (0 <= retval)
4282     {
4283       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4284     }
4285
4286   vam->retval = retval;
4287   vam->result_ready = 1;
4288 }
4289
4290 static void
4291   vl_api_one_show_pitr_mode_reply_t_handler_json
4292   (vl_api_one_show_pitr_mode_reply_t * mp)
4293 {
4294   vat_main_t *vam = &vat_main;
4295   vat_json_node_t node;
4296   u8 *status = 0;
4297
4298   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4299   vec_add1 (status, 0);
4300
4301   vat_json_init_object (&node);
4302   vat_json_object_add_string_copy (&node, "status", status);
4303
4304   vec_free (status);
4305
4306   vat_json_print (vam->ofp, &node);
4307   vat_json_free (&node);
4308
4309   vam->retval = ntohl (mp->retval);
4310   vam->result_ready = 1;
4311 }
4312
4313 static void
4314   vl_api_one_show_petr_mode_reply_t_handler
4315   (vl_api_one_show_petr_mode_reply_t * mp)
4316 {
4317   vat_main_t *vam = &vat_main;
4318   i32 retval = ntohl (mp->retval);
4319
4320   if (0 <= retval)
4321     {
4322       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4323     }
4324
4325   vam->retval = retval;
4326   vam->result_ready = 1;
4327 }
4328
4329 static void
4330   vl_api_one_show_petr_mode_reply_t_handler_json
4331   (vl_api_one_show_petr_mode_reply_t * mp)
4332 {
4333   vat_main_t *vam = &vat_main;
4334   vat_json_node_t node;
4335   u8 *status = 0;
4336
4337   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4338   vec_add1 (status, 0);
4339
4340   vat_json_init_object (&node);
4341   vat_json_object_add_string_copy (&node, "status", status);
4342
4343   vec_free (status);
4344
4345   vat_json_print (vam->ofp, &node);
4346   vat_json_free (&node);
4347
4348   vam->retval = ntohl (mp->retval);
4349   vam->result_ready = 1;
4350 }
4351
4352 static void
4353   vl_api_show_one_use_petr_reply_t_handler
4354   (vl_api_show_one_use_petr_reply_t * mp)
4355 {
4356   vat_main_t *vam = &vat_main;
4357   i32 retval = ntohl (mp->retval);
4358
4359   if (0 <= retval)
4360     {
4361       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4362       if (mp->status)
4363         {
4364           print (vam->ofp, "Proxy-ETR address; %U",
4365                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4366                  mp->address);
4367         }
4368     }
4369
4370   vam->retval = retval;
4371   vam->result_ready = 1;
4372 }
4373
4374 static void
4375   vl_api_show_one_use_petr_reply_t_handler_json
4376   (vl_api_show_one_use_petr_reply_t * mp)
4377 {
4378   vat_main_t *vam = &vat_main;
4379   vat_json_node_t node;
4380   u8 *status = 0;
4381   struct in_addr ip4;
4382   struct in6_addr ip6;
4383
4384   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4385   vec_add1 (status, 0);
4386
4387   vat_json_init_object (&node);
4388   vat_json_object_add_string_copy (&node, "status", status);
4389   if (mp->status)
4390     {
4391       if (mp->is_ip4)
4392         {
4393           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4394           vat_json_object_add_ip6 (&node, "address", ip6);
4395         }
4396       else
4397         {
4398           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4399           vat_json_object_add_ip4 (&node, "address", ip4);
4400         }
4401     }
4402
4403   vec_free (status);
4404
4405   vat_json_print (vam->ofp, &node);
4406   vat_json_free (&node);
4407
4408   vam->retval = ntohl (mp->retval);
4409   vam->result_ready = 1;
4410 }
4411
4412 static void
4413   vl_api_show_one_nsh_mapping_reply_t_handler
4414   (vl_api_show_one_nsh_mapping_reply_t * mp)
4415 {
4416   vat_main_t *vam = &vat_main;
4417   i32 retval = ntohl (mp->retval);
4418
4419   if (0 <= retval)
4420     {
4421       print (vam->ofp, "%-20s%-16s",
4422              mp->is_set ? "set" : "not-set",
4423              mp->is_set ? (char *) mp->locator_set_name : "");
4424     }
4425
4426   vam->retval = retval;
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431   vl_api_show_one_nsh_mapping_reply_t_handler_json
4432   (vl_api_show_one_nsh_mapping_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   vat_json_node_t node;
4436   u8 *status = 0;
4437
4438   status = format (0, "%s", mp->is_set ? "yes" : "no");
4439   vec_add1 (status, 0);
4440
4441   vat_json_init_object (&node);
4442   vat_json_object_add_string_copy (&node, "is_set", status);
4443   if (mp->is_set)
4444     {
4445       vat_json_object_add_string_copy (&node, "locator_set",
4446                                        mp->locator_set_name);
4447     }
4448
4449   vec_free (status);
4450
4451   vat_json_print (vam->ofp, &node);
4452   vat_json_free (&node);
4453
4454   vam->retval = ntohl (mp->retval);
4455   vam->result_ready = 1;
4456 }
4457
4458 static void
4459   vl_api_show_one_map_register_ttl_reply_t_handler
4460   (vl_api_show_one_map_register_ttl_reply_t * mp)
4461 {
4462   vat_main_t *vam = &vat_main;
4463   i32 retval = ntohl (mp->retval);
4464
4465   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4466
4467   if (0 <= retval)
4468     {
4469       print (vam->ofp, "ttl: %u", mp->ttl);
4470     }
4471
4472   vam->retval = retval;
4473   vam->result_ready = 1;
4474 }
4475
4476 static void
4477   vl_api_show_one_map_register_ttl_reply_t_handler_json
4478   (vl_api_show_one_map_register_ttl_reply_t * mp)
4479 {
4480   vat_main_t *vam = &vat_main;
4481   vat_json_node_t node;
4482
4483   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4484   vat_json_init_object (&node);
4485   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4486
4487   vat_json_print (vam->ofp, &node);
4488   vat_json_free (&node);
4489
4490   vam->retval = ntohl (mp->retval);
4491   vam->result_ready = 1;
4492 }
4493
4494 static void
4495 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4496 {
4497   vat_main_t *vam = &vat_main;
4498   i32 retval = ntohl (mp->retval);
4499
4500   if (0 <= retval)
4501     {
4502       print (vam->ofp, "%-20s%-16s",
4503              mp->status ? "enabled" : "disabled",
4504              mp->status ? (char *) mp->locator_set_name : "");
4505     }
4506
4507   vam->retval = retval;
4508   vam->result_ready = 1;
4509 }
4510
4511 static void
4512 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4513 {
4514   vat_main_t *vam = &vat_main;
4515   vat_json_node_t node;
4516   u8 *status = 0;
4517
4518   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4519   vec_add1 (status, 0);
4520
4521   vat_json_init_object (&node);
4522   vat_json_object_add_string_copy (&node, "status", status);
4523   if (mp->status)
4524     {
4525       vat_json_object_add_string_copy (&node, "locator_set",
4526                                        mp->locator_set_name);
4527     }
4528
4529   vec_free (status);
4530
4531   vat_json_print (vam->ofp, &node);
4532   vat_json_free (&node);
4533
4534   vam->retval = ntohl (mp->retval);
4535   vam->result_ready = 1;
4536 }
4537
4538 static u8 *
4539 format_policer_type (u8 * s, va_list * va)
4540 {
4541   u32 i = va_arg (*va, u32);
4542
4543   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4544     s = format (s, "1r2c");
4545   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4546     s = format (s, "1r3c");
4547   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4548     s = format (s, "2r3c-2698");
4549   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4550     s = format (s, "2r3c-4115");
4551   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4552     s = format (s, "2r3c-mef5cf1");
4553   else
4554     s = format (s, "ILLEGAL");
4555   return s;
4556 }
4557
4558 static u8 *
4559 format_policer_rate_type (u8 * s, va_list * va)
4560 {
4561   u32 i = va_arg (*va, u32);
4562
4563   if (i == SSE2_QOS_RATE_KBPS)
4564     s = format (s, "kbps");
4565   else if (i == SSE2_QOS_RATE_PPS)
4566     s = format (s, "pps");
4567   else
4568     s = format (s, "ILLEGAL");
4569   return s;
4570 }
4571
4572 static u8 *
4573 format_policer_round_type (u8 * s, va_list * va)
4574 {
4575   u32 i = va_arg (*va, u32);
4576
4577   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4578     s = format (s, "closest");
4579   else if (i == SSE2_QOS_ROUND_TO_UP)
4580     s = format (s, "up");
4581   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4582     s = format (s, "down");
4583   else
4584     s = format (s, "ILLEGAL");
4585   return s;
4586 }
4587
4588 static u8 *
4589 format_policer_action_type (u8 * s, va_list * va)
4590 {
4591   u32 i = va_arg (*va, u32);
4592
4593   if (i == SSE2_QOS_ACTION_DROP)
4594     s = format (s, "drop");
4595   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4596     s = format (s, "transmit");
4597   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4598     s = format (s, "mark-and-transmit");
4599   else
4600     s = format (s, "ILLEGAL");
4601   return s;
4602 }
4603
4604 static u8 *
4605 format_dscp (u8 * s, va_list * va)
4606 {
4607   u32 i = va_arg (*va, u32);
4608   char *t = 0;
4609
4610   switch (i)
4611     {
4612 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4613       foreach_vnet_dscp
4614 #undef _
4615     default:
4616       return format (s, "ILLEGAL");
4617     }
4618   s = format (s, "%s", t);
4619   return s;
4620 }
4621
4622 static void
4623 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4624 {
4625   vat_main_t *vam = &vat_main;
4626   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4627
4628   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4629     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4630   else
4631     conform_dscp_str = format (0, "");
4632
4633   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4634     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4635   else
4636     exceed_dscp_str = format (0, "");
4637
4638   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4639     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4640   else
4641     violate_dscp_str = format (0, "");
4642
4643   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4644          "rate type %U, round type %U, %s rate, %s color-aware, "
4645          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4646          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4647          "conform action %U%s, exceed action %U%s, violate action %U%s",
4648          mp->name,
4649          format_policer_type, mp->type,
4650          ntohl (mp->cir),
4651          ntohl (mp->eir),
4652          clib_net_to_host_u64 (mp->cb),
4653          clib_net_to_host_u64 (mp->eb),
4654          format_policer_rate_type, mp->rate_type,
4655          format_policer_round_type, mp->round_type,
4656          mp->single_rate ? "single" : "dual",
4657          mp->color_aware ? "is" : "not",
4658          ntohl (mp->cir_tokens_per_period),
4659          ntohl (mp->pir_tokens_per_period),
4660          ntohl (mp->scale),
4661          ntohl (mp->current_limit),
4662          ntohl (mp->current_bucket),
4663          ntohl (mp->extended_limit),
4664          ntohl (mp->extended_bucket),
4665          clib_net_to_host_u64 (mp->last_update_time),
4666          format_policer_action_type, mp->conform_action_type,
4667          conform_dscp_str,
4668          format_policer_action_type, mp->exceed_action_type,
4669          exceed_dscp_str,
4670          format_policer_action_type, mp->violate_action_type,
4671          violate_dscp_str);
4672
4673   vec_free (conform_dscp_str);
4674   vec_free (exceed_dscp_str);
4675   vec_free (violate_dscp_str);
4676 }
4677
4678 static void vl_api_policer_details_t_handler_json
4679   (vl_api_policer_details_t * mp)
4680 {
4681   vat_main_t *vam = &vat_main;
4682   vat_json_node_t *node;
4683   u8 *rate_type_str, *round_type_str, *type_str;
4684   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4685
4686   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4687   round_type_str =
4688     format (0, "%U", format_policer_round_type, mp->round_type);
4689   type_str = format (0, "%U", format_policer_type, mp->type);
4690   conform_action_str = format (0, "%U", format_policer_action_type,
4691                                mp->conform_action_type);
4692   exceed_action_str = format (0, "%U", format_policer_action_type,
4693                               mp->exceed_action_type);
4694   violate_action_str = format (0, "%U", format_policer_action_type,
4695                                mp->violate_action_type);
4696
4697   if (VAT_JSON_ARRAY != vam->json_tree.type)
4698     {
4699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4700       vat_json_init_array (&vam->json_tree);
4701     }
4702   node = vat_json_array_add (&vam->json_tree);
4703
4704   vat_json_init_object (node);
4705   vat_json_object_add_string_copy (node, "name", mp->name);
4706   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4707   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4708   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4709   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4710   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4711   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4712   vat_json_object_add_string_copy (node, "type", type_str);
4713   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4714   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4715   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4716   vat_json_object_add_uint (node, "cir_tokens_per_period",
4717                             ntohl (mp->cir_tokens_per_period));
4718   vat_json_object_add_uint (node, "eir_tokens_per_period",
4719                             ntohl (mp->pir_tokens_per_period));
4720   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4721   vat_json_object_add_uint (node, "current_bucket",
4722                             ntohl (mp->current_bucket));
4723   vat_json_object_add_uint (node, "extended_limit",
4724                             ntohl (mp->extended_limit));
4725   vat_json_object_add_uint (node, "extended_bucket",
4726                             ntohl (mp->extended_bucket));
4727   vat_json_object_add_uint (node, "last_update_time",
4728                             ntohl (mp->last_update_time));
4729   vat_json_object_add_string_copy (node, "conform_action",
4730                                    conform_action_str);
4731   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4732     {
4733       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4734       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4735       vec_free (dscp_str);
4736     }
4737   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4738   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4739     {
4740       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4741       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4742       vec_free (dscp_str);
4743     }
4744   vat_json_object_add_string_copy (node, "violate_action",
4745                                    violate_action_str);
4746   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4747     {
4748       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4749       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4750       vec_free (dscp_str);
4751     }
4752
4753   vec_free (rate_type_str);
4754   vec_free (round_type_str);
4755   vec_free (type_str);
4756   vec_free (conform_action_str);
4757   vec_free (exceed_action_str);
4758   vec_free (violate_action_str);
4759 }
4760
4761 static void
4762 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4763                                            mp)
4764 {
4765   vat_main_t *vam = &vat_main;
4766   int i, count = ntohl (mp->count);
4767
4768   if (count > 0)
4769     print (vam->ofp, "classify table ids (%d) : ", count);
4770   for (i = 0; i < count; i++)
4771     {
4772       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4773       print (vam->ofp, (i < count - 1) ? "," : "");
4774     }
4775   vam->retval = ntohl (mp->retval);
4776   vam->result_ready = 1;
4777 }
4778
4779 static void
4780   vl_api_classify_table_ids_reply_t_handler_json
4781   (vl_api_classify_table_ids_reply_t * mp)
4782 {
4783   vat_main_t *vam = &vat_main;
4784   int i, count = ntohl (mp->count);
4785
4786   if (count > 0)
4787     {
4788       vat_json_node_t node;
4789
4790       vat_json_init_object (&node);
4791       for (i = 0; i < count; i++)
4792         {
4793           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4794         }
4795       vat_json_print (vam->ofp, &node);
4796       vat_json_free (&node);
4797     }
4798   vam->retval = ntohl (mp->retval);
4799   vam->result_ready = 1;
4800 }
4801
4802 static void
4803   vl_api_classify_table_by_interface_reply_t_handler
4804   (vl_api_classify_table_by_interface_reply_t * mp)
4805 {
4806   vat_main_t *vam = &vat_main;
4807   u32 table_id;
4808
4809   table_id = ntohl (mp->l2_table_id);
4810   if (table_id != ~0)
4811     print (vam->ofp, "l2 table id : %d", table_id);
4812   else
4813     print (vam->ofp, "l2 table id : No input ACL tables configured");
4814   table_id = ntohl (mp->ip4_table_id);
4815   if (table_id != ~0)
4816     print (vam->ofp, "ip4 table id : %d", table_id);
4817   else
4818     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4819   table_id = ntohl (mp->ip6_table_id);
4820   if (table_id != ~0)
4821     print (vam->ofp, "ip6 table id : %d", table_id);
4822   else
4823     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4824   vam->retval = ntohl (mp->retval);
4825   vam->result_ready = 1;
4826 }
4827
4828 static void
4829   vl_api_classify_table_by_interface_reply_t_handler_json
4830   (vl_api_classify_table_by_interface_reply_t * mp)
4831 {
4832   vat_main_t *vam = &vat_main;
4833   vat_json_node_t node;
4834
4835   vat_json_init_object (&node);
4836
4837   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4838   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4839   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4840
4841   vat_json_print (vam->ofp, &node);
4842   vat_json_free (&node);
4843
4844   vam->retval = ntohl (mp->retval);
4845   vam->result_ready = 1;
4846 }
4847
4848 static void vl_api_policer_add_del_reply_t_handler
4849   (vl_api_policer_add_del_reply_t * mp)
4850 {
4851   vat_main_t *vam = &vat_main;
4852   i32 retval = ntohl (mp->retval);
4853   if (vam->async_mode)
4854     {
4855       vam->async_errors += (retval < 0);
4856     }
4857   else
4858     {
4859       vam->retval = retval;
4860       vam->result_ready = 1;
4861       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4862         /*
4863          * Note: this is just barely thread-safe, depends on
4864          * the main thread spinning waiting for an answer...
4865          */
4866         errmsg ("policer index %d", ntohl (mp->policer_index));
4867     }
4868 }
4869
4870 static void vl_api_policer_add_del_reply_t_handler_json
4871   (vl_api_policer_add_del_reply_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t node;
4875
4876   vat_json_init_object (&node);
4877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4878   vat_json_object_add_uint (&node, "policer_index",
4879                             ntohl (mp->policer_index));
4880
4881   vat_json_print (vam->ofp, &node);
4882   vat_json_free (&node);
4883
4884   vam->retval = ntohl (mp->retval);
4885   vam->result_ready = 1;
4886 }
4887
4888 /* Format hex dump. */
4889 u8 *
4890 format_hex_bytes (u8 * s, va_list * va)
4891 {
4892   u8 *bytes = va_arg (*va, u8 *);
4893   int n_bytes = va_arg (*va, int);
4894   uword i;
4895
4896   /* Print short or long form depending on byte count. */
4897   uword short_form = n_bytes <= 32;
4898   u32 indent = format_get_indent (s);
4899
4900   if (n_bytes == 0)
4901     return s;
4902
4903   for (i = 0; i < n_bytes; i++)
4904     {
4905       if (!short_form && (i % 32) == 0)
4906         s = format (s, "%08x: ", i);
4907       s = format (s, "%02x", bytes[i]);
4908       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4909         s = format (s, "\n%U", format_white_space, indent);
4910     }
4911
4912   return s;
4913 }
4914
4915 static void
4916 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4917                                             * mp)
4918 {
4919   vat_main_t *vam = &vat_main;
4920   i32 retval = ntohl (mp->retval);
4921   if (retval == 0)
4922     {
4923       print (vam->ofp, "classify table info :");
4924       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4925              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4926              ntohl (mp->miss_next_index));
4927       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4928              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4929              ntohl (mp->match_n_vectors));
4930       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4931              ntohl (mp->mask_length));
4932     }
4933   vam->retval = retval;
4934   vam->result_ready = 1;
4935 }
4936
4937 static void
4938   vl_api_classify_table_info_reply_t_handler_json
4939   (vl_api_classify_table_info_reply_t * mp)
4940 {
4941   vat_main_t *vam = &vat_main;
4942   vat_json_node_t node;
4943
4944   i32 retval = ntohl (mp->retval);
4945   if (retval == 0)
4946     {
4947       vat_json_init_object (&node);
4948
4949       vat_json_object_add_int (&node, "sessions",
4950                                ntohl (mp->active_sessions));
4951       vat_json_object_add_int (&node, "nexttbl",
4952                                ntohl (mp->next_table_index));
4953       vat_json_object_add_int (&node, "nextnode",
4954                                ntohl (mp->miss_next_index));
4955       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4956       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4957       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4958       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4959                       ntohl (mp->mask_length), 0);
4960       vat_json_object_add_string_copy (&node, "mask", s);
4961
4962       vat_json_print (vam->ofp, &node);
4963       vat_json_free (&node);
4964     }
4965   vam->retval = ntohl (mp->retval);
4966   vam->result_ready = 1;
4967 }
4968
4969 static void
4970 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4971                                            mp)
4972 {
4973   vat_main_t *vam = &vat_main;
4974
4975   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4976          ntohl (mp->hit_next_index), ntohl (mp->advance),
4977          ntohl (mp->opaque_index));
4978   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4979          ntohl (mp->match_length));
4980 }
4981
4982 static void
4983   vl_api_classify_session_details_t_handler_json
4984   (vl_api_classify_session_details_t * mp)
4985 {
4986   vat_main_t *vam = &vat_main;
4987   vat_json_node_t *node = NULL;
4988
4989   if (VAT_JSON_ARRAY != vam->json_tree.type)
4990     {
4991       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4992       vat_json_init_array (&vam->json_tree);
4993     }
4994   node = vat_json_array_add (&vam->json_tree);
4995
4996   vat_json_init_object (node);
4997   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4998   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4999   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5000   u8 *s =
5001     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5002             0);
5003   vat_json_object_add_string_copy (node, "match", s);
5004 }
5005
5006 static void vl_api_pg_create_interface_reply_t_handler
5007   (vl_api_pg_create_interface_reply_t * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010
5011   vam->retval = ntohl (mp->retval);
5012   vam->result_ready = 1;
5013 }
5014
5015 static void vl_api_pg_create_interface_reply_t_handler_json
5016   (vl_api_pg_create_interface_reply_t * mp)
5017 {
5018   vat_main_t *vam = &vat_main;
5019   vat_json_node_t node;
5020
5021   i32 retval = ntohl (mp->retval);
5022   if (retval == 0)
5023     {
5024       vat_json_init_object (&node);
5025
5026       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5027
5028       vat_json_print (vam->ofp, &node);
5029       vat_json_free (&node);
5030     }
5031   vam->retval = ntohl (mp->retval);
5032   vam->result_ready = 1;
5033 }
5034
5035 static void vl_api_policer_classify_details_t_handler
5036   (vl_api_policer_classify_details_t * mp)
5037 {
5038   vat_main_t *vam = &vat_main;
5039
5040   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5041          ntohl (mp->table_index));
5042 }
5043
5044 static void vl_api_policer_classify_details_t_handler_json
5045   (vl_api_policer_classify_details_t * mp)
5046 {
5047   vat_main_t *vam = &vat_main;
5048   vat_json_node_t *node;
5049
5050   if (VAT_JSON_ARRAY != vam->json_tree.type)
5051     {
5052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5053       vat_json_init_array (&vam->json_tree);
5054     }
5055   node = vat_json_array_add (&vam->json_tree);
5056
5057   vat_json_init_object (node);
5058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5059   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5060 }
5061
5062 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5063   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   i32 retval = ntohl (mp->retval);
5067   if (vam->async_mode)
5068     {
5069       vam->async_errors += (retval < 0);
5070     }
5071   else
5072     {
5073       vam->retval = retval;
5074       vam->sw_if_index = ntohl (mp->sw_if_index);
5075       vam->result_ready = 1;
5076     }
5077   vam->regenerate_interface_table = 1;
5078 }
5079
5080 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5081   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5082 {
5083   vat_main_t *vam = &vat_main;
5084   vat_json_node_t node;
5085
5086   vat_json_init_object (&node);
5087   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5088   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5089
5090   vat_json_print (vam->ofp, &node);
5091   vat_json_free (&node);
5092
5093   vam->retval = ntohl (mp->retval);
5094   vam->result_ready = 1;
5095 }
5096
5097 static void vl_api_flow_classify_details_t_handler
5098   (vl_api_flow_classify_details_t * mp)
5099 {
5100   vat_main_t *vam = &vat_main;
5101
5102   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5103          ntohl (mp->table_index));
5104 }
5105
5106 static void vl_api_flow_classify_details_t_handler_json
5107   (vl_api_flow_classify_details_t * mp)
5108 {
5109   vat_main_t *vam = &vat_main;
5110   vat_json_node_t *node;
5111
5112   if (VAT_JSON_ARRAY != vam->json_tree.type)
5113     {
5114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5115       vat_json_init_array (&vam->json_tree);
5116     }
5117   node = vat_json_array_add (&vam->json_tree);
5118
5119   vat_json_init_object (node);
5120   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5121   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5122 }
5123
5124 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5125 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5126 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5127 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5128 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5129 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5130 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5131 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5132 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5133 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5134
5135 /*
5136  * Generate boilerplate reply handlers, which
5137  * dig the return value out of the xxx_reply_t API message,
5138  * stick it into vam->retval, and set vam->result_ready
5139  *
5140  * Could also do this by pointing N message decode slots at
5141  * a single function, but that could break in subtle ways.
5142  */
5143
5144 #define foreach_standard_reply_retval_handler           \
5145 _(sw_interface_set_flags_reply)                         \
5146 _(sw_interface_add_del_address_reply)                   \
5147 _(sw_interface_set_rx_mode_reply)                       \
5148 _(sw_interface_set_rx_placement_reply)                  \
5149 _(sw_interface_set_table_reply)                         \
5150 _(sw_interface_set_mpls_enable_reply)                   \
5151 _(sw_interface_set_vpath_reply)                         \
5152 _(sw_interface_set_vxlan_bypass_reply)                  \
5153 _(sw_interface_set_geneve_bypass_reply)                 \
5154 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5155 _(sw_interface_set_l2_bridge_reply)                     \
5156 _(bridge_domain_add_del_reply)                          \
5157 _(sw_interface_set_l2_xconnect_reply)                   \
5158 _(l2fib_add_del_reply)                                  \
5159 _(l2fib_flush_int_reply)                                \
5160 _(l2fib_flush_bd_reply)                                 \
5161 _(ip_add_del_route_reply)                               \
5162 _(ip_table_add_del_reply)                               \
5163 _(ip_mroute_add_del_reply)                              \
5164 _(mpls_route_add_del_reply)                             \
5165 _(mpls_table_add_del_reply)                             \
5166 _(mpls_ip_bind_unbind_reply)                            \
5167 _(bier_route_add_del_reply)                             \
5168 _(bier_table_add_del_reply)                             \
5169 _(proxy_arp_add_del_reply)                              \
5170 _(proxy_arp_intfc_enable_disable_reply)                 \
5171 _(sw_interface_set_unnumbered_reply)                    \
5172 _(ip_neighbor_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 _(delete_loopback_reply)                                \
5218 _(bd_ip_mac_add_del_reply)                              \
5219 _(bd_ip_mac_flush_reply)                                \
5220 _(want_interface_events_reply)                          \
5221 _(cop_interface_enable_disable_reply)                   \
5222 _(cop_whitelist_enable_disable_reply)                   \
5223 _(sw_interface_clear_stats_reply)                       \
5224 _(ioam_enable_reply)                                    \
5225 _(ioam_disable_reply)                                   \
5226 _(one_add_del_locator_reply)                            \
5227 _(one_add_del_local_eid_reply)                          \
5228 _(one_add_del_remote_mapping_reply)                     \
5229 _(one_add_del_adjacency_reply)                          \
5230 _(one_add_del_map_resolver_reply)                       \
5231 _(one_add_del_map_server_reply)                         \
5232 _(one_enable_disable_reply)                             \
5233 _(one_rloc_probe_enable_disable_reply)                  \
5234 _(one_map_register_enable_disable_reply)                \
5235 _(one_map_register_set_ttl_reply)                       \
5236 _(one_set_transport_protocol_reply)                     \
5237 _(one_map_register_fallback_threshold_reply)            \
5238 _(one_pitr_set_locator_set_reply)                       \
5239 _(one_map_request_mode_reply)                           \
5240 _(one_add_del_map_request_itr_rlocs_reply)              \
5241 _(one_eid_table_add_del_map_reply)                      \
5242 _(one_use_petr_reply)                                   \
5243 _(one_stats_enable_disable_reply)                       \
5244 _(one_add_del_l2_arp_entry_reply)                       \
5245 _(one_add_del_ndp_entry_reply)                          \
5246 _(one_stats_flush_reply)                                \
5247 _(one_enable_disable_xtr_mode_reply)                    \
5248 _(one_enable_disable_pitr_mode_reply)                   \
5249 _(one_enable_disable_petr_mode_reply)                   \
5250 _(gpe_enable_disable_reply)                             \
5251 _(gpe_set_encap_mode_reply)                             \
5252 _(gpe_add_del_iface_reply)                              \
5253 _(gpe_add_del_native_fwd_rpath_reply)                   \
5254 _(af_packet_delete_reply)                               \
5255 _(policer_classify_set_interface_reply)                 \
5256 _(netmap_create_reply)                                  \
5257 _(netmap_delete_reply)                                  \
5258 _(set_ipfix_exporter_reply)                             \
5259 _(set_ipfix_classify_stream_reply)                      \
5260 _(ipfix_classify_table_add_del_reply)                   \
5261 _(flow_classify_set_interface_reply)                    \
5262 _(sw_interface_span_enable_disable_reply)               \
5263 _(pg_capture_reply)                                     \
5264 _(pg_enable_disable_reply)                              \
5265 _(ip_source_and_port_range_check_add_del_reply)         \
5266 _(ip_source_and_port_range_check_interface_add_del_reply)\
5267 _(delete_subif_reply)                                   \
5268 _(l2_interface_pbb_tag_rewrite_reply)                   \
5269 _(set_punt_reply)                                       \
5270 _(feature_enable_disable_reply)                         \
5271 _(sw_interface_tag_add_del_reply)                       \
5272 _(hw_interface_set_mtu_reply)                           \
5273 _(p2p_ethernet_add_reply)                               \
5274 _(p2p_ethernet_del_reply)                               \
5275 _(lldp_config_reply)                                    \
5276 _(sw_interface_set_lldp_reply)                          \
5277 _(tcp_configure_src_addresses_reply)                    \
5278 _(dns_enable_disable_reply)                             \
5279 _(dns_name_server_add_del_reply)                        \
5280 _(session_rule_add_del_reply)                           \
5281 _(ip_container_proxy_add_del_reply)                     \
5282 _(output_acl_set_interface_reply)                       \
5283 _(qos_record_enable_disable_reply)
5284
5285 #define _(n)                                    \
5286     static void vl_api_##n##_t_handler          \
5287     (vl_api_##n##_t * mp)                       \
5288     {                                           \
5289         vat_main_t * vam = &vat_main;           \
5290         i32 retval = ntohl(mp->retval);         \
5291         if (vam->async_mode) {                  \
5292             vam->async_errors += (retval < 0);  \
5293         } else {                                \
5294             vam->retval = retval;               \
5295             vam->result_ready = 1;              \
5296         }                                       \
5297     }
5298 foreach_standard_reply_retval_handler;
5299 #undef _
5300
5301 #define _(n)                                    \
5302     static void vl_api_##n##_t_handler_json     \
5303     (vl_api_##n##_t * mp)                       \
5304     {                                           \
5305         vat_main_t * vam = &vat_main;           \
5306         vat_json_node_t node;                   \
5307         vat_json_init_object(&node);            \
5308         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5309         vat_json_print(vam->ofp, &node);        \
5310         vam->retval = ntohl(mp->retval);        \
5311         vam->result_ready = 1;                  \
5312     }
5313 foreach_standard_reply_retval_handler;
5314 #undef _
5315
5316 /*
5317  * Table of message reply handlers, must include boilerplate handlers
5318  * we just generated
5319  */
5320
5321 #define foreach_vpe_api_reply_msg                                       \
5322 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5323 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5324 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5325 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5326 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5327 _(CLI_REPLY, cli_reply)                                                 \
5328 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5329 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5330   sw_interface_add_del_address_reply)                                   \
5331 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5332 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5333 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5334 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5335 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5336 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5337 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5338 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5339 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5340 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5341   sw_interface_set_l2_xconnect_reply)                                   \
5342 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5343   sw_interface_set_l2_bridge_reply)                                     \
5344 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5345 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5346 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5347 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5348 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5349 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5350 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5351 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5352 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5353 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5354 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5355 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5356 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5357 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5358 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5359 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5360 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5361 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5362 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5363 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5364 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5365 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5366 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5367 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5368 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5369 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5370 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5371 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5372 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5373 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5374   proxy_arp_intfc_enable_disable_reply)                                 \
5375 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5376 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5377   sw_interface_set_unnumbered_reply)                                    \
5378 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5379 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5380 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5381 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5382 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5383 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5384 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5385 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5386 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5387 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5388   sw_interface_ip6_enable_disable_reply)                                \
5389 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5390 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5391 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5392   sw_interface_ip6nd_ra_prefix_reply)                                   \
5393 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5394   sw_interface_ip6nd_ra_config_reply)                                   \
5395 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5396 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5397 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5398 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5399 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5400 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5401 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5402 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5403 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5404 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5405 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5406 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5407 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5408 classify_set_interface_ip_table_reply)                                  \
5409 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5410   classify_set_interface_l2_tables_reply)                               \
5411 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5412 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5413 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5414 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5415 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5416   l2tpv3_interface_enable_disable_reply)                                \
5417 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5418 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5419 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5420 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5421 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5422 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5423 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5424 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5425 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5426 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5427 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5428 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5429 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5430 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5431 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5432 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5433 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5434 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5435 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5436 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5437 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5438 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5439 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5440 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5441 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5442 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5443 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5444 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5445 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5446 _(L2_MACS_EVENT, l2_macs_event)                                         \
5447 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5448 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5449 _(IP_DETAILS, ip_details)                                               \
5450 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5451 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5452 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5453 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5454 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5455 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5456 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5457 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5458 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5459 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5460 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5461 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5462 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5463 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5464 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5465 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5466 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5467 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5468 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5469 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5470 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5471 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5472 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5473 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5474 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5475 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5476 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5477 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5478 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5479 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5480 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5481   one_map_register_enable_disable_reply)                                \
5482 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5483 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5484 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5485 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5486   one_map_register_fallback_threshold_reply)                            \
5487 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5488   one_rloc_probe_enable_disable_reply)                                  \
5489 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5490 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5491 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5492 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5493 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5494 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5495 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5496 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5497 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5498 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5499 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5500 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5501 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5502 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5503 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5504 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5505   show_one_stats_enable_disable_reply)                                  \
5506 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5507 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5508 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5509 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5510 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5511 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5512 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5513 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5514   one_enable_disable_pitr_mode_reply)                                   \
5515 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5516   one_enable_disable_petr_mode_reply)                                   \
5517 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5518 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5519 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5520 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5521 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5522 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5523 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5524 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5525 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5526 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5527 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5528 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5529   gpe_add_del_native_fwd_rpath_reply)                                   \
5530 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5531   gpe_fwd_entry_path_details)                                           \
5532 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5533 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5534   one_add_del_map_request_itr_rlocs_reply)                              \
5535 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5536   one_get_map_request_itr_rlocs_reply)                                  \
5537 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5538 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5539 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5540 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5541 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5542 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5543   show_one_map_register_state_reply)                                    \
5544 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5545 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5546   show_one_map_register_fallback_threshold_reply)                       \
5547 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5548 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5549 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5550 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5551 _(POLICER_DETAILS, policer_details)                                     \
5552 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5553 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5554 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5555 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5556 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5557 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5558 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5559 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5560 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5561 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5562 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5563 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5564 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5565 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5566 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5567 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5568 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5569 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5570 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5571 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5572 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5573 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5574 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5575 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5576 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5577  ip_source_and_port_range_check_add_del_reply)                          \
5578 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5579  ip_source_and_port_range_check_interface_add_del_reply)                \
5580 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5581 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5582 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5583 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5584 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5585 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5586 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5587 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5588 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5589 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5590 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5591 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5592 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5593 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5594 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5595 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5596 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5597 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5598 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5599 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5600 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5601 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5602 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5603 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5604 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5605 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5606 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5607 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5608
5609 #define foreach_standalone_reply_msg                                    \
5610 _(SW_INTERFACE_EVENT, sw_interface_event)
5611
5612 typedef struct
5613 {
5614   u8 *name;
5615   u32 value;
5616 } name_sort_t;
5617
5618 #define STR_VTR_OP_CASE(op)     \
5619     case L2_VTR_ ## op:         \
5620         return "" # op;
5621
5622 static const char *
5623 str_vtr_op (u32 vtr_op)
5624 {
5625   switch (vtr_op)
5626     {
5627       STR_VTR_OP_CASE (DISABLED);
5628       STR_VTR_OP_CASE (PUSH_1);
5629       STR_VTR_OP_CASE (PUSH_2);
5630       STR_VTR_OP_CASE (POP_1);
5631       STR_VTR_OP_CASE (POP_2);
5632       STR_VTR_OP_CASE (TRANSLATE_1_1);
5633       STR_VTR_OP_CASE (TRANSLATE_1_2);
5634       STR_VTR_OP_CASE (TRANSLATE_2_1);
5635       STR_VTR_OP_CASE (TRANSLATE_2_2);
5636     }
5637
5638   return "UNKNOWN";
5639 }
5640
5641 static int
5642 dump_sub_interface_table (vat_main_t * vam)
5643 {
5644   const sw_interface_subif_t *sub = NULL;
5645
5646   if (vam->json_output)
5647     {
5648       clib_warning
5649         ("JSON output supported only for VPE API calls and dump_stats_table");
5650       return -99;
5651     }
5652
5653   print (vam->ofp,
5654          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5655          "Interface", "sw_if_index",
5656          "sub id", "dot1ad", "tags", "outer id",
5657          "inner id", "exact", "default", "outer any", "inner any");
5658
5659   vec_foreach (sub, vam->sw_if_subif_table)
5660   {
5661     print (vam->ofp,
5662            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5663            sub->interface_name,
5664            sub->sw_if_index,
5665            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5666            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5667            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5668            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5669     if (sub->vtr_op != L2_VTR_DISABLED)
5670       {
5671         print (vam->ofp,
5672                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5673                "tag1: %d tag2: %d ]",
5674                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5675                sub->vtr_tag1, sub->vtr_tag2);
5676       }
5677   }
5678
5679   return 0;
5680 }
5681
5682 static int
5683 name_sort_cmp (void *a1, void *a2)
5684 {
5685   name_sort_t *n1 = a1;
5686   name_sort_t *n2 = a2;
5687
5688   return strcmp ((char *) n1->name, (char *) n2->name);
5689 }
5690
5691 static int
5692 dump_interface_table (vat_main_t * vam)
5693 {
5694   hash_pair_t *p;
5695   name_sort_t *nses = 0, *ns;
5696
5697   if (vam->json_output)
5698     {
5699       clib_warning
5700         ("JSON output supported only for VPE API calls and dump_stats_table");
5701       return -99;
5702     }
5703
5704   /* *INDENT-OFF* */
5705   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5706   ({
5707     vec_add2 (nses, ns, 1);
5708     ns->name = (u8 *)(p->key);
5709     ns->value = (u32) p->value[0];
5710   }));
5711   /* *INDENT-ON* */
5712
5713   vec_sort_with_function (nses, name_sort_cmp);
5714
5715   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5716   vec_foreach (ns, nses)
5717   {
5718     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5719   }
5720   vec_free (nses);
5721   return 0;
5722 }
5723
5724 static int
5725 dump_ip_table (vat_main_t * vam, int is_ipv6)
5726 {
5727   const ip_details_t *det = NULL;
5728   const ip_address_details_t *address = NULL;
5729   u32 i = ~0;
5730
5731   print (vam->ofp, "%-12s", "sw_if_index");
5732
5733   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5734   {
5735     i++;
5736     if (!det->present)
5737       {
5738         continue;
5739       }
5740     print (vam->ofp, "%-12d", i);
5741     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5742     if (!det->addr)
5743       {
5744         continue;
5745       }
5746     vec_foreach (address, det->addr)
5747     {
5748       print (vam->ofp,
5749              "            %-30U%-13d",
5750              is_ipv6 ? format_ip6_address : format_ip4_address,
5751              address->ip, address->prefix_length);
5752     }
5753   }
5754
5755   return 0;
5756 }
5757
5758 static int
5759 dump_ipv4_table (vat_main_t * vam)
5760 {
5761   if (vam->json_output)
5762     {
5763       clib_warning
5764         ("JSON output supported only for VPE API calls and dump_stats_table");
5765       return -99;
5766     }
5767
5768   return dump_ip_table (vam, 0);
5769 }
5770
5771 static int
5772 dump_ipv6_table (vat_main_t * vam)
5773 {
5774   if (vam->json_output)
5775     {
5776       clib_warning
5777         ("JSON output supported only for VPE API calls and dump_stats_table");
5778       return -99;
5779     }
5780
5781   return dump_ip_table (vam, 1);
5782 }
5783
5784 /*
5785  * Pass CLI buffers directly in the CLI_INBAND API message,
5786  * instead of an additional shared memory area.
5787  */
5788 static int
5789 exec_inband (vat_main_t * vam)
5790 {
5791   vl_api_cli_inband_t *mp;
5792   unformat_input_t *i = vam->input;
5793   int ret;
5794
5795   if (vec_len (i->buffer) == 0)
5796     return -1;
5797
5798   if (vam->exec_mode == 0 && unformat (i, "mode"))
5799     {
5800       vam->exec_mode = 1;
5801       return 0;
5802     }
5803   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5804     {
5805       vam->exec_mode = 0;
5806       return 0;
5807     }
5808
5809   /*
5810    * In order for the CLI command to work, it
5811    * must be a vector ending in \n, not a C-string ending
5812    * in \n\0.
5813    */
5814   u32 len = vec_len (vam->input->buffer);
5815   M2 (CLI_INBAND, mp, len);
5816   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5817
5818   S (mp);
5819   W (ret);
5820   /* json responses may or may not include a useful reply... */
5821   if (vec_len (vam->cmd_reply))
5822     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5823   return ret;
5824 }
5825
5826 int
5827 exec (vat_main_t * vam)
5828 {
5829   return exec_inband (vam);
5830 }
5831
5832 static int
5833 api_create_loopback (vat_main_t * vam)
5834 {
5835   unformat_input_t *i = vam->input;
5836   vl_api_create_loopback_t *mp;
5837   vl_api_create_loopback_instance_t *mp_lbi;
5838   u8 mac_address[6];
5839   u8 mac_set = 0;
5840   u8 is_specified = 0;
5841   u32 user_instance = 0;
5842   int ret;
5843
5844   clib_memset (mac_address, 0, sizeof (mac_address));
5845
5846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5847     {
5848       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5849         mac_set = 1;
5850       if (unformat (i, "instance %d", &user_instance))
5851         is_specified = 1;
5852       else
5853         break;
5854     }
5855
5856   if (is_specified)
5857     {
5858       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5859       mp_lbi->is_specified = is_specified;
5860       if (is_specified)
5861         mp_lbi->user_instance = htonl (user_instance);
5862       if (mac_set)
5863         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5864       S (mp_lbi);
5865     }
5866   else
5867     {
5868       /* Construct the API message */
5869       M (CREATE_LOOPBACK, mp);
5870       if (mac_set)
5871         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5872       S (mp);
5873     }
5874
5875   W (ret);
5876   return ret;
5877 }
5878
5879 static int
5880 api_delete_loopback (vat_main_t * vam)
5881 {
5882   unformat_input_t *i = vam->input;
5883   vl_api_delete_loopback_t *mp;
5884   u32 sw_if_index = ~0;
5885   int ret;
5886
5887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5888     {
5889       if (unformat (i, "sw_if_index %d", &sw_if_index))
5890         ;
5891       else
5892         break;
5893     }
5894
5895   if (sw_if_index == ~0)
5896     {
5897       errmsg ("missing sw_if_index");
5898       return -99;
5899     }
5900
5901   /* Construct the API message */
5902   M (DELETE_LOOPBACK, mp);
5903   mp->sw_if_index = ntohl (sw_if_index);
5904
5905   S (mp);
5906   W (ret);
5907   return ret;
5908 }
5909
5910 static int
5911 api_want_interface_events (vat_main_t * vam)
5912 {
5913   unformat_input_t *i = vam->input;
5914   vl_api_want_interface_events_t *mp;
5915   int enable = -1;
5916   int ret;
5917
5918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5919     {
5920       if (unformat (i, "enable"))
5921         enable = 1;
5922       else if (unformat (i, "disable"))
5923         enable = 0;
5924       else
5925         break;
5926     }
5927
5928   if (enable == -1)
5929     {
5930       errmsg ("missing enable|disable");
5931       return -99;
5932     }
5933
5934   M (WANT_INTERFACE_EVENTS, mp);
5935   mp->enable_disable = enable;
5936
5937   vam->interface_event_display = enable;
5938
5939   S (mp);
5940   W (ret);
5941   return ret;
5942 }
5943
5944
5945 /* Note: non-static, called once to set up the initial intfc table */
5946 int
5947 api_sw_interface_dump (vat_main_t * vam)
5948 {
5949   vl_api_sw_interface_dump_t *mp;
5950   vl_api_control_ping_t *mp_ping;
5951   hash_pair_t *p;
5952   name_sort_t *nses = 0, *ns;
5953   sw_interface_subif_t *sub = NULL;
5954   int ret;
5955
5956   /* Toss the old name table */
5957   /* *INDENT-OFF* */
5958   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5959   ({
5960     vec_add2 (nses, ns, 1);
5961     ns->name = (u8 *)(p->key);
5962     ns->value = (u32) p->value[0];
5963   }));
5964   /* *INDENT-ON* */
5965
5966   hash_free (vam->sw_if_index_by_interface_name);
5967
5968   vec_foreach (ns, nses) vec_free (ns->name);
5969
5970   vec_free (nses);
5971
5972   vec_foreach (sub, vam->sw_if_subif_table)
5973   {
5974     vec_free (sub->interface_name);
5975   }
5976   vec_free (vam->sw_if_subif_table);
5977
5978   /* recreate the interface name hash table */
5979   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5980
5981   /*
5982    * Ask for all interface names. Otherwise, the epic catalog of
5983    * name filters becomes ridiculously long, and vat ends up needing
5984    * to be taught about new interface types.
5985    */
5986   M (SW_INTERFACE_DUMP, mp);
5987   S (mp);
5988
5989   /* Use a control ping for synchronization */
5990   MPING (CONTROL_PING, mp_ping);
5991   S (mp_ping);
5992
5993   W (ret);
5994   return ret;
5995 }
5996
5997 static int
5998 api_sw_interface_set_flags (vat_main_t * vam)
5999 {
6000   unformat_input_t *i = vam->input;
6001   vl_api_sw_interface_set_flags_t *mp;
6002   u32 sw_if_index;
6003   u8 sw_if_index_set = 0;
6004   u8 admin_up = 0;
6005   int ret;
6006
6007   /* Parse args required to build the message */
6008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6009     {
6010       if (unformat (i, "admin-up"))
6011         admin_up = 1;
6012       else if (unformat (i, "admin-down"))
6013         admin_up = 0;
6014       else
6015         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6016         sw_if_index_set = 1;
6017       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6018         sw_if_index_set = 1;
6019       else
6020         break;
6021     }
6022
6023   if (sw_if_index_set == 0)
6024     {
6025       errmsg ("missing interface name or sw_if_index");
6026       return -99;
6027     }
6028
6029   /* Construct the API message */
6030   M (SW_INTERFACE_SET_FLAGS, mp);
6031   mp->sw_if_index = ntohl (sw_if_index);
6032   mp->admin_up_down = admin_up;
6033
6034   /* send it... */
6035   S (mp);
6036
6037   /* Wait for a reply, return the good/bad news... */
6038   W (ret);
6039   return ret;
6040 }
6041
6042 static int
6043 api_sw_interface_set_rx_mode (vat_main_t * vam)
6044 {
6045   unformat_input_t *i = vam->input;
6046   vl_api_sw_interface_set_rx_mode_t *mp;
6047   u32 sw_if_index;
6048   u8 sw_if_index_set = 0;
6049   int ret;
6050   u8 queue_id_valid = 0;
6051   u32 queue_id;
6052   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6053
6054   /* Parse args required to build the message */
6055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6056     {
6057       if (unformat (i, "queue %d", &queue_id))
6058         queue_id_valid = 1;
6059       else if (unformat (i, "polling"))
6060         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6061       else if (unformat (i, "interrupt"))
6062         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6063       else if (unformat (i, "adaptive"))
6064         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6065       else
6066         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6067         sw_if_index_set = 1;
6068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6069         sw_if_index_set = 1;
6070       else
6071         break;
6072     }
6073
6074   if (sw_if_index_set == 0)
6075     {
6076       errmsg ("missing interface name or sw_if_index");
6077       return -99;
6078     }
6079   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6080     {
6081       errmsg ("missing rx-mode");
6082       return -99;
6083     }
6084
6085   /* Construct the API message */
6086   M (SW_INTERFACE_SET_RX_MODE, mp);
6087   mp->sw_if_index = ntohl (sw_if_index);
6088   mp->mode = mode;
6089   mp->queue_id_valid = queue_id_valid;
6090   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6091
6092   /* send it... */
6093   S (mp);
6094
6095   /* Wait for a reply, return the good/bad news... */
6096   W (ret);
6097   return ret;
6098 }
6099
6100 static int
6101 api_sw_interface_set_rx_placement (vat_main_t * vam)
6102 {
6103   unformat_input_t *i = vam->input;
6104   vl_api_sw_interface_set_rx_placement_t *mp;
6105   u32 sw_if_index;
6106   u8 sw_if_index_set = 0;
6107   int ret;
6108   u8 is_main = 0;
6109   u32 queue_id, thread_index;
6110
6111   /* Parse args required to build the message */
6112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6113     {
6114       if (unformat (i, "queue %d", &queue_id))
6115         ;
6116       else if (unformat (i, "main"))
6117         is_main = 1;
6118       else if (unformat (i, "worker %d", &thread_index))
6119         ;
6120       else
6121         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6122         sw_if_index_set = 1;
6123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6124         sw_if_index_set = 1;
6125       else
6126         break;
6127     }
6128
6129   if (sw_if_index_set == 0)
6130     {
6131       errmsg ("missing interface name or sw_if_index");
6132       return -99;
6133     }
6134
6135   if (is_main)
6136     thread_index = 0;
6137   /* Construct the API message */
6138   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6139   mp->sw_if_index = ntohl (sw_if_index);
6140   mp->worker_id = ntohl (thread_index);
6141   mp->queue_id = ntohl (queue_id);
6142   mp->is_main = is_main;
6143
6144   /* send it... */
6145   S (mp);
6146   /* Wait for a reply, return the good/bad news... */
6147   W (ret);
6148   return ret;
6149 }
6150
6151 static void vl_api_sw_interface_rx_placement_details_t_handler
6152   (vl_api_sw_interface_rx_placement_details_t * mp)
6153 {
6154   vat_main_t *vam = &vat_main;
6155   u32 worker_id = ntohl (mp->worker_id);
6156
6157   print (vam->ofp,
6158          "\n%-11d %-11s %-6d %-5d %-9s",
6159          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6160          worker_id, ntohl (mp->queue_id),
6161          (mp->mode ==
6162           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6163 }
6164
6165 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6166   (vl_api_sw_interface_rx_placement_details_t * mp)
6167 {
6168   vat_main_t *vam = &vat_main;
6169   vat_json_node_t *node = NULL;
6170
6171   if (VAT_JSON_ARRAY != vam->json_tree.type)
6172     {
6173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6174       vat_json_init_array (&vam->json_tree);
6175     }
6176   node = vat_json_array_add (&vam->json_tree);
6177
6178   vat_json_init_object (node);
6179   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6180   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6181   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6182   vat_json_object_add_uint (node, "mode", mp->mode);
6183 }
6184
6185 static int
6186 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_sw_interface_rx_placement_dump_t *mp;
6190   vl_api_control_ping_t *mp_ping;
6191   int ret;
6192   u32 sw_if_index;
6193   u8 sw_if_index_set = 0;
6194
6195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6196     {
6197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6198         sw_if_index_set++;
6199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6200         sw_if_index_set++;
6201       else
6202         break;
6203     }
6204
6205   print (vam->ofp,
6206          "\n%-11s %-11s %-6s %-5s %-4s",
6207          "sw_if_index", "main/worker", "thread", "queue", "mode");
6208
6209   /* Dump Interface rx placement */
6210   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6211
6212   if (sw_if_index_set)
6213     mp->sw_if_index = htonl (sw_if_index);
6214   else
6215     mp->sw_if_index = ~0;
6216
6217   S (mp);
6218
6219   /* Use a control ping for synchronization */
6220   MPING (CONTROL_PING, mp_ping);
6221   S (mp_ping);
6222
6223   W (ret);
6224   return ret;
6225 }
6226
6227 static int
6228 api_sw_interface_clear_stats (vat_main_t * vam)
6229 {
6230   unformat_input_t *i = vam->input;
6231   vl_api_sw_interface_clear_stats_t *mp;
6232   u32 sw_if_index;
6233   u8 sw_if_index_set = 0;
6234   int ret;
6235
6236   /* Parse args required to build the message */
6237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6238     {
6239       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6240         sw_if_index_set = 1;
6241       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6242         sw_if_index_set = 1;
6243       else
6244         break;
6245     }
6246
6247   /* Construct the API message */
6248   M (SW_INTERFACE_CLEAR_STATS, mp);
6249
6250   if (sw_if_index_set == 1)
6251     mp->sw_if_index = ntohl (sw_if_index);
6252   else
6253     mp->sw_if_index = ~0;
6254
6255   /* send it... */
6256   S (mp);
6257
6258   /* Wait for a reply, return the good/bad news... */
6259   W (ret);
6260   return ret;
6261 }
6262
6263 static int
6264 api_sw_interface_add_del_address (vat_main_t * vam)
6265 {
6266   unformat_input_t *i = vam->input;
6267   vl_api_sw_interface_add_del_address_t *mp;
6268   u32 sw_if_index;
6269   u8 sw_if_index_set = 0;
6270   u8 is_add = 1, del_all = 0;
6271   u32 address_length = 0;
6272   u8 v4_address_set = 0;
6273   u8 v6_address_set = 0;
6274   ip4_address_t v4address;
6275   ip6_address_t v6address;
6276   int ret;
6277
6278   /* Parse args required to build the message */
6279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6280     {
6281       if (unformat (i, "del-all"))
6282         del_all = 1;
6283       else if (unformat (i, "del"))
6284         is_add = 0;
6285       else
6286         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6287         sw_if_index_set = 1;
6288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "%U/%d",
6291                          unformat_ip4_address, &v4address, &address_length))
6292         v4_address_set = 1;
6293       else if (unformat (i, "%U/%d",
6294                          unformat_ip6_address, &v6address, &address_length))
6295         v6_address_set = 1;
6296       else
6297         break;
6298     }
6299
6300   if (sw_if_index_set == 0)
6301     {
6302       errmsg ("missing interface name or sw_if_index");
6303       return -99;
6304     }
6305   if (v4_address_set && v6_address_set)
6306     {
6307       errmsg ("both v4 and v6 addresses set");
6308       return -99;
6309     }
6310   if (!v4_address_set && !v6_address_set && !del_all)
6311     {
6312       errmsg ("no addresses set");
6313       return -99;
6314     }
6315
6316   /* Construct the API message */
6317   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6318
6319   mp->sw_if_index = ntohl (sw_if_index);
6320   mp->is_add = is_add;
6321   mp->del_all = del_all;
6322   if (v6_address_set)
6323     {
6324       mp->is_ipv6 = 1;
6325       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6326     }
6327   else
6328     {
6329       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6330     }
6331   mp->address_length = address_length;
6332
6333   /* send it... */
6334   S (mp);
6335
6336   /* Wait for a reply, return good/bad news  */
6337   W (ret);
6338   return ret;
6339 }
6340
6341 static int
6342 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6343 {
6344   unformat_input_t *i = vam->input;
6345   vl_api_sw_interface_set_mpls_enable_t *mp;
6346   u32 sw_if_index;
6347   u8 sw_if_index_set = 0;
6348   u8 enable = 1;
6349   int ret;
6350
6351   /* Parse args required to build the message */
6352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6353     {
6354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6355         sw_if_index_set = 1;
6356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6357         sw_if_index_set = 1;
6358       else if (unformat (i, "disable"))
6359         enable = 0;
6360       else if (unformat (i, "dis"))
6361         enable = 0;
6362       else
6363         break;
6364     }
6365
6366   if (sw_if_index_set == 0)
6367     {
6368       errmsg ("missing interface name or sw_if_index");
6369       return -99;
6370     }
6371
6372   /* Construct the API message */
6373   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6374
6375   mp->sw_if_index = ntohl (sw_if_index);
6376   mp->enable = enable;
6377
6378   /* send it... */
6379   S (mp);
6380
6381   /* Wait for a reply... */
6382   W (ret);
6383   return ret;
6384 }
6385
6386 static int
6387 api_sw_interface_set_table (vat_main_t * vam)
6388 {
6389   unformat_input_t *i = vam->input;
6390   vl_api_sw_interface_set_table_t *mp;
6391   u32 sw_if_index, vrf_id = 0;
6392   u8 sw_if_index_set = 0;
6393   u8 is_ipv6 = 0;
6394   int ret;
6395
6396   /* Parse args required to build the message */
6397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6398     {
6399       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6400         sw_if_index_set = 1;
6401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6402         sw_if_index_set = 1;
6403       else if (unformat (i, "vrf %d", &vrf_id))
6404         ;
6405       else if (unformat (i, "ipv6"))
6406         is_ipv6 = 1;
6407       else
6408         break;
6409     }
6410
6411   if (sw_if_index_set == 0)
6412     {
6413       errmsg ("missing interface name or sw_if_index");
6414       return -99;
6415     }
6416
6417   /* Construct the API message */
6418   M (SW_INTERFACE_SET_TABLE, mp);
6419
6420   mp->sw_if_index = ntohl (sw_if_index);
6421   mp->is_ipv6 = is_ipv6;
6422   mp->vrf_id = ntohl (vrf_id);
6423
6424   /* send it... */
6425   S (mp);
6426
6427   /* Wait for a reply... */
6428   W (ret);
6429   return ret;
6430 }
6431
6432 static void vl_api_sw_interface_get_table_reply_t_handler
6433   (vl_api_sw_interface_get_table_reply_t * mp)
6434 {
6435   vat_main_t *vam = &vat_main;
6436
6437   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6438
6439   vam->retval = ntohl (mp->retval);
6440   vam->result_ready = 1;
6441
6442 }
6443
6444 static void vl_api_sw_interface_get_table_reply_t_handler_json
6445   (vl_api_sw_interface_get_table_reply_t * mp)
6446 {
6447   vat_main_t *vam = &vat_main;
6448   vat_json_node_t node;
6449
6450   vat_json_init_object (&node);
6451   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6452   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6453
6454   vat_json_print (vam->ofp, &node);
6455   vat_json_free (&node);
6456
6457   vam->retval = ntohl (mp->retval);
6458   vam->result_ready = 1;
6459 }
6460
6461 static int
6462 api_sw_interface_get_table (vat_main_t * vam)
6463 {
6464   unformat_input_t *i = vam->input;
6465   vl_api_sw_interface_get_table_t *mp;
6466   u32 sw_if_index;
6467   u8 sw_if_index_set = 0;
6468   u8 is_ipv6 = 0;
6469   int ret;
6470
6471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6472     {
6473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6474         sw_if_index_set = 1;
6475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6476         sw_if_index_set = 1;
6477       else if (unformat (i, "ipv6"))
6478         is_ipv6 = 1;
6479       else
6480         break;
6481     }
6482
6483   if (sw_if_index_set == 0)
6484     {
6485       errmsg ("missing interface name or sw_if_index");
6486       return -99;
6487     }
6488
6489   M (SW_INTERFACE_GET_TABLE, mp);
6490   mp->sw_if_index = htonl (sw_if_index);
6491   mp->is_ipv6 = is_ipv6;
6492
6493   S (mp);
6494   W (ret);
6495   return ret;
6496 }
6497
6498 static int
6499 api_sw_interface_set_vpath (vat_main_t * vam)
6500 {
6501   unformat_input_t *i = vam->input;
6502   vl_api_sw_interface_set_vpath_t *mp;
6503   u32 sw_if_index = 0;
6504   u8 sw_if_index_set = 0;
6505   u8 is_enable = 0;
6506   int ret;
6507
6508   /* Parse args required to build the message */
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6512         sw_if_index_set = 1;
6513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6514         sw_if_index_set = 1;
6515       else if (unformat (i, "enable"))
6516         is_enable = 1;
6517       else if (unformat (i, "disable"))
6518         is_enable = 0;
6519       else
6520         break;
6521     }
6522
6523   if (sw_if_index_set == 0)
6524     {
6525       errmsg ("missing interface name or sw_if_index");
6526       return -99;
6527     }
6528
6529   /* Construct the API message */
6530   M (SW_INTERFACE_SET_VPATH, mp);
6531
6532   mp->sw_if_index = ntohl (sw_if_index);
6533   mp->enable = is_enable;
6534
6535   /* send it... */
6536   S (mp);
6537
6538   /* Wait for a reply... */
6539   W (ret);
6540   return ret;
6541 }
6542
6543 static int
6544 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6545 {
6546   unformat_input_t *i = vam->input;
6547   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6548   u32 sw_if_index = 0;
6549   u8 sw_if_index_set = 0;
6550   u8 is_enable = 1;
6551   u8 is_ipv6 = 0;
6552   int ret;
6553
6554   /* Parse args required to build the message */
6555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6556     {
6557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6558         sw_if_index_set = 1;
6559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6560         sw_if_index_set = 1;
6561       else if (unformat (i, "enable"))
6562         is_enable = 1;
6563       else if (unformat (i, "disable"))
6564         is_enable = 0;
6565       else if (unformat (i, "ip4"))
6566         is_ipv6 = 0;
6567       else if (unformat (i, "ip6"))
6568         is_ipv6 = 1;
6569       else
6570         break;
6571     }
6572
6573   if (sw_if_index_set == 0)
6574     {
6575       errmsg ("missing interface name or sw_if_index");
6576       return -99;
6577     }
6578
6579   /* Construct the API message */
6580   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6581
6582   mp->sw_if_index = ntohl (sw_if_index);
6583   mp->enable = is_enable;
6584   mp->is_ipv6 = is_ipv6;
6585
6586   /* send it... */
6587   S (mp);
6588
6589   /* Wait for a reply... */
6590   W (ret);
6591   return ret;
6592 }
6593
6594 static int
6595 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6596 {
6597   unformat_input_t *i = vam->input;
6598   vl_api_sw_interface_set_geneve_bypass_t *mp;
6599   u32 sw_if_index = 0;
6600   u8 sw_if_index_set = 0;
6601   u8 is_enable = 1;
6602   u8 is_ipv6 = 0;
6603   int ret;
6604
6605   /* Parse args required to build the message */
6606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6607     {
6608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6609         sw_if_index_set = 1;
6610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6611         sw_if_index_set = 1;
6612       else if (unformat (i, "enable"))
6613         is_enable = 1;
6614       else if (unformat (i, "disable"))
6615         is_enable = 0;
6616       else if (unformat (i, "ip4"))
6617         is_ipv6 = 0;
6618       else if (unformat (i, "ip6"))
6619         is_ipv6 = 1;
6620       else
6621         break;
6622     }
6623
6624   if (sw_if_index_set == 0)
6625     {
6626       errmsg ("missing interface name or sw_if_index");
6627       return -99;
6628     }
6629
6630   /* Construct the API message */
6631   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6632
6633   mp->sw_if_index = ntohl (sw_if_index);
6634   mp->enable = is_enable;
6635   mp->is_ipv6 = is_ipv6;
6636
6637   /* send it... */
6638   S (mp);
6639
6640   /* Wait for a reply... */
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_sw_interface_set_l2_xconnect_t *mp;
6650   u32 rx_sw_if_index;
6651   u8 rx_sw_if_index_set = 0;
6652   u32 tx_sw_if_index;
6653   u8 tx_sw_if_index_set = 0;
6654   u8 enable = 1;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6661         rx_sw_if_index_set = 1;
6662       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6663         tx_sw_if_index_set = 1;
6664       else if (unformat (i, "rx"))
6665         {
6666           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6667             {
6668               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6669                             &rx_sw_if_index))
6670                 rx_sw_if_index_set = 1;
6671             }
6672           else
6673             break;
6674         }
6675       else if (unformat (i, "tx"))
6676         {
6677           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6678             {
6679               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6680                             &tx_sw_if_index))
6681                 tx_sw_if_index_set = 1;
6682             }
6683           else
6684             break;
6685         }
6686       else if (unformat (i, "enable"))
6687         enable = 1;
6688       else if (unformat (i, "disable"))
6689         enable = 0;
6690       else
6691         break;
6692     }
6693
6694   if (rx_sw_if_index_set == 0)
6695     {
6696       errmsg ("missing rx interface name or rx_sw_if_index");
6697       return -99;
6698     }
6699
6700   if (enable && (tx_sw_if_index_set == 0))
6701     {
6702       errmsg ("missing tx interface name or tx_sw_if_index");
6703       return -99;
6704     }
6705
6706   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6707
6708   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6709   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6710   mp->enable = enable;
6711
6712   S (mp);
6713   W (ret);
6714   return ret;
6715 }
6716
6717 static int
6718 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6719 {
6720   unformat_input_t *i = vam->input;
6721   vl_api_sw_interface_set_l2_bridge_t *mp;
6722   vl_api_l2_port_type_t port_type;
6723   u32 rx_sw_if_index;
6724   u8 rx_sw_if_index_set = 0;
6725   u32 bd_id;
6726   u8 bd_id_set = 0;
6727   u32 shg = 0;
6728   u8 enable = 1;
6729   int ret;
6730
6731   port_type = L2_API_PORT_TYPE_NORMAL;
6732
6733   /* Parse args required to build the message */
6734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6735     {
6736       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6737         rx_sw_if_index_set = 1;
6738       else if (unformat (i, "bd_id %d", &bd_id))
6739         bd_id_set = 1;
6740       else
6741         if (unformat
6742             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6743         rx_sw_if_index_set = 1;
6744       else if (unformat (i, "shg %d", &shg))
6745         ;
6746       else if (unformat (i, "bvi"))
6747         port_type = L2_API_PORT_TYPE_BVI;
6748       else if (unformat (i, "uu-fwd"))
6749         port_type = L2_API_PORT_TYPE_UU_FWD;
6750       else if (unformat (i, "enable"))
6751         enable = 1;
6752       else if (unformat (i, "disable"))
6753         enable = 0;
6754       else
6755         break;
6756     }
6757
6758   if (rx_sw_if_index_set == 0)
6759     {
6760       errmsg ("missing rx interface name or sw_if_index");
6761       return -99;
6762     }
6763
6764   if (enable && (bd_id_set == 0))
6765     {
6766       errmsg ("missing bridge domain");
6767       return -99;
6768     }
6769
6770   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6771
6772   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6773   mp->bd_id = ntohl (bd_id);
6774   mp->shg = (u8) shg;
6775   mp->port_type = ntohl (port_type);
6776   mp->enable = enable;
6777
6778   S (mp);
6779   W (ret);
6780   return ret;
6781 }
6782
6783 static int
6784 api_bridge_domain_dump (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_bridge_domain_dump_t *mp;
6788   vl_api_control_ping_t *mp_ping;
6789   u32 bd_id = ~0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "bd_id %d", &bd_id))
6796         ;
6797       else
6798         break;
6799     }
6800
6801   M (BRIDGE_DOMAIN_DUMP, mp);
6802   mp->bd_id = ntohl (bd_id);
6803   S (mp);
6804
6805   /* Use a control ping for synchronization */
6806   MPING (CONTROL_PING, mp_ping);
6807   S (mp_ping);
6808
6809   W (ret);
6810   return ret;
6811 }
6812
6813 static int
6814 api_bridge_domain_add_del (vat_main_t * vam)
6815 {
6816   unformat_input_t *i = vam->input;
6817   vl_api_bridge_domain_add_del_t *mp;
6818   u32 bd_id = ~0;
6819   u8 is_add = 1;
6820   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6821   u8 *bd_tag = NULL;
6822   u32 mac_age = 0;
6823   int ret;
6824
6825   /* Parse args required to build the message */
6826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6827     {
6828       if (unformat (i, "bd_id %d", &bd_id))
6829         ;
6830       else if (unformat (i, "flood %d", &flood))
6831         ;
6832       else if (unformat (i, "uu-flood %d", &uu_flood))
6833         ;
6834       else if (unformat (i, "forward %d", &forward))
6835         ;
6836       else if (unformat (i, "learn %d", &learn))
6837         ;
6838       else if (unformat (i, "arp-term %d", &arp_term))
6839         ;
6840       else if (unformat (i, "mac-age %d", &mac_age))
6841         ;
6842       else if (unformat (i, "bd-tag %s", &bd_tag))
6843         ;
6844       else if (unformat (i, "del"))
6845         {
6846           is_add = 0;
6847           flood = uu_flood = forward = learn = 0;
6848         }
6849       else
6850         break;
6851     }
6852
6853   if (bd_id == ~0)
6854     {
6855       errmsg ("missing bridge domain");
6856       ret = -99;
6857       goto done;
6858     }
6859
6860   if (mac_age > 255)
6861     {
6862       errmsg ("mac age must be less than 256 ");
6863       ret = -99;
6864       goto done;
6865     }
6866
6867   if ((bd_tag) && (vec_len (bd_tag) > 63))
6868     {
6869       errmsg ("bd-tag cannot be longer than 63");
6870       ret = -99;
6871       goto done;
6872     }
6873
6874   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6875
6876   mp->bd_id = ntohl (bd_id);
6877   mp->flood = flood;
6878   mp->uu_flood = uu_flood;
6879   mp->forward = forward;
6880   mp->learn = learn;
6881   mp->arp_term = arp_term;
6882   mp->is_add = is_add;
6883   mp->mac_age = (u8) mac_age;
6884   if (bd_tag)
6885     {
6886       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6887       mp->bd_tag[vec_len (bd_tag)] = 0;
6888     }
6889   S (mp);
6890   W (ret);
6891
6892 done:
6893   vec_free (bd_tag);
6894   return ret;
6895 }
6896
6897 static int
6898 api_l2fib_flush_bd (vat_main_t * vam)
6899 {
6900   unformat_input_t *i = vam->input;
6901   vl_api_l2fib_flush_bd_t *mp;
6902   u32 bd_id = ~0;
6903   int ret;
6904
6905   /* Parse args required to build the message */
6906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907     {
6908       if (unformat (i, "bd_id %d", &bd_id));
6909       else
6910         break;
6911     }
6912
6913   if (bd_id == ~0)
6914     {
6915       errmsg ("missing bridge domain");
6916       return -99;
6917     }
6918
6919   M (L2FIB_FLUSH_BD, mp);
6920
6921   mp->bd_id = htonl (bd_id);
6922
6923   S (mp);
6924   W (ret);
6925   return ret;
6926 }
6927
6928 static int
6929 api_l2fib_flush_int (vat_main_t * vam)
6930 {
6931   unformat_input_t *i = vam->input;
6932   vl_api_l2fib_flush_int_t *mp;
6933   u32 sw_if_index = ~0;
6934   int ret;
6935
6936   /* Parse args required to build the message */
6937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6938     {
6939       if (unformat (i, "sw_if_index %d", &sw_if_index));
6940       else
6941         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6942       else
6943         break;
6944     }
6945
6946   if (sw_if_index == ~0)
6947     {
6948       errmsg ("missing interface name or sw_if_index");
6949       return -99;
6950     }
6951
6952   M (L2FIB_FLUSH_INT, mp);
6953
6954   mp->sw_if_index = ntohl (sw_if_index);
6955
6956   S (mp);
6957   W (ret);
6958   return ret;
6959 }
6960
6961 static int
6962 api_l2fib_add_del (vat_main_t * vam)
6963 {
6964   unformat_input_t *i = vam->input;
6965   vl_api_l2fib_add_del_t *mp;
6966   f64 timeout;
6967   u8 mac[6] = { 0 };
6968   u8 mac_set = 0;
6969   u32 bd_id;
6970   u8 bd_id_set = 0;
6971   u32 sw_if_index = 0;
6972   u8 sw_if_index_set = 0;
6973   u8 is_add = 1;
6974   u8 static_mac = 0;
6975   u8 filter_mac = 0;
6976   u8 bvi_mac = 0;
6977   int count = 1;
6978   f64 before = 0;
6979   int j;
6980
6981   /* Parse args required to build the message */
6982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6983     {
6984       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6985         mac_set = 1;
6986       else if (unformat (i, "bd_id %d", &bd_id))
6987         bd_id_set = 1;
6988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6989         sw_if_index_set = 1;
6990       else if (unformat (i, "sw_if"))
6991         {
6992           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993             {
6994               if (unformat
6995                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6996                 sw_if_index_set = 1;
6997             }
6998           else
6999             break;
7000         }
7001       else if (unformat (i, "static"))
7002         static_mac = 1;
7003       else if (unformat (i, "filter"))
7004         {
7005           filter_mac = 1;
7006           static_mac = 1;
7007         }
7008       else if (unformat (i, "bvi"))
7009         {
7010           bvi_mac = 1;
7011           static_mac = 1;
7012         }
7013       else if (unformat (i, "del"))
7014         is_add = 0;
7015       else if (unformat (i, "count %d", &count))
7016         ;
7017       else
7018         break;
7019     }
7020
7021   if (mac_set == 0)
7022     {
7023       errmsg ("missing mac address");
7024       return -99;
7025     }
7026
7027   if (bd_id_set == 0)
7028     {
7029       errmsg ("missing bridge domain");
7030       return -99;
7031     }
7032
7033   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7034     {
7035       errmsg ("missing interface name or sw_if_index");
7036       return -99;
7037     }
7038
7039   if (count > 1)
7040     {
7041       /* Turn on async mode */
7042       vam->async_mode = 1;
7043       vam->async_errors = 0;
7044       before = vat_time_now (vam);
7045     }
7046
7047   for (j = 0; j < count; j++)
7048     {
7049       M (L2FIB_ADD_DEL, mp);
7050
7051       clib_memcpy (mp->mac, mac, 6);
7052       mp->bd_id = ntohl (bd_id);
7053       mp->is_add = is_add;
7054       mp->sw_if_index = ntohl (sw_if_index);
7055
7056       if (is_add)
7057         {
7058           mp->static_mac = static_mac;
7059           mp->filter_mac = filter_mac;
7060           mp->bvi_mac = bvi_mac;
7061         }
7062       increment_mac_address (mac);
7063       /* send it... */
7064       S (mp);
7065     }
7066
7067   if (count > 1)
7068     {
7069       vl_api_control_ping_t *mp_ping;
7070       f64 after;
7071
7072       /* Shut off async mode */
7073       vam->async_mode = 0;
7074
7075       MPING (CONTROL_PING, mp_ping);
7076       S (mp_ping);
7077
7078       timeout = vat_time_now (vam) + 1.0;
7079       while (vat_time_now (vam) < timeout)
7080         if (vam->result_ready == 1)
7081           goto out;
7082       vam->retval = -99;
7083
7084     out:
7085       if (vam->retval == -99)
7086         errmsg ("timeout");
7087
7088       if (vam->async_errors > 0)
7089         {
7090           errmsg ("%d asynchronous errors", vam->async_errors);
7091           vam->retval = -98;
7092         }
7093       vam->async_errors = 0;
7094       after = vat_time_now (vam);
7095
7096       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7097              count, after - before, count / (after - before));
7098     }
7099   else
7100     {
7101       int ret;
7102
7103       /* Wait for a reply... */
7104       W (ret);
7105       return ret;
7106     }
7107   /* Return the good/bad news */
7108   return (vam->retval);
7109 }
7110
7111 static int
7112 api_bridge_domain_set_mac_age (vat_main_t * vam)
7113 {
7114   unformat_input_t *i = vam->input;
7115   vl_api_bridge_domain_set_mac_age_t *mp;
7116   u32 bd_id = ~0;
7117   u32 mac_age = 0;
7118   int ret;
7119
7120   /* Parse args required to build the message */
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "bd_id %d", &bd_id));
7124       else if (unformat (i, "mac-age %d", &mac_age));
7125       else
7126         break;
7127     }
7128
7129   if (bd_id == ~0)
7130     {
7131       errmsg ("missing bridge domain");
7132       return -99;
7133     }
7134
7135   if (mac_age > 255)
7136     {
7137       errmsg ("mac age must be less than 256 ");
7138       return -99;
7139     }
7140
7141   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7142
7143   mp->bd_id = htonl (bd_id);
7144   mp->mac_age = (u8) mac_age;
7145
7146   S (mp);
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_l2_flags (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_l2_flags_t *mp;
7156   u32 sw_if_index;
7157   u32 flags = 0;
7158   u8 sw_if_index_set = 0;
7159   u8 is_set = 0;
7160   int ret;
7161
7162   /* Parse args required to build the message */
7163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7164     {
7165       if (unformat (i, "sw_if_index %d", &sw_if_index))
7166         sw_if_index_set = 1;
7167       else if (unformat (i, "sw_if"))
7168         {
7169           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7170             {
7171               if (unformat
7172                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7173                 sw_if_index_set = 1;
7174             }
7175           else
7176             break;
7177         }
7178       else if (unformat (i, "learn"))
7179         flags |= L2_LEARN;
7180       else if (unformat (i, "forward"))
7181         flags |= L2_FWD;
7182       else if (unformat (i, "flood"))
7183         flags |= L2_FLOOD;
7184       else if (unformat (i, "uu-flood"))
7185         flags |= L2_UU_FLOOD;
7186       else if (unformat (i, "arp-term"))
7187         flags |= L2_ARP_TERM;
7188       else if (unformat (i, "off"))
7189         is_set = 0;
7190       else if (unformat (i, "disable"))
7191         is_set = 0;
7192       else
7193         break;
7194     }
7195
7196   if (sw_if_index_set == 0)
7197     {
7198       errmsg ("missing interface name or sw_if_index");
7199       return -99;
7200     }
7201
7202   M (L2_FLAGS, mp);
7203
7204   mp->sw_if_index = ntohl (sw_if_index);
7205   mp->feature_bitmap = ntohl (flags);
7206   mp->is_set = is_set;
7207
7208   S (mp);
7209   W (ret);
7210   return ret;
7211 }
7212
7213 static int
7214 api_bridge_flags (vat_main_t * vam)
7215 {
7216   unformat_input_t *i = vam->input;
7217   vl_api_bridge_flags_t *mp;
7218   u32 bd_id;
7219   u8 bd_id_set = 0;
7220   u8 is_set = 1;
7221   bd_flags_t flags = 0;
7222   int ret;
7223
7224   /* Parse args required to build the message */
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "bd_id %d", &bd_id))
7228         bd_id_set = 1;
7229       else if (unformat (i, "learn"))
7230         flags |= BRIDGE_API_FLAG_LEARN;
7231       else if (unformat (i, "forward"))
7232         flags |= BRIDGE_API_FLAG_FWD;
7233       else if (unformat (i, "flood"))
7234         flags |= BRIDGE_API_FLAG_FLOOD;
7235       else if (unformat (i, "uu-flood"))
7236         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7237       else if (unformat (i, "arp-term"))
7238         flags |= BRIDGE_API_FLAG_ARP_TERM;
7239       else if (unformat (i, "off"))
7240         is_set = 0;
7241       else if (unformat (i, "disable"))
7242         is_set = 0;
7243       else
7244         break;
7245     }
7246
7247   if (bd_id_set == 0)
7248     {
7249       errmsg ("missing bridge domain");
7250       return -99;
7251     }
7252
7253   M (BRIDGE_FLAGS, mp);
7254
7255   mp->bd_id = ntohl (bd_id);
7256   mp->flags = ntohl (flags);
7257   mp->is_set = is_set;
7258
7259   S (mp);
7260   W (ret);
7261   return ret;
7262 }
7263
7264 static int
7265 api_bd_ip_mac_add_del (vat_main_t * vam)
7266 {
7267   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7268   vl_api_mac_address_t mac = { 0 };
7269   unformat_input_t *i = vam->input;
7270   vl_api_bd_ip_mac_add_del_t *mp;
7271   ip46_type_t type;
7272   u32 bd_id;
7273   u8 is_ipv6 = 0;
7274   u8 is_add = 1;
7275   u8 bd_id_set = 0;
7276   u8 ip_set = 0;
7277   u8 mac_set = 0;
7278   u8 macaddr[6];
7279   int ret;
7280
7281
7282   /* Parse args required to build the message */
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "bd_id %d", &bd_id))
7286         {
7287           bd_id_set++;
7288         }
7289       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7290         {
7291           ip_set++;
7292         }
7293       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7294         {
7295           mac_set++;
7296         }
7297       else if (unformat (i, "del"))
7298         is_add = 0;
7299       else
7300         break;
7301     }
7302
7303   if (bd_id_set == 0)
7304     {
7305       errmsg ("missing bridge domain");
7306       return -99;
7307     }
7308   else if (ip_set == 0)
7309     {
7310       errmsg ("missing IP address");
7311       return -99;
7312     }
7313   else if (mac_set == 0)
7314     {
7315       errmsg ("missing MAC address");
7316       return -99;
7317     }
7318
7319   M (BD_IP_MAC_ADD_DEL, mp);
7320
7321   mp->bd_id = ntohl (bd_id);
7322   mp->is_add = is_add;
7323
7324   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7325   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7326
7327   S (mp);
7328   W (ret);
7329   return ret;
7330 }
7331
7332 static int
7333 api_bd_ip_mac_flush (vat_main_t * vam)
7334 {
7335   unformat_input_t *i = vam->input;
7336   vl_api_bd_ip_mac_flush_t *mp;
7337   u32 bd_id;
7338   u8 bd_id_set = 0;
7339   int ret;
7340
7341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7342     {
7343       if (unformat (i, "bd_id %d", &bd_id))
7344         {
7345           bd_id_set++;
7346         }
7347       else
7348         break;
7349     }
7350
7351   if (bd_id_set == 0)
7352     {
7353       errmsg ("missing bridge domain");
7354       return -99;
7355     }
7356
7357   M (BD_IP_MAC_FLUSH, mp);
7358
7359   mp->bd_id = ntohl (bd_id);
7360
7361   S (mp);
7362   W (ret);
7363   return ret;
7364 }
7365
7366 static void vl_api_bd_ip_mac_details_t_handler
7367   (vl_api_bd_ip_mac_details_t * mp)
7368 {
7369   vat_main_t *vam = &vat_main;
7370   u8 *ip = 0;
7371
7372   if (!mp->is_ipv6)
7373     ip =
7374       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7375   else
7376     ip =
7377       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7378
7379   print (vam->ofp,
7380          "\n%-5d %-7s %-20U %-30s",
7381          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7382          format_ethernet_address, mp->mac_address, ip);
7383
7384   vec_free (ip);
7385 }
7386
7387 static void vl_api_bd_ip_mac_details_t_handler_json
7388   (vl_api_bd_ip_mac_details_t * mp)
7389 {
7390   vat_main_t *vam = &vat_main;
7391   vat_json_node_t *node = NULL;
7392
7393   if (VAT_JSON_ARRAY != vam->json_tree.type)
7394     {
7395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7396       vat_json_init_array (&vam->json_tree);
7397     }
7398   node = vat_json_array_add (&vam->json_tree);
7399
7400   vat_json_init_object (node);
7401   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7402   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7403   vat_json_object_add_string_copy (node, "mac_address",
7404                                    format (0, "%U", format_ethernet_address,
7405                                            &mp->mac_address));
7406   u8 *ip = 0;
7407
7408   if (!mp->is_ipv6)
7409     ip =
7410       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7411   else
7412     ip =
7413       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7414   vat_json_object_add_string_copy (node, "ip_address", ip);
7415   vec_free (ip);
7416 }
7417
7418 static int
7419 api_bd_ip_mac_dump (vat_main_t * vam)
7420 {
7421   unformat_input_t *i = vam->input;
7422   vl_api_bd_ip_mac_dump_t *mp;
7423   vl_api_control_ping_t *mp_ping;
7424   int ret;
7425   u32 bd_id;
7426   u8 bd_id_set = 0;
7427
7428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7429     {
7430       if (unformat (i, "bd_id %d", &bd_id))
7431         {
7432           bd_id_set++;
7433         }
7434       else
7435         break;
7436     }
7437
7438   print (vam->ofp,
7439          "\n%-5s %-7s %-20s %-30s",
7440          "bd_id", "is_ipv6", "mac_address", "ip_address");
7441
7442   /* Dump Bridge Domain Ip to Mac entries */
7443   M (BD_IP_MAC_DUMP, mp);
7444
7445   if (bd_id_set)
7446     mp->bd_id = htonl (bd_id);
7447   else
7448     mp->bd_id = ~0;
7449
7450   S (mp);
7451
7452   /* Use a control ping for synchronization */
7453   MPING (CONTROL_PING, mp_ping);
7454   S (mp_ping);
7455
7456   W (ret);
7457   return ret;
7458 }
7459
7460 static int
7461 api_tap_create_v2 (vat_main_t * vam)
7462 {
7463   unformat_input_t *i = vam->input;
7464   vl_api_tap_create_v2_t *mp;
7465   u8 mac_address[6];
7466   u8 random_mac = 1;
7467   u32 id = ~0;
7468   u8 *host_if_name = 0;
7469   u8 *host_ns = 0;
7470   u8 host_mac_addr[6];
7471   u8 host_mac_addr_set = 0;
7472   u8 *host_bridge = 0;
7473   ip4_address_t host_ip4_addr;
7474   ip4_address_t host_ip4_gw;
7475   u8 host_ip4_gw_set = 0;
7476   u32 host_ip4_prefix_len = 0;
7477   ip6_address_t host_ip6_addr;
7478   ip6_address_t host_ip6_gw;
7479   u8 host_ip6_gw_set = 0;
7480   u32 host_ip6_prefix_len = 0;
7481   int ret;
7482   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7483
7484   clib_memset (mac_address, 0, sizeof (mac_address));
7485
7486   /* Parse args required to build the message */
7487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7488     {
7489       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7490         {
7491           random_mac = 0;
7492         }
7493       else if (unformat (i, "id %u", &id))
7494         ;
7495       else if (unformat (i, "host-if-name %s", &host_if_name))
7496         ;
7497       else if (unformat (i, "host-ns %s", &host_ns))
7498         ;
7499       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7500                          host_mac_addr))
7501         host_mac_addr_set = 1;
7502       else if (unformat (i, "host-bridge %s", &host_bridge))
7503         ;
7504       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7505                          &host_ip4_addr, &host_ip4_prefix_len))
7506         ;
7507       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7508                          &host_ip6_addr, &host_ip6_prefix_len))
7509         ;
7510       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7511                          &host_ip4_gw))
7512         host_ip4_gw_set = 1;
7513       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7514                          &host_ip6_gw))
7515         host_ip6_gw_set = 1;
7516       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7517         ;
7518       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7519         ;
7520       else
7521         break;
7522     }
7523
7524   if (vec_len (host_if_name) > 63)
7525     {
7526       errmsg ("tap name too long. ");
7527       return -99;
7528     }
7529   if (vec_len (host_ns) > 63)
7530     {
7531       errmsg ("host name space too long. ");
7532       return -99;
7533     }
7534   if (vec_len (host_bridge) > 63)
7535     {
7536       errmsg ("host bridge name too long. ");
7537       return -99;
7538     }
7539   if (host_ip4_prefix_len > 32)
7540     {
7541       errmsg ("host ip4 prefix length not valid. ");
7542       return -99;
7543     }
7544   if (host_ip6_prefix_len > 128)
7545     {
7546       errmsg ("host ip6 prefix length not valid. ");
7547       return -99;
7548     }
7549   if (!is_pow2 (rx_ring_sz))
7550     {
7551       errmsg ("rx ring size must be power of 2. ");
7552       return -99;
7553     }
7554   if (rx_ring_sz > 32768)
7555     {
7556       errmsg ("rx ring size must be 32768 or lower. ");
7557       return -99;
7558     }
7559   if (!is_pow2 (tx_ring_sz))
7560     {
7561       errmsg ("tx ring size must be power of 2. ");
7562       return -99;
7563     }
7564   if (tx_ring_sz > 32768)
7565     {
7566       errmsg ("tx ring size must be 32768 or lower. ");
7567       return -99;
7568     }
7569
7570   /* Construct the API message */
7571   M (TAP_CREATE_V2, mp);
7572
7573   mp->use_random_mac = random_mac;
7574
7575   mp->id = ntohl (id);
7576   mp->host_namespace_set = host_ns != 0;
7577   mp->host_bridge_set = host_bridge != 0;
7578   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7579   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7580   mp->rx_ring_sz = ntohs (rx_ring_sz);
7581   mp->tx_ring_sz = ntohs (tx_ring_sz);
7582
7583   if (random_mac == 0)
7584     clib_memcpy (mp->mac_address, mac_address, 6);
7585   if (host_mac_addr_set)
7586     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7587   if (host_if_name)
7588     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7589   if (host_ns)
7590     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7591   if (host_bridge)
7592     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7593   if (host_ip4_prefix_len)
7594     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7595   if (host_ip6_prefix_len)
7596     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7597   if (host_ip4_gw_set)
7598     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7599   if (host_ip6_gw_set)
7600     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7601
7602   vec_free (host_ns);
7603   vec_free (host_if_name);
7604   vec_free (host_bridge);
7605
7606   /* send it... */
7607   S (mp);
7608
7609   /* Wait for a reply... */
7610   W (ret);
7611   return ret;
7612 }
7613
7614 static int
7615 api_tap_delete_v2 (vat_main_t * vam)
7616 {
7617   unformat_input_t *i = vam->input;
7618   vl_api_tap_delete_v2_t *mp;
7619   u32 sw_if_index = ~0;
7620   u8 sw_if_index_set = 0;
7621   int ret;
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7629         sw_if_index_set = 1;
7630       else
7631         break;
7632     }
7633
7634   if (sw_if_index_set == 0)
7635     {
7636       errmsg ("missing vpp interface name. ");
7637       return -99;
7638     }
7639
7640   /* Construct the API message */
7641   M (TAP_DELETE_V2, mp);
7642
7643   mp->sw_if_index = ntohl (sw_if_index);
7644
7645   /* send it... */
7646   S (mp);
7647
7648   /* Wait for a reply... */
7649   W (ret);
7650   return ret;
7651 }
7652
7653 uword
7654 unformat_pci_addr (unformat_input_t * input, va_list * args)
7655 {
7656   struct pci_addr_t
7657   {
7658     u16 domain;
7659     u8 bus;
7660     u8 slot:5;
7661     u8 function:3;
7662   } *addr;
7663   addr = va_arg (*args, struct pci_addr_t *);
7664   u32 x[4];
7665
7666   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7667     return 0;
7668
7669   addr->domain = x[0];
7670   addr->bus = x[1];
7671   addr->slot = x[2];
7672   addr->function = x[3];
7673
7674   return 1;
7675 }
7676
7677 static int
7678 api_virtio_pci_create (vat_main_t * vam)
7679 {
7680   unformat_input_t *i = vam->input;
7681   vl_api_virtio_pci_create_t *mp;
7682   u8 mac_address[6];
7683   u8 random_mac = 1;
7684   u32 pci_addr = 0;
7685   u64 features = (u64) ~ (0ULL);
7686   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7687   int ret;
7688
7689   clib_memset (mac_address, 0, sizeof (mac_address));
7690
7691   /* Parse args required to build the message */
7692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7693     {
7694       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7695         {
7696           random_mac = 0;
7697         }
7698       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7699         ;
7700       else if (unformat (i, "features 0x%llx", &features))
7701         ;
7702       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7703         ;
7704       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7705         ;
7706       else
7707         break;
7708     }
7709
7710   if (pci_addr == 0)
7711     {
7712       errmsg ("pci address must be non zero. ");
7713       return -99;
7714     }
7715   if (!is_pow2 (rx_ring_sz))
7716     {
7717       errmsg ("rx ring size must be power of 2. ");
7718       return -99;
7719     }
7720   if (rx_ring_sz > 32768)
7721     {
7722       errmsg ("rx ring size must be 32768 or lower. ");
7723       return -99;
7724     }
7725   if (!is_pow2 (tx_ring_sz))
7726     {
7727       errmsg ("tx ring size must be power of 2. ");
7728       return -99;
7729     }
7730   if (tx_ring_sz > 32768)
7731     {
7732       errmsg ("tx ring size must be 32768 or lower. ");
7733       return -99;
7734     }
7735
7736   /* Construct the API message */
7737   M (VIRTIO_PCI_CREATE, mp);
7738
7739   mp->use_random_mac = random_mac;
7740
7741   mp->pci_addr = htonl (pci_addr);
7742   mp->features = clib_host_to_net_u64 (features);
7743
7744   if (random_mac == 0)
7745     clib_memcpy (mp->mac_address, mac_address, 6);
7746
7747   /* send it... */
7748   S (mp);
7749
7750   /* Wait for a reply... */
7751   W (ret);
7752   return ret;
7753 }
7754
7755 static int
7756 api_virtio_pci_delete (vat_main_t * vam)
7757 {
7758   unformat_input_t *i = vam->input;
7759   vl_api_virtio_pci_delete_t *mp;
7760   u32 sw_if_index = ~0;
7761   u8 sw_if_index_set = 0;
7762   int ret;
7763
7764   /* Parse args required to build the message */
7765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7766     {
7767       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7768         sw_if_index_set = 1;
7769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7770         sw_if_index_set = 1;
7771       else
7772         break;
7773     }
7774
7775   if (sw_if_index_set == 0)
7776     {
7777       errmsg ("missing vpp interface name. ");
7778       return -99;
7779     }
7780
7781   /* Construct the API message */
7782   M (VIRTIO_PCI_DELETE, mp);
7783
7784   mp->sw_if_index = htonl (sw_if_index);
7785
7786   /* send it... */
7787   S (mp);
7788
7789   /* Wait for a reply... */
7790   W (ret);
7791   return ret;
7792 }
7793
7794 static int
7795 api_bond_create (vat_main_t * vam)
7796 {
7797   unformat_input_t *i = vam->input;
7798   vl_api_bond_create_t *mp;
7799   u8 mac_address[6];
7800   u8 custom_mac = 0;
7801   int ret;
7802   u8 mode;
7803   u8 lb;
7804   u8 mode_is_set = 0;
7805   u32 id = ~0;
7806
7807   clib_memset (mac_address, 0, sizeof (mac_address));
7808   lb = BOND_LB_L2;
7809
7810   /* Parse args required to build the message */
7811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7812     {
7813       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7814         mode_is_set = 1;
7815       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7816                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7817         ;
7818       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7819                          mac_address))
7820         custom_mac = 1;
7821       else if (unformat (i, "id %u", &id))
7822         ;
7823       else
7824         break;
7825     }
7826
7827   if (mode_is_set == 0)
7828     {
7829       errmsg ("Missing bond mode. ");
7830       return -99;
7831     }
7832
7833   /* Construct the API message */
7834   M (BOND_CREATE, mp);
7835
7836   mp->use_custom_mac = custom_mac;
7837
7838   mp->mode = mode;
7839   mp->lb = lb;
7840   mp->id = htonl (id);
7841
7842   if (custom_mac)
7843     clib_memcpy (mp->mac_address, mac_address, 6);
7844
7845   /* send it... */
7846   S (mp);
7847
7848   /* Wait for a reply... */
7849   W (ret);
7850   return ret;
7851 }
7852
7853 static int
7854 api_bond_delete (vat_main_t * vam)
7855 {
7856   unformat_input_t *i = vam->input;
7857   vl_api_bond_delete_t *mp;
7858   u32 sw_if_index = ~0;
7859   u8 sw_if_index_set = 0;
7860   int ret;
7861
7862   /* Parse args required to build the message */
7863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7864     {
7865       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7866         sw_if_index_set = 1;
7867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7868         sw_if_index_set = 1;
7869       else
7870         break;
7871     }
7872
7873   if (sw_if_index_set == 0)
7874     {
7875       errmsg ("missing vpp interface name. ");
7876       return -99;
7877     }
7878
7879   /* Construct the API message */
7880   M (BOND_DELETE, mp);
7881
7882   mp->sw_if_index = ntohl (sw_if_index);
7883
7884   /* send it... */
7885   S (mp);
7886
7887   /* Wait for a reply... */
7888   W (ret);
7889   return ret;
7890 }
7891
7892 static int
7893 api_bond_enslave (vat_main_t * vam)
7894 {
7895   unformat_input_t *i = vam->input;
7896   vl_api_bond_enslave_t *mp;
7897   u32 bond_sw_if_index;
7898   int ret;
7899   u8 is_passive;
7900   u8 is_long_timeout;
7901   u32 bond_sw_if_index_is_set = 0;
7902   u32 sw_if_index;
7903   u8 sw_if_index_is_set = 0;
7904
7905   /* Parse args required to build the message */
7906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7907     {
7908       if (unformat (i, "sw_if_index %d", &sw_if_index))
7909         sw_if_index_is_set = 1;
7910       else if (unformat (i, "bond %u", &bond_sw_if_index))
7911         bond_sw_if_index_is_set = 1;
7912       else if (unformat (i, "passive %d", &is_passive))
7913         ;
7914       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7915         ;
7916       else
7917         break;
7918     }
7919
7920   if (bond_sw_if_index_is_set == 0)
7921     {
7922       errmsg ("Missing bond sw_if_index. ");
7923       return -99;
7924     }
7925   if (sw_if_index_is_set == 0)
7926     {
7927       errmsg ("Missing slave sw_if_index. ");
7928       return -99;
7929     }
7930
7931   /* Construct the API message */
7932   M (BOND_ENSLAVE, mp);
7933
7934   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7935   mp->sw_if_index = ntohl (sw_if_index);
7936   mp->is_long_timeout = is_long_timeout;
7937   mp->is_passive = is_passive;
7938
7939   /* send it... */
7940   S (mp);
7941
7942   /* Wait for a reply... */
7943   W (ret);
7944   return ret;
7945 }
7946
7947 static int
7948 api_bond_detach_slave (vat_main_t * vam)
7949 {
7950   unformat_input_t *i = vam->input;
7951   vl_api_bond_detach_slave_t *mp;
7952   u32 sw_if_index = ~0;
7953   u8 sw_if_index_set = 0;
7954   int ret;
7955
7956   /* Parse args required to build the message */
7957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7958     {
7959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7960         sw_if_index_set = 1;
7961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7962         sw_if_index_set = 1;
7963       else
7964         break;
7965     }
7966
7967   if (sw_if_index_set == 0)
7968     {
7969       errmsg ("missing vpp interface name. ");
7970       return -99;
7971     }
7972
7973   /* Construct the API message */
7974   M (BOND_DETACH_SLAVE, mp);
7975
7976   mp->sw_if_index = ntohl (sw_if_index);
7977
7978   /* send it... */
7979   S (mp);
7980
7981   /* Wait for a reply... */
7982   W (ret);
7983   return ret;
7984 }
7985
7986 static int
7987 api_ip_table_add_del (vat_main_t * vam)
7988 {
7989   unformat_input_t *i = vam->input;
7990   vl_api_ip_table_add_del_t *mp;
7991   u32 table_id = ~0;
7992   u8 is_ipv6 = 0;
7993   u8 is_add = 1;
7994   int ret = 0;
7995
7996   /* Parse args required to build the message */
7997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7998     {
7999       if (unformat (i, "ipv6"))
8000         is_ipv6 = 1;
8001       else if (unformat (i, "del"))
8002         is_add = 0;
8003       else if (unformat (i, "add"))
8004         is_add = 1;
8005       else if (unformat (i, "table %d", &table_id))
8006         ;
8007       else
8008         {
8009           clib_warning ("parse error '%U'", format_unformat_error, i);
8010           return -99;
8011         }
8012     }
8013
8014   if (~0 == table_id)
8015     {
8016       errmsg ("missing table-ID");
8017       return -99;
8018     }
8019
8020   /* Construct the API message */
8021   M (IP_TABLE_ADD_DEL, mp);
8022
8023   mp->table_id = ntohl (table_id);
8024   mp->is_ipv6 = is_ipv6;
8025   mp->is_add = is_add;
8026
8027   /* send it... */
8028   S (mp);
8029
8030   /* Wait for a reply... */
8031   W (ret);
8032
8033   return ret;
8034 }
8035
8036 static int
8037 api_ip_add_del_route (vat_main_t * vam)
8038 {
8039   unformat_input_t *i = vam->input;
8040   vl_api_ip_add_del_route_t *mp;
8041   u32 sw_if_index = ~0, vrf_id = 0;
8042   u8 is_ipv6 = 0;
8043   u8 is_local = 0, is_drop = 0;
8044   u8 is_unreach = 0, is_prohibit = 0;
8045   u8 is_add = 1;
8046   u32 next_hop_weight = 1;
8047   u8 is_multipath = 0;
8048   u8 address_set = 0;
8049   u8 address_length_set = 0;
8050   u32 next_hop_table_id = 0;
8051   u32 resolve_attempts = 0;
8052   u32 dst_address_length = 0;
8053   u8 next_hop_set = 0;
8054   ip4_address_t v4_dst_address, v4_next_hop_address;
8055   ip6_address_t v6_dst_address, v6_next_hop_address;
8056   int count = 1;
8057   int j;
8058   f64 before = 0;
8059   u32 random_add_del = 0;
8060   u32 *random_vector = 0;
8061   uword *random_hash;
8062   u32 random_seed = 0xdeaddabe;
8063   u32 classify_table_index = ~0;
8064   u8 is_classify = 0;
8065   u8 resolve_host = 0, resolve_attached = 0;
8066   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8067   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8068   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8069
8070   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8071   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8072   /* Parse args required to build the message */
8073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8074     {
8075       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8076         ;
8077       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8078         ;
8079       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8080         {
8081           address_set = 1;
8082           is_ipv6 = 0;
8083         }
8084       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8085         {
8086           address_set = 1;
8087           is_ipv6 = 1;
8088         }
8089       else if (unformat (i, "/%d", &dst_address_length))
8090         {
8091           address_length_set = 1;
8092         }
8093
8094       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8095                                          &v4_next_hop_address))
8096         {
8097           next_hop_set = 1;
8098         }
8099       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8100                                          &v6_next_hop_address))
8101         {
8102           next_hop_set = 1;
8103         }
8104       else
8105         if (unformat
8106             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8107         {
8108           next_hop_set = 1;
8109         }
8110       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8111         {
8112           next_hop_set = 1;
8113         }
8114       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8115         ;
8116       else if (unformat (i, "weight %d", &next_hop_weight))
8117         ;
8118       else if (unformat (i, "drop"))
8119         {
8120           is_drop = 1;
8121         }
8122       else if (unformat (i, "null-send-unreach"))
8123         {
8124           is_unreach = 1;
8125         }
8126       else if (unformat (i, "null-send-prohibit"))
8127         {
8128           is_prohibit = 1;
8129         }
8130       else if (unformat (i, "local"))
8131         {
8132           is_local = 1;
8133         }
8134       else if (unformat (i, "classify %d", &classify_table_index))
8135         {
8136           is_classify = 1;
8137         }
8138       else if (unformat (i, "del"))
8139         is_add = 0;
8140       else if (unformat (i, "add"))
8141         is_add = 1;
8142       else if (unformat (i, "resolve-via-host"))
8143         resolve_host = 1;
8144       else if (unformat (i, "resolve-via-attached"))
8145         resolve_attached = 1;
8146       else if (unformat (i, "multipath"))
8147         is_multipath = 1;
8148       else if (unformat (i, "vrf %d", &vrf_id))
8149         ;
8150       else if (unformat (i, "count %d", &count))
8151         ;
8152       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8153         ;
8154       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8155         ;
8156       else if (unformat (i, "out-label %d", &next_hop_out_label))
8157         {
8158           vl_api_fib_mpls_label_t fib_label = {
8159             .label = ntohl (next_hop_out_label),
8160             .ttl = 64,
8161             .exp = 0,
8162           };
8163           vec_add1 (next_hop_out_label_stack, fib_label);
8164         }
8165       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8166         ;
8167       else if (unformat (i, "random"))
8168         random_add_del = 1;
8169       else if (unformat (i, "seed %d", &random_seed))
8170         ;
8171       else
8172         {
8173           clib_warning ("parse error '%U'", format_unformat_error, i);
8174           return -99;
8175         }
8176     }
8177
8178   if (!next_hop_set && !is_drop && !is_local &&
8179       !is_classify && !is_unreach && !is_prohibit &&
8180       MPLS_LABEL_INVALID == next_hop_via_label)
8181     {
8182       errmsg
8183         ("next hop / local / drop / unreach / prohibit / classify not set");
8184       return -99;
8185     }
8186
8187   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8188     {
8189       errmsg ("next hop and next-hop via label set");
8190       return -99;
8191     }
8192   if (address_set == 0)
8193     {
8194       errmsg ("missing addresses");
8195       return -99;
8196     }
8197
8198   if (address_length_set == 0)
8199     {
8200       errmsg ("missing address length");
8201       return -99;
8202     }
8203
8204   /* Generate a pile of unique, random routes */
8205   if (random_add_del)
8206     {
8207       u32 this_random_address;
8208       random_hash = hash_create (count, sizeof (uword));
8209
8210       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8211       for (j = 0; j <= count; j++)
8212         {
8213           do
8214             {
8215               this_random_address = random_u32 (&random_seed);
8216               this_random_address =
8217                 clib_host_to_net_u32 (this_random_address);
8218             }
8219           while (hash_get (random_hash, this_random_address));
8220           vec_add1 (random_vector, this_random_address);
8221           hash_set (random_hash, this_random_address, 1);
8222         }
8223       hash_free (random_hash);
8224       v4_dst_address.as_u32 = random_vector[0];
8225     }
8226
8227   if (count > 1)
8228     {
8229       /* Turn on async mode */
8230       vam->async_mode = 1;
8231       vam->async_errors = 0;
8232       before = vat_time_now (vam);
8233     }
8234
8235   for (j = 0; j < count; j++)
8236     {
8237       /* Construct the API message */
8238       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8239           vec_len (next_hop_out_label_stack));
8240
8241       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8242       mp->table_id = ntohl (vrf_id);
8243
8244       mp->is_add = is_add;
8245       mp->is_drop = is_drop;
8246       mp->is_unreach = is_unreach;
8247       mp->is_prohibit = is_prohibit;
8248       mp->is_ipv6 = is_ipv6;
8249       mp->is_local = is_local;
8250       mp->is_classify = is_classify;
8251       mp->is_multipath = is_multipath;
8252       mp->is_resolve_host = resolve_host;
8253       mp->is_resolve_attached = resolve_attached;
8254       mp->next_hop_weight = next_hop_weight;
8255       mp->next_hop_preference = 0;
8256       mp->dst_address_length = dst_address_length;
8257       mp->next_hop_table_id = ntohl (next_hop_table_id);
8258       mp->classify_table_index = ntohl (classify_table_index);
8259       mp->next_hop_via_label = ntohl (next_hop_via_label);
8260       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8261       if (0 != mp->next_hop_n_out_labels)
8262         {
8263           memcpy (mp->next_hop_out_label_stack,
8264                   next_hop_out_label_stack,
8265                   (vec_len (next_hop_out_label_stack) *
8266                    sizeof (vl_api_fib_mpls_label_t)));
8267           vec_free (next_hop_out_label_stack);
8268         }
8269
8270       if (is_ipv6)
8271         {
8272           clib_memcpy (mp->dst_address, &v6_dst_address,
8273                        sizeof (v6_dst_address));
8274           if (next_hop_set)
8275             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8276                          sizeof (v6_next_hop_address));
8277           increment_v6_address (&v6_dst_address);
8278         }
8279       else
8280         {
8281           clib_memcpy (mp->dst_address, &v4_dst_address,
8282                        sizeof (v4_dst_address));
8283           if (next_hop_set)
8284             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8285                          sizeof (v4_next_hop_address));
8286           if (random_add_del)
8287             v4_dst_address.as_u32 = random_vector[j + 1];
8288           else
8289             increment_v4_address (&v4_dst_address);
8290         }
8291       /* send it... */
8292       S (mp);
8293       /* If we receive SIGTERM, stop now... */
8294       if (vam->do_exit)
8295         break;
8296     }
8297
8298   /* When testing multiple add/del ops, use a control-ping to sync */
8299   if (count > 1)
8300     {
8301       vl_api_control_ping_t *mp_ping;
8302       f64 after;
8303       f64 timeout;
8304
8305       /* Shut off async mode */
8306       vam->async_mode = 0;
8307
8308       MPING (CONTROL_PING, mp_ping);
8309       S (mp_ping);
8310
8311       timeout = vat_time_now (vam) + 1.0;
8312       while (vat_time_now (vam) < timeout)
8313         if (vam->result_ready == 1)
8314           goto out;
8315       vam->retval = -99;
8316
8317     out:
8318       if (vam->retval == -99)
8319         errmsg ("timeout");
8320
8321       if (vam->async_errors > 0)
8322         {
8323           errmsg ("%d asynchronous errors", vam->async_errors);
8324           vam->retval = -98;
8325         }
8326       vam->async_errors = 0;
8327       after = vat_time_now (vam);
8328
8329       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8330       if (j > 0)
8331         count = j;
8332
8333       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8334              count, after - before, count / (after - before));
8335     }
8336   else
8337     {
8338       int ret;
8339
8340       /* Wait for a reply... */
8341       W (ret);
8342       return ret;
8343     }
8344
8345   /* Return the good/bad news */
8346   return (vam->retval);
8347 }
8348
8349 static int
8350 api_ip_mroute_add_del (vat_main_t * vam)
8351 {
8352   unformat_input_t *i = vam->input;
8353   vl_api_ip_mroute_add_del_t *mp;
8354   u32 sw_if_index = ~0, vrf_id = 0;
8355   u8 is_ipv6 = 0;
8356   u8 is_local = 0;
8357   u8 is_add = 1;
8358   u8 address_set = 0;
8359   u32 grp_address_length = 0;
8360   ip4_address_t v4_grp_address, v4_src_address;
8361   ip6_address_t v6_grp_address, v6_src_address;
8362   mfib_itf_flags_t iflags = 0;
8363   mfib_entry_flags_t eflags = 0;
8364   int ret;
8365
8366   /* Parse args required to build the message */
8367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8368     {
8369       if (unformat (i, "sw_if_index %d", &sw_if_index))
8370         ;
8371       else if (unformat (i, "%U %U",
8372                          unformat_ip4_address, &v4_src_address,
8373                          unformat_ip4_address, &v4_grp_address))
8374         {
8375           grp_address_length = 64;
8376           address_set = 1;
8377           is_ipv6 = 0;
8378         }
8379       else if (unformat (i, "%U %U",
8380                          unformat_ip6_address, &v6_src_address,
8381                          unformat_ip6_address, &v6_grp_address))
8382         {
8383           grp_address_length = 256;
8384           address_set = 1;
8385           is_ipv6 = 1;
8386         }
8387       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8388         {
8389           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8390           grp_address_length = 32;
8391           address_set = 1;
8392           is_ipv6 = 0;
8393         }
8394       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8395         {
8396           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8397           grp_address_length = 128;
8398           address_set = 1;
8399           is_ipv6 = 1;
8400         }
8401       else if (unformat (i, "/%d", &grp_address_length))
8402         ;
8403       else if (unformat (i, "local"))
8404         {
8405           is_local = 1;
8406         }
8407       else if (unformat (i, "del"))
8408         is_add = 0;
8409       else if (unformat (i, "add"))
8410         is_add = 1;
8411       else if (unformat (i, "vrf %d", &vrf_id))
8412         ;
8413       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8414         ;
8415       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8416         ;
8417       else
8418         {
8419           clib_warning ("parse error '%U'", format_unformat_error, i);
8420           return -99;
8421         }
8422     }
8423
8424   if (address_set == 0)
8425     {
8426       errmsg ("missing addresses\n");
8427       return -99;
8428     }
8429
8430   /* Construct the API message */
8431   M (IP_MROUTE_ADD_DEL, mp);
8432
8433   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8434   mp->table_id = ntohl (vrf_id);
8435
8436   mp->is_add = is_add;
8437   mp->is_ipv6 = is_ipv6;
8438   mp->is_local = is_local;
8439   mp->itf_flags = ntohl (iflags);
8440   mp->entry_flags = ntohl (eflags);
8441   mp->grp_address_length = grp_address_length;
8442   mp->grp_address_length = ntohs (mp->grp_address_length);
8443
8444   if (is_ipv6)
8445     {
8446       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8447       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8448     }
8449   else
8450     {
8451       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8452       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8453
8454     }
8455
8456   /* send it... */
8457   S (mp);
8458   /* Wait for a reply... */
8459   W (ret);
8460   return ret;
8461 }
8462
8463 static int
8464 api_mpls_table_add_del (vat_main_t * vam)
8465 {
8466   unformat_input_t *i = vam->input;
8467   vl_api_mpls_table_add_del_t *mp;
8468   u32 table_id = ~0;
8469   u8 is_add = 1;
8470   int ret = 0;
8471
8472   /* Parse args required to build the message */
8473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8474     {
8475       if (unformat (i, "table %d", &table_id))
8476         ;
8477       else if (unformat (i, "del"))
8478         is_add = 0;
8479       else if (unformat (i, "add"))
8480         is_add = 1;
8481       else
8482         {
8483           clib_warning ("parse error '%U'", format_unformat_error, i);
8484           return -99;
8485         }
8486     }
8487
8488   if (~0 == table_id)
8489     {
8490       errmsg ("missing table-ID");
8491       return -99;
8492     }
8493
8494   /* Construct the API message */
8495   M (MPLS_TABLE_ADD_DEL, mp);
8496
8497   mp->mt_table_id = ntohl (table_id);
8498   mp->mt_is_add = is_add;
8499
8500   /* send it... */
8501   S (mp);
8502
8503   /* Wait for a reply... */
8504   W (ret);
8505
8506   return ret;
8507 }
8508
8509 static int
8510 api_mpls_route_add_del (vat_main_t * vam)
8511 {
8512   unformat_input_t *i = vam->input;
8513   vl_api_mpls_route_add_del_t *mp;
8514   u32 sw_if_index = ~0, table_id = 0;
8515   u8 is_add = 1;
8516   u32 next_hop_weight = 1;
8517   u8 is_multipath = 0;
8518   u32 next_hop_table_id = 0;
8519   u8 next_hop_set = 0;
8520   ip4_address_t v4_next_hop_address = {
8521     .as_u32 = 0,
8522   };
8523   ip6_address_t v6_next_hop_address = { {0} };
8524   int count = 1;
8525   int j;
8526   f64 before = 0;
8527   u32 classify_table_index = ~0;
8528   u8 is_classify = 0;
8529   u8 resolve_host = 0, resolve_attached = 0;
8530   u8 is_interface_rx = 0;
8531   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8532   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8533   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8534   mpls_label_t local_label = MPLS_LABEL_INVALID;
8535   u8 is_eos = 0;
8536   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8537
8538   /* Parse args required to build the message */
8539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8540     {
8541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8542         ;
8543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8544         ;
8545       else if (unformat (i, "%d", &local_label))
8546         ;
8547       else if (unformat (i, "eos"))
8548         is_eos = 1;
8549       else if (unformat (i, "non-eos"))
8550         is_eos = 0;
8551       else if (unformat (i, "via %U", unformat_ip4_address,
8552                          &v4_next_hop_address))
8553         {
8554           next_hop_set = 1;
8555           next_hop_proto = DPO_PROTO_IP4;
8556         }
8557       else if (unformat (i, "via %U", unformat_ip6_address,
8558                          &v6_next_hop_address))
8559         {
8560           next_hop_set = 1;
8561           next_hop_proto = DPO_PROTO_IP6;
8562         }
8563       else if (unformat (i, "weight %d", &next_hop_weight))
8564         ;
8565       else if (unformat (i, "classify %d", &classify_table_index))
8566         {
8567           is_classify = 1;
8568         }
8569       else if (unformat (i, "del"))
8570         is_add = 0;
8571       else if (unformat (i, "add"))
8572         is_add = 1;
8573       else if (unformat (i, "resolve-via-host"))
8574         resolve_host = 1;
8575       else if (unformat (i, "resolve-via-attached"))
8576         resolve_attached = 1;
8577       else if (unformat (i, "multipath"))
8578         is_multipath = 1;
8579       else if (unformat (i, "count %d", &count))
8580         ;
8581       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8582         {
8583           next_hop_set = 1;
8584           next_hop_proto = DPO_PROTO_IP4;
8585         }
8586       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8587         {
8588           next_hop_set = 1;
8589           next_hop_proto = DPO_PROTO_IP6;
8590         }
8591       else
8592         if (unformat
8593             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8594              &sw_if_index))
8595         {
8596           next_hop_set = 1;
8597           next_hop_proto = DPO_PROTO_ETHERNET;
8598           is_interface_rx = 1;
8599         }
8600       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8601         {
8602           next_hop_set = 1;
8603           next_hop_proto = DPO_PROTO_ETHERNET;
8604           is_interface_rx = 1;
8605         }
8606       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8607         next_hop_set = 1;
8608       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8609         next_hop_set = 1;
8610       else if (unformat (i, "out-label %d", &next_hop_out_label))
8611         {
8612           vl_api_fib_mpls_label_t fib_label = {
8613             .label = ntohl (next_hop_out_label),
8614             .ttl = 64,
8615             .exp = 0,
8616           };
8617           vec_add1 (next_hop_out_label_stack, fib_label);
8618         }
8619       else
8620         {
8621           clib_warning ("parse error '%U'", format_unformat_error, i);
8622           return -99;
8623         }
8624     }
8625
8626   if (!next_hop_set && !is_classify)
8627     {
8628       errmsg ("next hop / classify not set");
8629       return -99;
8630     }
8631
8632   if (MPLS_LABEL_INVALID == local_label)
8633     {
8634       errmsg ("missing label");
8635       return -99;
8636     }
8637
8638   if (count > 1)
8639     {
8640       /* Turn on async mode */
8641       vam->async_mode = 1;
8642       vam->async_errors = 0;
8643       before = vat_time_now (vam);
8644     }
8645
8646   for (j = 0; j < count; j++)
8647     {
8648       /* Construct the API message */
8649       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8650           vec_len (next_hop_out_label_stack));
8651
8652       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8653       mp->mr_table_id = ntohl (table_id);
8654
8655       mp->mr_is_add = is_add;
8656       mp->mr_next_hop_proto = next_hop_proto;
8657       mp->mr_is_classify = is_classify;
8658       mp->mr_is_multipath = is_multipath;
8659       mp->mr_is_resolve_host = resolve_host;
8660       mp->mr_is_resolve_attached = resolve_attached;
8661       mp->mr_is_interface_rx = is_interface_rx;
8662       mp->mr_next_hop_weight = next_hop_weight;
8663       mp->mr_next_hop_preference = 0;
8664       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8665       mp->mr_classify_table_index = ntohl (classify_table_index);
8666       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8667       mp->mr_label = ntohl (local_label);
8668       mp->mr_eos = is_eos;
8669
8670       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8671       if (0 != mp->mr_next_hop_n_out_labels)
8672         {
8673           memcpy (mp->mr_next_hop_out_label_stack,
8674                   next_hop_out_label_stack,
8675                   vec_len (next_hop_out_label_stack) *
8676                   sizeof (vl_api_fib_mpls_label_t));
8677           vec_free (next_hop_out_label_stack);
8678         }
8679
8680       if (next_hop_set)
8681         {
8682           if (DPO_PROTO_IP4 == next_hop_proto)
8683             {
8684               clib_memcpy (mp->mr_next_hop,
8685                            &v4_next_hop_address,
8686                            sizeof (v4_next_hop_address));
8687             }
8688           else if (DPO_PROTO_IP6 == next_hop_proto)
8689
8690             {
8691               clib_memcpy (mp->mr_next_hop,
8692                            &v6_next_hop_address,
8693                            sizeof (v6_next_hop_address));
8694             }
8695         }
8696       local_label++;
8697
8698       /* send it... */
8699       S (mp);
8700       /* If we receive SIGTERM, stop now... */
8701       if (vam->do_exit)
8702         break;
8703     }
8704
8705   /* When testing multiple add/del ops, use a control-ping to sync */
8706   if (count > 1)
8707     {
8708       vl_api_control_ping_t *mp_ping;
8709       f64 after;
8710       f64 timeout;
8711
8712       /* Shut off async mode */
8713       vam->async_mode = 0;
8714
8715       MPING (CONTROL_PING, mp_ping);
8716       S (mp_ping);
8717
8718       timeout = vat_time_now (vam) + 1.0;
8719       while (vat_time_now (vam) < timeout)
8720         if (vam->result_ready == 1)
8721           goto out;
8722       vam->retval = -99;
8723
8724     out:
8725       if (vam->retval == -99)
8726         errmsg ("timeout");
8727
8728       if (vam->async_errors > 0)
8729         {
8730           errmsg ("%d asynchronous errors", vam->async_errors);
8731           vam->retval = -98;
8732         }
8733       vam->async_errors = 0;
8734       after = vat_time_now (vam);
8735
8736       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8737       if (j > 0)
8738         count = j;
8739
8740       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8741              count, after - before, count / (after - before));
8742     }
8743   else
8744     {
8745       int ret;
8746
8747       /* Wait for a reply... */
8748       W (ret);
8749       return ret;
8750     }
8751
8752   /* Return the good/bad news */
8753   return (vam->retval);
8754 }
8755
8756 static int
8757 api_mpls_ip_bind_unbind (vat_main_t * vam)
8758 {
8759   unformat_input_t *i = vam->input;
8760   vl_api_mpls_ip_bind_unbind_t *mp;
8761   u32 ip_table_id = 0;
8762   u8 is_bind = 1;
8763   u8 is_ip4 = 1;
8764   ip4_address_t v4_address;
8765   ip6_address_t v6_address;
8766   u32 address_length;
8767   u8 address_set = 0;
8768   mpls_label_t local_label = MPLS_LABEL_INVALID;
8769   int ret;
8770
8771   /* Parse args required to build the message */
8772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8773     {
8774       if (unformat (i, "%U/%d", unformat_ip4_address,
8775                     &v4_address, &address_length))
8776         {
8777           is_ip4 = 1;
8778           address_set = 1;
8779         }
8780       else if (unformat (i, "%U/%d", unformat_ip6_address,
8781                          &v6_address, &address_length))
8782         {
8783           is_ip4 = 0;
8784           address_set = 1;
8785         }
8786       else if (unformat (i, "%d", &local_label))
8787         ;
8788       else if (unformat (i, "table-id %d", &ip_table_id))
8789         ;
8790       else if (unformat (i, "unbind"))
8791         is_bind = 0;
8792       else if (unformat (i, "bind"))
8793         is_bind = 1;
8794       else
8795         {
8796           clib_warning ("parse error '%U'", format_unformat_error, i);
8797           return -99;
8798         }
8799     }
8800
8801   if (!address_set)
8802     {
8803       errmsg ("IP address not set");
8804       return -99;
8805     }
8806
8807   if (MPLS_LABEL_INVALID == local_label)
8808     {
8809       errmsg ("missing label");
8810       return -99;
8811     }
8812
8813   /* Construct the API message */
8814   M (MPLS_IP_BIND_UNBIND, mp);
8815
8816   mp->mb_is_bind = is_bind;
8817   mp->mb_is_ip4 = is_ip4;
8818   mp->mb_ip_table_id = ntohl (ip_table_id);
8819   mp->mb_mpls_table_id = 0;
8820   mp->mb_label = ntohl (local_label);
8821   mp->mb_address_length = address_length;
8822
8823   if (is_ip4)
8824     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8825   else
8826     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8827
8828   /* send it... */
8829   S (mp);
8830
8831   /* Wait for a reply... */
8832   W (ret);
8833   return ret;
8834 }
8835
8836 static int
8837 api_sr_mpls_policy_add (vat_main_t * vam)
8838 {
8839   unformat_input_t *i = vam->input;
8840   vl_api_sr_mpls_policy_add_t *mp;
8841   u32 bsid = 0;
8842   u32 weight = 1;
8843   u8 type = 0;
8844   u8 n_segments = 0;
8845   u32 sid;
8846   u32 *segments = NULL;
8847   int ret;
8848
8849   /* Parse args required to build the message */
8850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8851     {
8852       if (unformat (i, "bsid %d", &bsid))
8853         ;
8854       else if (unformat (i, "weight %d", &weight))
8855         ;
8856       else if (unformat (i, "spray"))
8857         type = 1;
8858       else if (unformat (i, "next %d", &sid))
8859         {
8860           n_segments += 1;
8861           vec_add1 (segments, htonl (sid));
8862         }
8863       else
8864         {
8865           clib_warning ("parse error '%U'", format_unformat_error, i);
8866           return -99;
8867         }
8868     }
8869
8870   if (bsid == 0)
8871     {
8872       errmsg ("bsid not set");
8873       return -99;
8874     }
8875
8876   if (n_segments == 0)
8877     {
8878       errmsg ("no sid in segment stack");
8879       return -99;
8880     }
8881
8882   /* Construct the API message */
8883   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8884
8885   mp->bsid = htonl (bsid);
8886   mp->weight = htonl (weight);
8887   mp->type = type;
8888   mp->n_segments = n_segments;
8889   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8890   vec_free (segments);
8891
8892   /* send it... */
8893   S (mp);
8894
8895   /* Wait for a reply... */
8896   W (ret);
8897   return ret;
8898 }
8899
8900 static int
8901 api_sr_mpls_policy_del (vat_main_t * vam)
8902 {
8903   unformat_input_t *i = vam->input;
8904   vl_api_sr_mpls_policy_del_t *mp;
8905   u32 bsid = 0;
8906   int ret;
8907
8908   /* Parse args required to build the message */
8909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8910     {
8911       if (unformat (i, "bsid %d", &bsid))
8912         ;
8913       else
8914         {
8915           clib_warning ("parse error '%U'", format_unformat_error, i);
8916           return -99;
8917         }
8918     }
8919
8920   if (bsid == 0)
8921     {
8922       errmsg ("bsid not set");
8923       return -99;
8924     }
8925
8926   /* Construct the API message */
8927   M (SR_MPLS_POLICY_DEL, mp);
8928
8929   mp->bsid = htonl (bsid);
8930
8931   /* send it... */
8932   S (mp);
8933
8934   /* Wait for a reply... */
8935   W (ret);
8936   return ret;
8937 }
8938
8939 static int
8940 api_bier_table_add_del (vat_main_t * vam)
8941 {
8942   unformat_input_t *i = vam->input;
8943   vl_api_bier_table_add_del_t *mp;
8944   u8 is_add = 1;
8945   u32 set = 0, sub_domain = 0, hdr_len = 3;
8946   mpls_label_t local_label = MPLS_LABEL_INVALID;
8947   int ret;
8948
8949   /* Parse args required to build the message */
8950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8951     {
8952       if (unformat (i, "sub-domain %d", &sub_domain))
8953         ;
8954       else if (unformat (i, "set %d", &set))
8955         ;
8956       else if (unformat (i, "label %d", &local_label))
8957         ;
8958       else if (unformat (i, "hdr-len %d", &hdr_len))
8959         ;
8960       else if (unformat (i, "add"))
8961         is_add = 1;
8962       else if (unformat (i, "del"))
8963         is_add = 0;
8964       else
8965         {
8966           clib_warning ("parse error '%U'", format_unformat_error, i);
8967           return -99;
8968         }
8969     }
8970
8971   if (MPLS_LABEL_INVALID == local_label)
8972     {
8973       errmsg ("missing label\n");
8974       return -99;
8975     }
8976
8977   /* Construct the API message */
8978   M (BIER_TABLE_ADD_DEL, mp);
8979
8980   mp->bt_is_add = is_add;
8981   mp->bt_label = ntohl (local_label);
8982   mp->bt_tbl_id.bt_set = set;
8983   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8984   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8985
8986   /* send it... */
8987   S (mp);
8988
8989   /* Wait for a reply... */
8990   W (ret);
8991
8992   return (ret);
8993 }
8994
8995 static int
8996 api_bier_route_add_del (vat_main_t * vam)
8997 {
8998   unformat_input_t *i = vam->input;
8999   vl_api_bier_route_add_del_t *mp;
9000   u8 is_add = 1;
9001   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9002   ip4_address_t v4_next_hop_address;
9003   ip6_address_t v6_next_hop_address;
9004   u8 next_hop_set = 0;
9005   u8 next_hop_proto_is_ip4 = 1;
9006   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9007   int ret;
9008
9009   /* Parse args required to build the message */
9010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9011     {
9012       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9013         {
9014           next_hop_proto_is_ip4 = 1;
9015           next_hop_set = 1;
9016         }
9017       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9018         {
9019           next_hop_proto_is_ip4 = 0;
9020           next_hop_set = 1;
9021         }
9022       if (unformat (i, "sub-domain %d", &sub_domain))
9023         ;
9024       else if (unformat (i, "set %d", &set))
9025         ;
9026       else if (unformat (i, "hdr-len %d", &hdr_len))
9027         ;
9028       else if (unformat (i, "bp %d", &bp))
9029         ;
9030       else if (unformat (i, "add"))
9031         is_add = 1;
9032       else if (unformat (i, "del"))
9033         is_add = 0;
9034       else if (unformat (i, "out-label %d", &next_hop_out_label))
9035         ;
9036       else
9037         {
9038           clib_warning ("parse error '%U'", format_unformat_error, i);
9039           return -99;
9040         }
9041     }
9042
9043   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9044     {
9045       errmsg ("next hop / label set\n");
9046       return -99;
9047     }
9048   if (0 == bp)
9049     {
9050       errmsg ("bit=position not set\n");
9051       return -99;
9052     }
9053
9054   /* Construct the API message */
9055   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9056
9057   mp->br_is_add = is_add;
9058   mp->br_tbl_id.bt_set = set;
9059   mp->br_tbl_id.bt_sub_domain = sub_domain;
9060   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9061   mp->br_bp = ntohs (bp);
9062   mp->br_n_paths = 1;
9063   mp->br_paths[0].n_labels = 1;
9064   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9065   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9066
9067   if (next_hop_proto_is_ip4)
9068     {
9069       clib_memcpy (mp->br_paths[0].next_hop,
9070                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9071     }
9072   else
9073     {
9074       clib_memcpy (mp->br_paths[0].next_hop,
9075                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9076     }
9077
9078   /* send it... */
9079   S (mp);
9080
9081   /* Wait for a reply... */
9082   W (ret);
9083
9084   return (ret);
9085 }
9086
9087 static int
9088 api_proxy_arp_add_del (vat_main_t * vam)
9089 {
9090   unformat_input_t *i = vam->input;
9091   vl_api_proxy_arp_add_del_t *mp;
9092   u32 vrf_id = 0;
9093   u8 is_add = 1;
9094   vl_api_ip4_address_t lo, hi;
9095   u8 range_set = 0;
9096   int ret;
9097
9098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9099     {
9100       if (unformat (i, "vrf %d", &vrf_id))
9101         ;
9102       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9103                          unformat_vl_api_ip4_address, &hi))
9104         range_set = 1;
9105       else if (unformat (i, "del"))
9106         is_add = 0;
9107       else
9108         {
9109           clib_warning ("parse error '%U'", format_unformat_error, i);
9110           return -99;
9111         }
9112     }
9113
9114   if (range_set == 0)
9115     {
9116       errmsg ("address range not set");
9117       return -99;
9118     }
9119
9120   M (PROXY_ARP_ADD_DEL, mp);
9121
9122   mp->proxy.table_id = ntohl (vrf_id);
9123   mp->is_add = is_add;
9124   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9125   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9126
9127   S (mp);
9128   W (ret);
9129   return ret;
9130 }
9131
9132 static int
9133 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9134 {
9135   unformat_input_t *i = vam->input;
9136   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9137   u32 sw_if_index;
9138   u8 enable = 1;
9139   u8 sw_if_index_set = 0;
9140   int ret;
9141
9142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9143     {
9144       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9145         sw_if_index_set = 1;
9146       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9147         sw_if_index_set = 1;
9148       else if (unformat (i, "enable"))
9149         enable = 1;
9150       else if (unformat (i, "disable"))
9151         enable = 0;
9152       else
9153         {
9154           clib_warning ("parse error '%U'", format_unformat_error, i);
9155           return -99;
9156         }
9157     }
9158
9159   if (sw_if_index_set == 0)
9160     {
9161       errmsg ("missing interface name or sw_if_index");
9162       return -99;
9163     }
9164
9165   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9166
9167   mp->sw_if_index = ntohl (sw_if_index);
9168   mp->enable_disable = enable;
9169
9170   S (mp);
9171   W (ret);
9172   return ret;
9173 }
9174
9175 static int
9176 api_mpls_tunnel_add_del (vat_main_t * vam)
9177 {
9178   unformat_input_t *i = vam->input;
9179   vl_api_mpls_tunnel_add_del_t *mp;
9180
9181   u8 is_add = 1;
9182   u8 l2_only = 0;
9183   u32 sw_if_index = ~0;
9184   u32 next_hop_sw_if_index = ~0;
9185   u32 next_hop_proto_is_ip4 = 1;
9186
9187   u32 next_hop_table_id = 0;
9188   ip4_address_t v4_next_hop_address = {
9189     .as_u32 = 0,
9190   };
9191   ip6_address_t v6_next_hop_address = { {0} };
9192   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9193   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9194   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9195   int ret;
9196
9197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9198     {
9199       if (unformat (i, "add"))
9200         is_add = 1;
9201       else
9202         if (unformat
9203             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9204         is_add = 0;
9205       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9206         is_add = 0;
9207       else if (unformat (i, "via %U",
9208                          unformat_ip4_address, &v4_next_hop_address))
9209         {
9210           next_hop_proto_is_ip4 = 1;
9211         }
9212       else if (unformat (i, "via %U",
9213                          unformat_ip6_address, &v6_next_hop_address))
9214         {
9215           next_hop_proto_is_ip4 = 0;
9216         }
9217       else if (unformat (i, "via-label %d", &next_hop_via_label))
9218         ;
9219       else
9220         if (unformat
9221             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9222         ;
9223       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9224         ;
9225       else if (unformat (i, "l2-only"))
9226         l2_only = 1;
9227       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9228         ;
9229       else if (unformat (i, "out-label %d", &next_hop_out_label))
9230         {
9231           vl_api_fib_mpls_label_t fib_label = {
9232             .label = ntohl (next_hop_out_label),
9233             .ttl = 64,
9234             .exp = 0,
9235           };
9236           vec_add1 (next_hop_out_label_stack, fib_label);
9237         }
9238       else
9239         {
9240           clib_warning ("parse error '%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9246       vec_len (next_hop_out_label_stack));
9247
9248   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9249   mp->mt_sw_if_index = ntohl (sw_if_index);
9250   mp->mt_is_add = is_add;
9251   mp->mt_l2_only = l2_only;
9252   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9253   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9254   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9255   mp->mt_next_hop_weight = 1;
9256   mp->mt_next_hop_preference = 0;
9257
9258   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9259
9260   if (0 != mp->mt_next_hop_n_out_labels)
9261     {
9262       clib_memcpy (mp->mt_next_hop_out_label_stack,
9263                    next_hop_out_label_stack,
9264                    (vec_len (next_hop_out_label_stack) *
9265                     sizeof (vl_api_fib_mpls_label_t)));
9266       vec_free (next_hop_out_label_stack);
9267     }
9268
9269   if (next_hop_proto_is_ip4)
9270     {
9271       clib_memcpy (mp->mt_next_hop,
9272                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9273     }
9274   else
9275     {
9276       clib_memcpy (mp->mt_next_hop,
9277                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9278     }
9279
9280   S (mp);
9281   W (ret);
9282   return ret;
9283 }
9284
9285 static int
9286 api_sw_interface_set_unnumbered (vat_main_t * vam)
9287 {
9288   unformat_input_t *i = vam->input;
9289   vl_api_sw_interface_set_unnumbered_t *mp;
9290   u32 sw_if_index;
9291   u32 unnum_sw_index = ~0;
9292   u8 is_add = 1;
9293   u8 sw_if_index_set = 0;
9294   int ret;
9295
9296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9297     {
9298       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9299         sw_if_index_set = 1;
9300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9301         sw_if_index_set = 1;
9302       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9303         ;
9304       else if (unformat (i, "del"))
9305         is_add = 0;
9306       else
9307         {
9308           clib_warning ("parse error '%U'", format_unformat_error, i);
9309           return -99;
9310         }
9311     }
9312
9313   if (sw_if_index_set == 0)
9314     {
9315       errmsg ("missing interface name or sw_if_index");
9316       return -99;
9317     }
9318
9319   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9320
9321   mp->sw_if_index = ntohl (sw_if_index);
9322   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9323   mp->is_add = is_add;
9324
9325   S (mp);
9326   W (ret);
9327   return ret;
9328 }
9329
9330 static int
9331 api_ip_neighbor_add_del (vat_main_t * vam)
9332 {
9333   vl_api_mac_address_t mac_address;
9334   unformat_input_t *i = vam->input;
9335   vl_api_ip_neighbor_add_del_t *mp;
9336   vl_api_address_t ip_address;
9337   u32 sw_if_index;
9338   u8 sw_if_index_set = 0;
9339   u8 is_add = 1;
9340   u8 mac_set = 0;
9341   u8 address_set = 0;
9342   int ret;
9343   ip_neighbor_flags_t flags;
9344
9345   flags = IP_NEIGHBOR_FLAG_NONE;
9346   clib_memset (&ip_address, 0, sizeof (ip_address));
9347   clib_memset (&mac_address, 0, sizeof (mac_address));
9348   /* Parse args required to build the message */
9349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9350     {
9351       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9352         {
9353           mac_set = 1;
9354         }
9355       else if (unformat (i, "del"))
9356         is_add = 0;
9357       else
9358         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9359         sw_if_index_set = 1;
9360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9361         sw_if_index_set = 1;
9362       else if (unformat (i, "static"))
9363         flags |= IP_NEIGHBOR_FLAG_STATIC;
9364       else if (unformat (i, "no-fib-entry"))
9365         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9366       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9367         address_set = 1;
9368       else
9369         {
9370           clib_warning ("parse error '%U'", format_unformat_error, i);
9371           return -99;
9372         }
9373     }
9374
9375   if (sw_if_index_set == 0)
9376     {
9377       errmsg ("missing interface name or sw_if_index");
9378       return -99;
9379     }
9380   if (!address_set)
9381     {
9382       errmsg ("no address set");
9383       return -99;
9384     }
9385
9386   /* Construct the API message */
9387   M (IP_NEIGHBOR_ADD_DEL, mp);
9388
9389   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9390   mp->is_add = is_add;
9391   mp->neighbor.flags = htonl (flags);
9392   if (mac_set)
9393     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9394                  sizeof (mac_address));
9395   if (address_set)
9396     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9397
9398   /* send it... */
9399   S (mp);
9400
9401   /* Wait for a reply, return good/bad news  */
9402   W (ret);
9403   return ret;
9404 }
9405
9406 static int
9407 api_create_vlan_subif (vat_main_t * vam)
9408 {
9409   unformat_input_t *i = vam->input;
9410   vl_api_create_vlan_subif_t *mp;
9411   u32 sw_if_index;
9412   u8 sw_if_index_set = 0;
9413   u32 vlan_id;
9414   u8 vlan_id_set = 0;
9415   int ret;
9416
9417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9418     {
9419       if (unformat (i, "sw_if_index %d", &sw_if_index))
9420         sw_if_index_set = 1;
9421       else
9422         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9423         sw_if_index_set = 1;
9424       else if (unformat (i, "vlan %d", &vlan_id))
9425         vlan_id_set = 1;
9426       else
9427         {
9428           clib_warning ("parse error '%U'", format_unformat_error, i);
9429           return -99;
9430         }
9431     }
9432
9433   if (sw_if_index_set == 0)
9434     {
9435       errmsg ("missing interface name or sw_if_index");
9436       return -99;
9437     }
9438
9439   if (vlan_id_set == 0)
9440     {
9441       errmsg ("missing vlan_id");
9442       return -99;
9443     }
9444   M (CREATE_VLAN_SUBIF, mp);
9445
9446   mp->sw_if_index = ntohl (sw_if_index);
9447   mp->vlan_id = ntohl (vlan_id);
9448
9449   S (mp);
9450   W (ret);
9451   return ret;
9452 }
9453
9454 #define foreach_create_subif_bit                \
9455 _(no_tags)                                      \
9456 _(one_tag)                                      \
9457 _(two_tags)                                     \
9458 _(dot1ad)                                       \
9459 _(exact_match)                                  \
9460 _(default_sub)                                  \
9461 _(outer_vlan_id_any)                            \
9462 _(inner_vlan_id_any)
9463
9464 static int
9465 api_create_subif (vat_main_t * vam)
9466 {
9467   unformat_input_t *i = vam->input;
9468   vl_api_create_subif_t *mp;
9469   u32 sw_if_index;
9470   u8 sw_if_index_set = 0;
9471   u32 sub_id;
9472   u8 sub_id_set = 0;
9473   u32 no_tags = 0;
9474   u32 one_tag = 0;
9475   u32 two_tags = 0;
9476   u32 dot1ad = 0;
9477   u32 exact_match = 0;
9478   u32 default_sub = 0;
9479   u32 outer_vlan_id_any = 0;
9480   u32 inner_vlan_id_any = 0;
9481   u32 tmp;
9482   u16 outer_vlan_id = 0;
9483   u16 inner_vlan_id = 0;
9484   int ret;
9485
9486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9487     {
9488       if (unformat (i, "sw_if_index %d", &sw_if_index))
9489         sw_if_index_set = 1;
9490       else
9491         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9492         sw_if_index_set = 1;
9493       else if (unformat (i, "sub_id %d", &sub_id))
9494         sub_id_set = 1;
9495       else if (unformat (i, "outer_vlan_id %d", &tmp))
9496         outer_vlan_id = tmp;
9497       else if (unformat (i, "inner_vlan_id %d", &tmp))
9498         inner_vlan_id = tmp;
9499
9500 #define _(a) else if (unformat (i, #a)) a = 1 ;
9501       foreach_create_subif_bit
9502 #undef _
9503         else
9504         {
9505           clib_warning ("parse error '%U'", format_unformat_error, i);
9506           return -99;
9507         }
9508     }
9509
9510   if (sw_if_index_set == 0)
9511     {
9512       errmsg ("missing interface name or sw_if_index");
9513       return -99;
9514     }
9515
9516   if (sub_id_set == 0)
9517     {
9518       errmsg ("missing sub_id");
9519       return -99;
9520     }
9521   M (CREATE_SUBIF, mp);
9522
9523   mp->sw_if_index = ntohl (sw_if_index);
9524   mp->sub_id = ntohl (sub_id);
9525
9526 #define _(a) mp->a = a;
9527   foreach_create_subif_bit;
9528 #undef _
9529
9530   mp->outer_vlan_id = ntohs (outer_vlan_id);
9531   mp->inner_vlan_id = ntohs (inner_vlan_id);
9532
9533   S (mp);
9534   W (ret);
9535   return ret;
9536 }
9537
9538 static int
9539 api_reset_fib (vat_main_t * vam)
9540 {
9541   unformat_input_t *i = vam->input;
9542   vl_api_reset_fib_t *mp;
9543   u32 vrf_id = 0;
9544   u8 is_ipv6 = 0;
9545   u8 vrf_id_set = 0;
9546
9547   int ret;
9548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9549     {
9550       if (unformat (i, "vrf %d", &vrf_id))
9551         vrf_id_set = 1;
9552       else if (unformat (i, "ipv6"))
9553         is_ipv6 = 1;
9554       else
9555         {
9556           clib_warning ("parse error '%U'", format_unformat_error, i);
9557           return -99;
9558         }
9559     }
9560
9561   if (vrf_id_set == 0)
9562     {
9563       errmsg ("missing vrf id");
9564       return -99;
9565     }
9566
9567   M (RESET_FIB, mp);
9568
9569   mp->vrf_id = ntohl (vrf_id);
9570   mp->is_ipv6 = is_ipv6;
9571
9572   S (mp);
9573   W (ret);
9574   return ret;
9575 }
9576
9577 static int
9578 api_dhcp_proxy_config (vat_main_t * vam)
9579 {
9580   unformat_input_t *i = vam->input;
9581   vl_api_dhcp_proxy_config_t *mp;
9582   u32 rx_vrf_id = 0;
9583   u32 server_vrf_id = 0;
9584   u8 is_add = 1;
9585   u8 v4_address_set = 0;
9586   u8 v6_address_set = 0;
9587   ip4_address_t v4address;
9588   ip6_address_t v6address;
9589   u8 v4_src_address_set = 0;
9590   u8 v6_src_address_set = 0;
9591   ip4_address_t v4srcaddress;
9592   ip6_address_t v6srcaddress;
9593   int ret;
9594
9595   /* Parse args required to build the message */
9596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9597     {
9598       if (unformat (i, "del"))
9599         is_add = 0;
9600       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9601         ;
9602       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9603         ;
9604       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9605         v4_address_set = 1;
9606       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9607         v6_address_set = 1;
9608       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9609         v4_src_address_set = 1;
9610       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9611         v6_src_address_set = 1;
9612       else
9613         break;
9614     }
9615
9616   if (v4_address_set && v6_address_set)
9617     {
9618       errmsg ("both v4 and v6 server addresses set");
9619       return -99;
9620     }
9621   if (!v4_address_set && !v6_address_set)
9622     {
9623       errmsg ("no server addresses set");
9624       return -99;
9625     }
9626
9627   if (v4_src_address_set && v6_src_address_set)
9628     {
9629       errmsg ("both v4 and v6  src addresses set");
9630       return -99;
9631     }
9632   if (!v4_src_address_set && !v6_src_address_set)
9633     {
9634       errmsg ("no src addresses set");
9635       return -99;
9636     }
9637
9638   if (!(v4_src_address_set && v4_address_set) &&
9639       !(v6_src_address_set && v6_address_set))
9640     {
9641       errmsg ("no matching server and src addresses set");
9642       return -99;
9643     }
9644
9645   /* Construct the API message */
9646   M (DHCP_PROXY_CONFIG, mp);
9647
9648   mp->is_add = is_add;
9649   mp->rx_vrf_id = ntohl (rx_vrf_id);
9650   mp->server_vrf_id = ntohl (server_vrf_id);
9651   if (v6_address_set)
9652     {
9653       mp->is_ipv6 = 1;
9654       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9655       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9656     }
9657   else
9658     {
9659       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9660       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9661     }
9662
9663   /* send it... */
9664   S (mp);
9665
9666   /* Wait for a reply, return good/bad news  */
9667   W (ret);
9668   return ret;
9669 }
9670
9671 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9672 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9673
9674 static void
9675 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9676 {
9677   vat_main_t *vam = &vat_main;
9678   u32 i, count = mp->count;
9679   vl_api_dhcp_server_t *s;
9680
9681   if (mp->is_ipv6)
9682     print (vam->ofp,
9683            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9684            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9685            ntohl (mp->rx_vrf_id),
9686            format_ip6_address, mp->dhcp_src_address,
9687            mp->vss_type, mp->vss_vpn_ascii_id,
9688            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9689   else
9690     print (vam->ofp,
9691            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9692            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9693            ntohl (mp->rx_vrf_id),
9694            format_ip4_address, mp->dhcp_src_address,
9695            mp->vss_type, mp->vss_vpn_ascii_id,
9696            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9697
9698   for (i = 0; i < count; i++)
9699     {
9700       s = &mp->servers[i];
9701
9702       if (mp->is_ipv6)
9703         print (vam->ofp,
9704                " Server Table-ID %d, Server Address %U",
9705                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9706       else
9707         print (vam->ofp,
9708                " Server Table-ID %d, Server Address %U",
9709                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9710     }
9711 }
9712
9713 static void vl_api_dhcp_proxy_details_t_handler_json
9714   (vl_api_dhcp_proxy_details_t * mp)
9715 {
9716   vat_main_t *vam = &vat_main;
9717   vat_json_node_t *node = NULL;
9718   u32 i, count = mp->count;
9719   struct in_addr ip4;
9720   struct in6_addr ip6;
9721   vl_api_dhcp_server_t *s;
9722
9723   if (VAT_JSON_ARRAY != vam->json_tree.type)
9724     {
9725       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9726       vat_json_init_array (&vam->json_tree);
9727     }
9728   node = vat_json_array_add (&vam->json_tree);
9729
9730   vat_json_init_object (node);
9731   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9732   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9733                              sizeof (mp->vss_type));
9734   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9735                                    mp->vss_vpn_ascii_id);
9736   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9737   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9738
9739   if (mp->is_ipv6)
9740     {
9741       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9742       vat_json_object_add_ip6 (node, "src_address", ip6);
9743     }
9744   else
9745     {
9746       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9747       vat_json_object_add_ip4 (node, "src_address", ip4);
9748     }
9749
9750   for (i = 0; i < count; i++)
9751     {
9752       s = &mp->servers[i];
9753
9754       vat_json_object_add_uint (node, "server-table-id",
9755                                 ntohl (s->server_vrf_id));
9756
9757       if (mp->is_ipv6)
9758         {
9759           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9760           vat_json_object_add_ip4 (node, "src_address", ip4);
9761         }
9762       else
9763         {
9764           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9765           vat_json_object_add_ip6 (node, "server_address", ip6);
9766         }
9767     }
9768 }
9769
9770 static int
9771 api_dhcp_proxy_dump (vat_main_t * vam)
9772 {
9773   unformat_input_t *i = vam->input;
9774   vl_api_control_ping_t *mp_ping;
9775   vl_api_dhcp_proxy_dump_t *mp;
9776   u8 is_ipv6 = 0;
9777   int ret;
9778
9779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9780     {
9781       if (unformat (i, "ipv6"))
9782         is_ipv6 = 1;
9783       else
9784         {
9785           clib_warning ("parse error '%U'", format_unformat_error, i);
9786           return -99;
9787         }
9788     }
9789
9790   M (DHCP_PROXY_DUMP, mp);
9791
9792   mp->is_ip6 = is_ipv6;
9793   S (mp);
9794
9795   /* Use a control ping for synchronization */
9796   MPING (CONTROL_PING, mp_ping);
9797   S (mp_ping);
9798
9799   W (ret);
9800   return ret;
9801 }
9802
9803 static int
9804 api_dhcp_proxy_set_vss (vat_main_t * vam)
9805 {
9806   unformat_input_t *i = vam->input;
9807   vl_api_dhcp_proxy_set_vss_t *mp;
9808   u8 is_ipv6 = 0;
9809   u8 is_add = 1;
9810   u32 tbl_id = ~0;
9811   u8 vss_type = VSS_TYPE_DEFAULT;
9812   u8 *vpn_ascii_id = 0;
9813   u32 oui = 0;
9814   u32 fib_id = 0;
9815   int ret;
9816
9817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9818     {
9819       if (unformat (i, "tbl_id %d", &tbl_id))
9820         ;
9821       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9822         vss_type = VSS_TYPE_ASCII;
9823       else if (unformat (i, "fib_id %d", &fib_id))
9824         vss_type = VSS_TYPE_VPN_ID;
9825       else if (unformat (i, "oui %d", &oui))
9826         vss_type = VSS_TYPE_VPN_ID;
9827       else if (unformat (i, "ipv6"))
9828         is_ipv6 = 1;
9829       else if (unformat (i, "del"))
9830         is_add = 0;
9831       else
9832         break;
9833     }
9834
9835   if (tbl_id == ~0)
9836     {
9837       errmsg ("missing tbl_id ");
9838       vec_free (vpn_ascii_id);
9839       return -99;
9840     }
9841
9842   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9843     {
9844       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9845       vec_free (vpn_ascii_id);
9846       return -99;
9847     }
9848
9849   M (DHCP_PROXY_SET_VSS, mp);
9850   mp->tbl_id = ntohl (tbl_id);
9851   mp->vss_type = vss_type;
9852   if (vpn_ascii_id)
9853     {
9854       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9855       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9856     }
9857   mp->vpn_index = ntohl (fib_id);
9858   mp->oui = ntohl (oui);
9859   mp->is_ipv6 = is_ipv6;
9860   mp->is_add = is_add;
9861
9862   S (mp);
9863   W (ret);
9864
9865   vec_free (vpn_ascii_id);
9866   return ret;
9867 }
9868
9869 static int
9870 api_dhcp_client_config (vat_main_t * vam)
9871 {
9872   unformat_input_t *i = vam->input;
9873   vl_api_dhcp_client_config_t *mp;
9874   u32 sw_if_index;
9875   u8 sw_if_index_set = 0;
9876   u8 is_add = 1;
9877   u8 *hostname = 0;
9878   u8 disable_event = 0;
9879   int ret;
9880
9881   /* Parse args required to build the message */
9882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9883     {
9884       if (unformat (i, "del"))
9885         is_add = 0;
9886       else
9887         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9888         sw_if_index_set = 1;
9889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9890         sw_if_index_set = 1;
9891       else if (unformat (i, "hostname %s", &hostname))
9892         ;
9893       else if (unformat (i, "disable_event"))
9894         disable_event = 1;
9895       else
9896         break;
9897     }
9898
9899   if (sw_if_index_set == 0)
9900     {
9901       errmsg ("missing interface name or sw_if_index");
9902       return -99;
9903     }
9904
9905   if (vec_len (hostname) > 63)
9906     {
9907       errmsg ("hostname too long");
9908     }
9909   vec_add1 (hostname, 0);
9910
9911   /* Construct the API message */
9912   M (DHCP_CLIENT_CONFIG, mp);
9913
9914   mp->is_add = is_add;
9915   mp->client.sw_if_index = htonl (sw_if_index);
9916   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9917   vec_free (hostname);
9918   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9919   mp->client.pid = htonl (getpid ());
9920
9921   /* send it... */
9922   S (mp);
9923
9924   /* Wait for a reply, return good/bad news  */
9925   W (ret);
9926   return ret;
9927 }
9928
9929 static int
9930 api_set_ip_flow_hash (vat_main_t * vam)
9931 {
9932   unformat_input_t *i = vam->input;
9933   vl_api_set_ip_flow_hash_t *mp;
9934   u32 vrf_id = 0;
9935   u8 is_ipv6 = 0;
9936   u8 vrf_id_set = 0;
9937   u8 src = 0;
9938   u8 dst = 0;
9939   u8 sport = 0;
9940   u8 dport = 0;
9941   u8 proto = 0;
9942   u8 reverse = 0;
9943   int ret;
9944
9945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9946     {
9947       if (unformat (i, "vrf %d", &vrf_id))
9948         vrf_id_set = 1;
9949       else if (unformat (i, "ipv6"))
9950         is_ipv6 = 1;
9951       else if (unformat (i, "src"))
9952         src = 1;
9953       else if (unformat (i, "dst"))
9954         dst = 1;
9955       else if (unformat (i, "sport"))
9956         sport = 1;
9957       else if (unformat (i, "dport"))
9958         dport = 1;
9959       else if (unformat (i, "proto"))
9960         proto = 1;
9961       else if (unformat (i, "reverse"))
9962         reverse = 1;
9963
9964       else
9965         {
9966           clib_warning ("parse error '%U'", format_unformat_error, i);
9967           return -99;
9968         }
9969     }
9970
9971   if (vrf_id_set == 0)
9972     {
9973       errmsg ("missing vrf id");
9974       return -99;
9975     }
9976
9977   M (SET_IP_FLOW_HASH, mp);
9978   mp->src = src;
9979   mp->dst = dst;
9980   mp->sport = sport;
9981   mp->dport = dport;
9982   mp->proto = proto;
9983   mp->reverse = reverse;
9984   mp->vrf_id = ntohl (vrf_id);
9985   mp->is_ipv6 = is_ipv6;
9986
9987   S (mp);
9988   W (ret);
9989   return ret;
9990 }
9991
9992 static int
9993 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9994 {
9995   unformat_input_t *i = vam->input;
9996   vl_api_sw_interface_ip6_enable_disable_t *mp;
9997   u32 sw_if_index;
9998   u8 sw_if_index_set = 0;
9999   u8 enable = 0;
10000   int ret;
10001
10002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10003     {
10004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10005         sw_if_index_set = 1;
10006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10007         sw_if_index_set = 1;
10008       else if (unformat (i, "enable"))
10009         enable = 1;
10010       else if (unformat (i, "disable"))
10011         enable = 0;
10012       else
10013         {
10014           clib_warning ("parse error '%U'", format_unformat_error, i);
10015           return -99;
10016         }
10017     }
10018
10019   if (sw_if_index_set == 0)
10020     {
10021       errmsg ("missing interface name or sw_if_index");
10022       return -99;
10023     }
10024
10025   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10026
10027   mp->sw_if_index = ntohl (sw_if_index);
10028   mp->enable = enable;
10029
10030   S (mp);
10031   W (ret);
10032   return ret;
10033 }
10034
10035 static int
10036 api_ip6nd_proxy_add_del (vat_main_t * vam)
10037 {
10038   unformat_input_t *i = vam->input;
10039   vl_api_ip6nd_proxy_add_del_t *mp;
10040   u32 sw_if_index = ~0;
10041   u8 v6_address_set = 0;
10042   vl_api_ip6_address_t v6address;
10043   u8 is_del = 0;
10044   int ret;
10045
10046   /* Parse args required to build the message */
10047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10048     {
10049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10050         ;
10051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10052         ;
10053       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10054         v6_address_set = 1;
10055       if (unformat (i, "del"))
10056         is_del = 1;
10057       else
10058         {
10059           clib_warning ("parse error '%U'", format_unformat_error, i);
10060           return -99;
10061         }
10062     }
10063
10064   if (sw_if_index == ~0)
10065     {
10066       errmsg ("missing interface name or sw_if_index");
10067       return -99;
10068     }
10069   if (!v6_address_set)
10070     {
10071       errmsg ("no address set");
10072       return -99;
10073     }
10074
10075   /* Construct the API message */
10076   M (IP6ND_PROXY_ADD_DEL, mp);
10077
10078   mp->is_del = is_del;
10079   mp->sw_if_index = ntohl (sw_if_index);
10080   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10081
10082   /* send it... */
10083   S (mp);
10084
10085   /* Wait for a reply, return good/bad news  */
10086   W (ret);
10087   return ret;
10088 }
10089
10090 static int
10091 api_ip6nd_proxy_dump (vat_main_t * vam)
10092 {
10093   vl_api_ip6nd_proxy_dump_t *mp;
10094   vl_api_control_ping_t *mp_ping;
10095   int ret;
10096
10097   M (IP6ND_PROXY_DUMP, mp);
10098
10099   S (mp);
10100
10101   /* Use a control ping for synchronization */
10102   MPING (CONTROL_PING, mp_ping);
10103   S (mp_ping);
10104
10105   W (ret);
10106   return ret;
10107 }
10108
10109 static void vl_api_ip6nd_proxy_details_t_handler
10110   (vl_api_ip6nd_proxy_details_t * mp)
10111 {
10112   vat_main_t *vam = &vat_main;
10113
10114   print (vam->ofp, "host %U sw_if_index %d",
10115          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10116 }
10117
10118 static void vl_api_ip6nd_proxy_details_t_handler_json
10119   (vl_api_ip6nd_proxy_details_t * mp)
10120 {
10121   vat_main_t *vam = &vat_main;
10122   struct in6_addr ip6;
10123   vat_json_node_t *node = NULL;
10124
10125   if (VAT_JSON_ARRAY != vam->json_tree.type)
10126     {
10127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10128       vat_json_init_array (&vam->json_tree);
10129     }
10130   node = vat_json_array_add (&vam->json_tree);
10131
10132   vat_json_init_object (node);
10133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10134
10135   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10136   vat_json_object_add_ip6 (node, "host", ip6);
10137 }
10138
10139 static int
10140 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10141 {
10142   unformat_input_t *i = vam->input;
10143   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10144   u32 sw_if_index;
10145   u8 sw_if_index_set = 0;
10146   u32 address_length = 0;
10147   u8 v6_address_set = 0;
10148   vl_api_prefix_t pfx;
10149   u8 use_default = 0;
10150   u8 no_advertise = 0;
10151   u8 off_link = 0;
10152   u8 no_autoconfig = 0;
10153   u8 no_onlink = 0;
10154   u8 is_no = 0;
10155   u32 val_lifetime = 0;
10156   u32 pref_lifetime = 0;
10157   int ret;
10158
10159   /* Parse args required to build the message */
10160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10161     {
10162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10163         sw_if_index_set = 1;
10164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10165         sw_if_index_set = 1;
10166       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10167         v6_address_set = 1;
10168       else if (unformat (i, "val_life %d", &val_lifetime))
10169         ;
10170       else if (unformat (i, "pref_life %d", &pref_lifetime))
10171         ;
10172       else if (unformat (i, "def"))
10173         use_default = 1;
10174       else if (unformat (i, "noadv"))
10175         no_advertise = 1;
10176       else if (unformat (i, "offl"))
10177         off_link = 1;
10178       else if (unformat (i, "noauto"))
10179         no_autoconfig = 1;
10180       else if (unformat (i, "nolink"))
10181         no_onlink = 1;
10182       else if (unformat (i, "isno"))
10183         is_no = 1;
10184       else
10185         {
10186           clib_warning ("parse error '%U'", format_unformat_error, i);
10187           return -99;
10188         }
10189     }
10190
10191   if (sw_if_index_set == 0)
10192     {
10193       errmsg ("missing interface name or sw_if_index");
10194       return -99;
10195     }
10196   if (!v6_address_set)
10197     {
10198       errmsg ("no address set");
10199       return -99;
10200     }
10201
10202   /* Construct the API message */
10203   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10204
10205   mp->sw_if_index = ntohl (sw_if_index);
10206   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10207   mp->use_default = use_default;
10208   mp->no_advertise = no_advertise;
10209   mp->off_link = off_link;
10210   mp->no_autoconfig = no_autoconfig;
10211   mp->no_onlink = no_onlink;
10212   mp->is_no = is_no;
10213   mp->val_lifetime = ntohl (val_lifetime);
10214   mp->pref_lifetime = ntohl (pref_lifetime);
10215
10216   /* send it... */
10217   S (mp);
10218
10219   /* Wait for a reply, return good/bad news  */
10220   W (ret);
10221   return ret;
10222 }
10223
10224 static int
10225 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10226 {
10227   unformat_input_t *i = vam->input;
10228   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10229   u32 sw_if_index;
10230   u8 sw_if_index_set = 0;
10231   u8 suppress = 0;
10232   u8 managed = 0;
10233   u8 other = 0;
10234   u8 ll_option = 0;
10235   u8 send_unicast = 0;
10236   u8 cease = 0;
10237   u8 is_no = 0;
10238   u8 default_router = 0;
10239   u32 max_interval = 0;
10240   u32 min_interval = 0;
10241   u32 lifetime = 0;
10242   u32 initial_count = 0;
10243   u32 initial_interval = 0;
10244   int ret;
10245
10246
10247   /* Parse args required to build the message */
10248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249     {
10250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10251         sw_if_index_set = 1;
10252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10253         sw_if_index_set = 1;
10254       else if (unformat (i, "maxint %d", &max_interval))
10255         ;
10256       else if (unformat (i, "minint %d", &min_interval))
10257         ;
10258       else if (unformat (i, "life %d", &lifetime))
10259         ;
10260       else if (unformat (i, "count %d", &initial_count))
10261         ;
10262       else if (unformat (i, "interval %d", &initial_interval))
10263         ;
10264       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10265         suppress = 1;
10266       else if (unformat (i, "managed"))
10267         managed = 1;
10268       else if (unformat (i, "other"))
10269         other = 1;
10270       else if (unformat (i, "ll"))
10271         ll_option = 1;
10272       else if (unformat (i, "send"))
10273         send_unicast = 1;
10274       else if (unformat (i, "cease"))
10275         cease = 1;
10276       else if (unformat (i, "isno"))
10277         is_no = 1;
10278       else if (unformat (i, "def"))
10279         default_router = 1;
10280       else
10281         {
10282           clib_warning ("parse error '%U'", format_unformat_error, i);
10283           return -99;
10284         }
10285     }
10286
10287   if (sw_if_index_set == 0)
10288     {
10289       errmsg ("missing interface name or sw_if_index");
10290       return -99;
10291     }
10292
10293   /* Construct the API message */
10294   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10295
10296   mp->sw_if_index = ntohl (sw_if_index);
10297   mp->max_interval = ntohl (max_interval);
10298   mp->min_interval = ntohl (min_interval);
10299   mp->lifetime = ntohl (lifetime);
10300   mp->initial_count = ntohl (initial_count);
10301   mp->initial_interval = ntohl (initial_interval);
10302   mp->suppress = suppress;
10303   mp->managed = managed;
10304   mp->other = other;
10305   mp->ll_option = ll_option;
10306   mp->send_unicast = send_unicast;
10307   mp->cease = cease;
10308   mp->is_no = is_no;
10309   mp->default_router = default_router;
10310
10311   /* send it... */
10312   S (mp);
10313
10314   /* Wait for a reply, return good/bad news  */
10315   W (ret);
10316   return ret;
10317 }
10318
10319 static int
10320 api_set_arp_neighbor_limit (vat_main_t * vam)
10321 {
10322   unformat_input_t *i = vam->input;
10323   vl_api_set_arp_neighbor_limit_t *mp;
10324   u32 arp_nbr_limit;
10325   u8 limit_set = 0;
10326   u8 is_ipv6 = 0;
10327   int ret;
10328
10329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10330     {
10331       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10332         limit_set = 1;
10333       else if (unformat (i, "ipv6"))
10334         is_ipv6 = 1;
10335       else
10336         {
10337           clib_warning ("parse error '%U'", format_unformat_error, i);
10338           return -99;
10339         }
10340     }
10341
10342   if (limit_set == 0)
10343     {
10344       errmsg ("missing limit value");
10345       return -99;
10346     }
10347
10348   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10349
10350   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10351   mp->is_ipv6 = is_ipv6;
10352
10353   S (mp);
10354   W (ret);
10355   return ret;
10356 }
10357
10358 static int
10359 api_l2_patch_add_del (vat_main_t * vam)
10360 {
10361   unformat_input_t *i = vam->input;
10362   vl_api_l2_patch_add_del_t *mp;
10363   u32 rx_sw_if_index;
10364   u8 rx_sw_if_index_set = 0;
10365   u32 tx_sw_if_index;
10366   u8 tx_sw_if_index_set = 0;
10367   u8 is_add = 1;
10368   int ret;
10369
10370   /* Parse args required to build the message */
10371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10374         rx_sw_if_index_set = 1;
10375       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10376         tx_sw_if_index_set = 1;
10377       else if (unformat (i, "rx"))
10378         {
10379           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10380             {
10381               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10382                             &rx_sw_if_index))
10383                 rx_sw_if_index_set = 1;
10384             }
10385           else
10386             break;
10387         }
10388       else if (unformat (i, "tx"))
10389         {
10390           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10391             {
10392               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10393                             &tx_sw_if_index))
10394                 tx_sw_if_index_set = 1;
10395             }
10396           else
10397             break;
10398         }
10399       else if (unformat (i, "del"))
10400         is_add = 0;
10401       else
10402         break;
10403     }
10404
10405   if (rx_sw_if_index_set == 0)
10406     {
10407       errmsg ("missing rx interface name or rx_sw_if_index");
10408       return -99;
10409     }
10410
10411   if (tx_sw_if_index_set == 0)
10412     {
10413       errmsg ("missing tx interface name or tx_sw_if_index");
10414       return -99;
10415     }
10416
10417   M (L2_PATCH_ADD_DEL, mp);
10418
10419   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10420   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10421   mp->is_add = is_add;
10422
10423   S (mp);
10424   W (ret);
10425   return ret;
10426 }
10427
10428 u8 is_del;
10429 u8 localsid_addr[16];
10430 u8 end_psp;
10431 u8 behavior;
10432 u32 sw_if_index;
10433 u32 vlan_index;
10434 u32 fib_table;
10435 u8 nh_addr[16];
10436
10437 static int
10438 api_sr_localsid_add_del (vat_main_t * vam)
10439 {
10440   unformat_input_t *i = vam->input;
10441   vl_api_sr_localsid_add_del_t *mp;
10442
10443   u8 is_del;
10444   ip6_address_t localsid;
10445   u8 end_psp = 0;
10446   u8 behavior = ~0;
10447   u32 sw_if_index;
10448   u32 fib_table = ~(u32) 0;
10449   ip6_address_t nh_addr6;
10450   ip4_address_t nh_addr4;
10451   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10452   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10453
10454   bool nexthop_set = 0;
10455
10456   int ret;
10457
10458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10459     {
10460       if (unformat (i, "del"))
10461         is_del = 1;
10462       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10463       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10464         nexthop_set = 1;
10465       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10466         nexthop_set = 1;
10467       else if (unformat (i, "behavior %u", &behavior));
10468       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10469       else if (unformat (i, "fib-table %u", &fib_table));
10470       else if (unformat (i, "end.psp %u", &behavior));
10471       else
10472         break;
10473     }
10474
10475   M (SR_LOCALSID_ADD_DEL, mp);
10476
10477   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10478   if (nexthop_set)
10479     {
10480       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10481       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10482     }
10483   mp->behavior = behavior;
10484   mp->sw_if_index = ntohl (sw_if_index);
10485   mp->fib_table = ntohl (fib_table);
10486   mp->end_psp = end_psp;
10487   mp->is_del = is_del;
10488
10489   S (mp);
10490   W (ret);
10491   return ret;
10492 }
10493
10494 static int
10495 api_ioam_enable (vat_main_t * vam)
10496 {
10497   unformat_input_t *input = vam->input;
10498   vl_api_ioam_enable_t *mp;
10499   u32 id = 0;
10500   int has_trace_option = 0;
10501   int has_pot_option = 0;
10502   int has_seqno_option = 0;
10503   int has_analyse_option = 0;
10504   int ret;
10505
10506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10507     {
10508       if (unformat (input, "trace"))
10509         has_trace_option = 1;
10510       else if (unformat (input, "pot"))
10511         has_pot_option = 1;
10512       else if (unformat (input, "seqno"))
10513         has_seqno_option = 1;
10514       else if (unformat (input, "analyse"))
10515         has_analyse_option = 1;
10516       else
10517         break;
10518     }
10519   M (IOAM_ENABLE, mp);
10520   mp->id = htons (id);
10521   mp->seqno = has_seqno_option;
10522   mp->analyse = has_analyse_option;
10523   mp->pot_enable = has_pot_option;
10524   mp->trace_enable = has_trace_option;
10525
10526   S (mp);
10527   W (ret);
10528   return ret;
10529 }
10530
10531
10532 static int
10533 api_ioam_disable (vat_main_t * vam)
10534 {
10535   vl_api_ioam_disable_t *mp;
10536   int ret;
10537
10538   M (IOAM_DISABLE, mp);
10539   S (mp);
10540   W (ret);
10541   return ret;
10542 }
10543
10544 #define foreach_tcp_proto_field                 \
10545 _(src_port)                                     \
10546 _(dst_port)
10547
10548 #define foreach_udp_proto_field                 \
10549 _(src_port)                                     \
10550 _(dst_port)
10551
10552 #define foreach_ip4_proto_field                 \
10553 _(src_address)                                  \
10554 _(dst_address)                                  \
10555 _(tos)                                          \
10556 _(length)                                       \
10557 _(fragment_id)                                  \
10558 _(ttl)                                          \
10559 _(protocol)                                     \
10560 _(checksum)
10561
10562 typedef struct
10563 {
10564   u16 src_port, dst_port;
10565 } tcpudp_header_t;
10566
10567 #if VPP_API_TEST_BUILTIN == 0
10568 uword
10569 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10570 {
10571   u8 **maskp = va_arg (*args, u8 **);
10572   u8 *mask = 0;
10573   u8 found_something = 0;
10574   tcp_header_t *tcp;
10575
10576 #define _(a) u8 a=0;
10577   foreach_tcp_proto_field;
10578 #undef _
10579
10580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10581     {
10582       if (0);
10583 #define _(a) else if (unformat (input, #a)) a=1;
10584       foreach_tcp_proto_field
10585 #undef _
10586         else
10587         break;
10588     }
10589
10590 #define _(a) found_something += a;
10591   foreach_tcp_proto_field;
10592 #undef _
10593
10594   if (found_something == 0)
10595     return 0;
10596
10597   vec_validate (mask, sizeof (*tcp) - 1);
10598
10599   tcp = (tcp_header_t *) mask;
10600
10601 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10602   foreach_tcp_proto_field;
10603 #undef _
10604
10605   *maskp = mask;
10606   return 1;
10607 }
10608
10609 uword
10610 unformat_udp_mask (unformat_input_t * input, va_list * args)
10611 {
10612   u8 **maskp = va_arg (*args, u8 **);
10613   u8 *mask = 0;
10614   u8 found_something = 0;
10615   udp_header_t *udp;
10616
10617 #define _(a) u8 a=0;
10618   foreach_udp_proto_field;
10619 #undef _
10620
10621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10622     {
10623       if (0);
10624 #define _(a) else if (unformat (input, #a)) a=1;
10625       foreach_udp_proto_field
10626 #undef _
10627         else
10628         break;
10629     }
10630
10631 #define _(a) found_something += a;
10632   foreach_udp_proto_field;
10633 #undef _
10634
10635   if (found_something == 0)
10636     return 0;
10637
10638   vec_validate (mask, sizeof (*udp) - 1);
10639
10640   udp = (udp_header_t *) mask;
10641
10642 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10643   foreach_udp_proto_field;
10644 #undef _
10645
10646   *maskp = mask;
10647   return 1;
10648 }
10649
10650 uword
10651 unformat_l4_mask (unformat_input_t * input, va_list * args)
10652 {
10653   u8 **maskp = va_arg (*args, u8 **);
10654   u16 src_port = 0, dst_port = 0;
10655   tcpudp_header_t *tcpudp;
10656
10657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10658     {
10659       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10660         return 1;
10661       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10662         return 1;
10663       else if (unformat (input, "src_port"))
10664         src_port = 0xFFFF;
10665       else if (unformat (input, "dst_port"))
10666         dst_port = 0xFFFF;
10667       else
10668         return 0;
10669     }
10670
10671   if (!src_port && !dst_port)
10672     return 0;
10673
10674   u8 *mask = 0;
10675   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10676
10677   tcpudp = (tcpudp_header_t *) mask;
10678   tcpudp->src_port = src_port;
10679   tcpudp->dst_port = dst_port;
10680
10681   *maskp = mask;
10682
10683   return 1;
10684 }
10685
10686 uword
10687 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10688 {
10689   u8 **maskp = va_arg (*args, u8 **);
10690   u8 *mask = 0;
10691   u8 found_something = 0;
10692   ip4_header_t *ip;
10693
10694 #define _(a) u8 a=0;
10695   foreach_ip4_proto_field;
10696 #undef _
10697   u8 version = 0;
10698   u8 hdr_length = 0;
10699
10700
10701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10702     {
10703       if (unformat (input, "version"))
10704         version = 1;
10705       else if (unformat (input, "hdr_length"))
10706         hdr_length = 1;
10707       else if (unformat (input, "src"))
10708         src_address = 1;
10709       else if (unformat (input, "dst"))
10710         dst_address = 1;
10711       else if (unformat (input, "proto"))
10712         protocol = 1;
10713
10714 #define _(a) else if (unformat (input, #a)) a=1;
10715       foreach_ip4_proto_field
10716 #undef _
10717         else
10718         break;
10719     }
10720
10721 #define _(a) found_something += a;
10722   foreach_ip4_proto_field;
10723 #undef _
10724
10725   if (found_something == 0)
10726     return 0;
10727
10728   vec_validate (mask, sizeof (*ip) - 1);
10729
10730   ip = (ip4_header_t *) mask;
10731
10732 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10733   foreach_ip4_proto_field;
10734 #undef _
10735
10736   ip->ip_version_and_header_length = 0;
10737
10738   if (version)
10739     ip->ip_version_and_header_length |= 0xF0;
10740
10741   if (hdr_length)
10742     ip->ip_version_and_header_length |= 0x0F;
10743
10744   *maskp = mask;
10745   return 1;
10746 }
10747
10748 #define foreach_ip6_proto_field                 \
10749 _(src_address)                                  \
10750 _(dst_address)                                  \
10751 _(payload_length)                               \
10752 _(hop_limit)                                    \
10753 _(protocol)
10754
10755 uword
10756 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10757 {
10758   u8 **maskp = va_arg (*args, u8 **);
10759   u8 *mask = 0;
10760   u8 found_something = 0;
10761   ip6_header_t *ip;
10762   u32 ip_version_traffic_class_and_flow_label;
10763
10764 #define _(a) u8 a=0;
10765   foreach_ip6_proto_field;
10766 #undef _
10767   u8 version = 0;
10768   u8 traffic_class = 0;
10769   u8 flow_label = 0;
10770
10771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10772     {
10773       if (unformat (input, "version"))
10774         version = 1;
10775       else if (unformat (input, "traffic-class"))
10776         traffic_class = 1;
10777       else if (unformat (input, "flow-label"))
10778         flow_label = 1;
10779       else if (unformat (input, "src"))
10780         src_address = 1;
10781       else if (unformat (input, "dst"))
10782         dst_address = 1;
10783       else if (unformat (input, "proto"))
10784         protocol = 1;
10785
10786 #define _(a) else if (unformat (input, #a)) a=1;
10787       foreach_ip6_proto_field
10788 #undef _
10789         else
10790         break;
10791     }
10792
10793 #define _(a) found_something += a;
10794   foreach_ip6_proto_field;
10795 #undef _
10796
10797   if (found_something == 0)
10798     return 0;
10799
10800   vec_validate (mask, sizeof (*ip) - 1);
10801
10802   ip = (ip6_header_t *) mask;
10803
10804 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10805   foreach_ip6_proto_field;
10806 #undef _
10807
10808   ip_version_traffic_class_and_flow_label = 0;
10809
10810   if (version)
10811     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10812
10813   if (traffic_class)
10814     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10815
10816   if (flow_label)
10817     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10818
10819   ip->ip_version_traffic_class_and_flow_label =
10820     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10821
10822   *maskp = mask;
10823   return 1;
10824 }
10825
10826 uword
10827 unformat_l3_mask (unformat_input_t * input, va_list * args)
10828 {
10829   u8 **maskp = va_arg (*args, u8 **);
10830
10831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10832     {
10833       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10834         return 1;
10835       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10836         return 1;
10837       else
10838         break;
10839     }
10840   return 0;
10841 }
10842
10843 uword
10844 unformat_l2_mask (unformat_input_t * input, va_list * args)
10845 {
10846   u8 **maskp = va_arg (*args, u8 **);
10847   u8 *mask = 0;
10848   u8 src = 0;
10849   u8 dst = 0;
10850   u8 proto = 0;
10851   u8 tag1 = 0;
10852   u8 tag2 = 0;
10853   u8 ignore_tag1 = 0;
10854   u8 ignore_tag2 = 0;
10855   u8 cos1 = 0;
10856   u8 cos2 = 0;
10857   u8 dot1q = 0;
10858   u8 dot1ad = 0;
10859   int len = 14;
10860
10861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10862     {
10863       if (unformat (input, "src"))
10864         src = 1;
10865       else if (unformat (input, "dst"))
10866         dst = 1;
10867       else if (unformat (input, "proto"))
10868         proto = 1;
10869       else if (unformat (input, "tag1"))
10870         tag1 = 1;
10871       else if (unformat (input, "tag2"))
10872         tag2 = 1;
10873       else if (unformat (input, "ignore-tag1"))
10874         ignore_tag1 = 1;
10875       else if (unformat (input, "ignore-tag2"))
10876         ignore_tag2 = 1;
10877       else if (unformat (input, "cos1"))
10878         cos1 = 1;
10879       else if (unformat (input, "cos2"))
10880         cos2 = 1;
10881       else if (unformat (input, "dot1q"))
10882         dot1q = 1;
10883       else if (unformat (input, "dot1ad"))
10884         dot1ad = 1;
10885       else
10886         break;
10887     }
10888   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10889        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10890     return 0;
10891
10892   if (tag1 || ignore_tag1 || cos1 || dot1q)
10893     len = 18;
10894   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10895     len = 22;
10896
10897   vec_validate (mask, len - 1);
10898
10899   if (dst)
10900     clib_memset (mask, 0xff, 6);
10901
10902   if (src)
10903     clib_memset (mask + 6, 0xff, 6);
10904
10905   if (tag2 || dot1ad)
10906     {
10907       /* inner vlan tag */
10908       if (tag2)
10909         {
10910           mask[19] = 0xff;
10911           mask[18] = 0x0f;
10912         }
10913       if (cos2)
10914         mask[18] |= 0xe0;
10915       if (proto)
10916         mask[21] = mask[20] = 0xff;
10917       if (tag1)
10918         {
10919           mask[15] = 0xff;
10920           mask[14] = 0x0f;
10921         }
10922       if (cos1)
10923         mask[14] |= 0xe0;
10924       *maskp = mask;
10925       return 1;
10926     }
10927   if (tag1 | dot1q)
10928     {
10929       if (tag1)
10930         {
10931           mask[15] = 0xff;
10932           mask[14] = 0x0f;
10933         }
10934       if (cos1)
10935         mask[14] |= 0xe0;
10936       if (proto)
10937         mask[16] = mask[17] = 0xff;
10938
10939       *maskp = mask;
10940       return 1;
10941     }
10942   if (cos2)
10943     mask[18] |= 0xe0;
10944   if (cos1)
10945     mask[14] |= 0xe0;
10946   if (proto)
10947     mask[12] = mask[13] = 0xff;
10948
10949   *maskp = mask;
10950   return 1;
10951 }
10952
10953 uword
10954 unformat_classify_mask (unformat_input_t * input, va_list * args)
10955 {
10956   u8 **maskp = va_arg (*args, u8 **);
10957   u32 *skipp = va_arg (*args, u32 *);
10958   u32 *matchp = va_arg (*args, u32 *);
10959   u32 match;
10960   u8 *mask = 0;
10961   u8 *l2 = 0;
10962   u8 *l3 = 0;
10963   u8 *l4 = 0;
10964   int i;
10965
10966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10967     {
10968       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10969         ;
10970       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10971         ;
10972       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10973         ;
10974       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10975         ;
10976       else
10977         break;
10978     }
10979
10980   if (l4 && !l3)
10981     {
10982       vec_free (mask);
10983       vec_free (l2);
10984       vec_free (l4);
10985       return 0;
10986     }
10987
10988   if (mask || l2 || l3 || l4)
10989     {
10990       if (l2 || l3 || l4)
10991         {
10992           /* "With a free Ethernet header in every package" */
10993           if (l2 == 0)
10994             vec_validate (l2, 13);
10995           mask = l2;
10996           if (vec_len (l3))
10997             {
10998               vec_append (mask, l3);
10999               vec_free (l3);
11000             }
11001           if (vec_len (l4))
11002             {
11003               vec_append (mask, l4);
11004               vec_free (l4);
11005             }
11006         }
11007
11008       /* Scan forward looking for the first significant mask octet */
11009       for (i = 0; i < vec_len (mask); i++)
11010         if (mask[i])
11011           break;
11012
11013       /* compute (skip, match) params */
11014       *skipp = i / sizeof (u32x4);
11015       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11016
11017       /* Pad mask to an even multiple of the vector size */
11018       while (vec_len (mask) % sizeof (u32x4))
11019         vec_add1 (mask, 0);
11020
11021       match = vec_len (mask) / sizeof (u32x4);
11022
11023       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11024         {
11025           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11026           if (*tmp || *(tmp + 1))
11027             break;
11028           match--;
11029         }
11030       if (match == 0)
11031         clib_warning ("BUG: match 0");
11032
11033       _vec_len (mask) = match * sizeof (u32x4);
11034
11035       *matchp = match;
11036       *maskp = mask;
11037
11038       return 1;
11039     }
11040
11041   return 0;
11042 }
11043 #endif /* VPP_API_TEST_BUILTIN */
11044
11045 #define foreach_l2_next                         \
11046 _(drop, DROP)                                   \
11047 _(ethernet, ETHERNET_INPUT)                     \
11048 _(ip4, IP4_INPUT)                               \
11049 _(ip6, IP6_INPUT)
11050
11051 uword
11052 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11053 {
11054   u32 *miss_next_indexp = va_arg (*args, u32 *);
11055   u32 next_index = 0;
11056   u32 tmp;
11057
11058 #define _(n,N) \
11059   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11060   foreach_l2_next;
11061 #undef _
11062
11063   if (unformat (input, "%d", &tmp))
11064     {
11065       next_index = tmp;
11066       goto out;
11067     }
11068
11069   return 0;
11070
11071 out:
11072   *miss_next_indexp = next_index;
11073   return 1;
11074 }
11075
11076 #define foreach_ip_next                         \
11077 _(drop, DROP)                                   \
11078 _(local, LOCAL)                                 \
11079 _(rewrite, REWRITE)
11080
11081 uword
11082 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11083 {
11084   u32 *miss_next_indexp = va_arg (*args, u32 *);
11085   u32 next_index = 0;
11086   u32 tmp;
11087
11088 #define _(n,N) \
11089   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11090   foreach_ip_next;
11091 #undef _
11092
11093   if (unformat (input, "%d", &tmp))
11094     {
11095       next_index = tmp;
11096       goto out;
11097     }
11098
11099   return 0;
11100
11101 out:
11102   *miss_next_indexp = next_index;
11103   return 1;
11104 }
11105
11106 #define foreach_acl_next                        \
11107 _(deny, DENY)
11108
11109 uword
11110 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11111 {
11112   u32 *miss_next_indexp = va_arg (*args, u32 *);
11113   u32 next_index = 0;
11114   u32 tmp;
11115
11116 #define _(n,N) \
11117   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11118   foreach_acl_next;
11119 #undef _
11120
11121   if (unformat (input, "permit"))
11122     {
11123       next_index = ~0;
11124       goto out;
11125     }
11126   else if (unformat (input, "%d", &tmp))
11127     {
11128       next_index = tmp;
11129       goto out;
11130     }
11131
11132   return 0;
11133
11134 out:
11135   *miss_next_indexp = next_index;
11136   return 1;
11137 }
11138
11139 uword
11140 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11141 {
11142   u32 *r = va_arg (*args, u32 *);
11143
11144   if (unformat (input, "conform-color"))
11145     *r = POLICE_CONFORM;
11146   else if (unformat (input, "exceed-color"))
11147     *r = POLICE_EXCEED;
11148   else
11149     return 0;
11150
11151   return 1;
11152 }
11153
11154 static int
11155 api_classify_add_del_table (vat_main_t * vam)
11156 {
11157   unformat_input_t *i = vam->input;
11158   vl_api_classify_add_del_table_t *mp;
11159
11160   u32 nbuckets = 2;
11161   u32 skip = ~0;
11162   u32 match = ~0;
11163   int is_add = 1;
11164   int del_chain = 0;
11165   u32 table_index = ~0;
11166   u32 next_table_index = ~0;
11167   u32 miss_next_index = ~0;
11168   u32 memory_size = 32 << 20;
11169   u8 *mask = 0;
11170   u32 current_data_flag = 0;
11171   int current_data_offset = 0;
11172   int ret;
11173
11174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11175     {
11176       if (unformat (i, "del"))
11177         is_add = 0;
11178       else if (unformat (i, "del-chain"))
11179         {
11180           is_add = 0;
11181           del_chain = 1;
11182         }
11183       else if (unformat (i, "buckets %d", &nbuckets))
11184         ;
11185       else if (unformat (i, "memory_size %d", &memory_size))
11186         ;
11187       else if (unformat (i, "skip %d", &skip))
11188         ;
11189       else if (unformat (i, "match %d", &match))
11190         ;
11191       else if (unformat (i, "table %d", &table_index))
11192         ;
11193       else if (unformat (i, "mask %U", unformat_classify_mask,
11194                          &mask, &skip, &match))
11195         ;
11196       else if (unformat (i, "next-table %d", &next_table_index))
11197         ;
11198       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11199                          &miss_next_index))
11200         ;
11201       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11202                          &miss_next_index))
11203         ;
11204       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11205                          &miss_next_index))
11206         ;
11207       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11208         ;
11209       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11210         ;
11211       else
11212         break;
11213     }
11214
11215   if (is_add && mask == 0)
11216     {
11217       errmsg ("Mask required");
11218       return -99;
11219     }
11220
11221   if (is_add && skip == ~0)
11222     {
11223       errmsg ("skip count required");
11224       return -99;
11225     }
11226
11227   if (is_add && match == ~0)
11228     {
11229       errmsg ("match count required");
11230       return -99;
11231     }
11232
11233   if (!is_add && table_index == ~0)
11234     {
11235       errmsg ("table index required for delete");
11236       return -99;
11237     }
11238
11239   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11240
11241   mp->is_add = is_add;
11242   mp->del_chain = del_chain;
11243   mp->table_index = ntohl (table_index);
11244   mp->nbuckets = ntohl (nbuckets);
11245   mp->memory_size = ntohl (memory_size);
11246   mp->skip_n_vectors = ntohl (skip);
11247   mp->match_n_vectors = ntohl (match);
11248   mp->next_table_index = ntohl (next_table_index);
11249   mp->miss_next_index = ntohl (miss_next_index);
11250   mp->current_data_flag = ntohl (current_data_flag);
11251   mp->current_data_offset = ntohl (current_data_offset);
11252   mp->mask_len = ntohl (vec_len (mask));
11253   clib_memcpy (mp->mask, mask, vec_len (mask));
11254
11255   vec_free (mask);
11256
11257   S (mp);
11258   W (ret);
11259   return ret;
11260 }
11261
11262 #if VPP_API_TEST_BUILTIN == 0
11263 uword
11264 unformat_l4_match (unformat_input_t * input, va_list * args)
11265 {
11266   u8 **matchp = va_arg (*args, u8 **);
11267
11268   u8 *proto_header = 0;
11269   int src_port = 0;
11270   int dst_port = 0;
11271
11272   tcpudp_header_t h;
11273
11274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11275     {
11276       if (unformat (input, "src_port %d", &src_port))
11277         ;
11278       else if (unformat (input, "dst_port %d", &dst_port))
11279         ;
11280       else
11281         return 0;
11282     }
11283
11284   h.src_port = clib_host_to_net_u16 (src_port);
11285   h.dst_port = clib_host_to_net_u16 (dst_port);
11286   vec_validate (proto_header, sizeof (h) - 1);
11287   memcpy (proto_header, &h, sizeof (h));
11288
11289   *matchp = proto_header;
11290
11291   return 1;
11292 }
11293
11294 uword
11295 unformat_ip4_match (unformat_input_t * input, va_list * args)
11296 {
11297   u8 **matchp = va_arg (*args, u8 **);
11298   u8 *match = 0;
11299   ip4_header_t *ip;
11300   int version = 0;
11301   u32 version_val;
11302   int hdr_length = 0;
11303   u32 hdr_length_val;
11304   int src = 0, dst = 0;
11305   ip4_address_t src_val, dst_val;
11306   int proto = 0;
11307   u32 proto_val;
11308   int tos = 0;
11309   u32 tos_val;
11310   int length = 0;
11311   u32 length_val;
11312   int fragment_id = 0;
11313   u32 fragment_id_val;
11314   int ttl = 0;
11315   int ttl_val;
11316   int checksum = 0;
11317   u32 checksum_val;
11318
11319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (input, "version %d", &version_val))
11322         version = 1;
11323       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11324         hdr_length = 1;
11325       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11326         src = 1;
11327       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11328         dst = 1;
11329       else if (unformat (input, "proto %d", &proto_val))
11330         proto = 1;
11331       else if (unformat (input, "tos %d", &tos_val))
11332         tos = 1;
11333       else if (unformat (input, "length %d", &length_val))
11334         length = 1;
11335       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11336         fragment_id = 1;
11337       else if (unformat (input, "ttl %d", &ttl_val))
11338         ttl = 1;
11339       else if (unformat (input, "checksum %d", &checksum_val))
11340         checksum = 1;
11341       else
11342         break;
11343     }
11344
11345   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11346       + ttl + checksum == 0)
11347     return 0;
11348
11349   /*
11350    * Aligned because we use the real comparison functions
11351    */
11352   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11353
11354   ip = (ip4_header_t *) match;
11355
11356   /* These are realistically matched in practice */
11357   if (src)
11358     ip->src_address.as_u32 = src_val.as_u32;
11359
11360   if (dst)
11361     ip->dst_address.as_u32 = dst_val.as_u32;
11362
11363   if (proto)
11364     ip->protocol = proto_val;
11365
11366
11367   /* These are not, but they're included for completeness */
11368   if (version)
11369     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11370
11371   if (hdr_length)
11372     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11373
11374   if (tos)
11375     ip->tos = tos_val;
11376
11377   if (length)
11378     ip->length = clib_host_to_net_u16 (length_val);
11379
11380   if (ttl)
11381     ip->ttl = ttl_val;
11382
11383   if (checksum)
11384     ip->checksum = clib_host_to_net_u16 (checksum_val);
11385
11386   *matchp = match;
11387   return 1;
11388 }
11389
11390 uword
11391 unformat_ip6_match (unformat_input_t * input, va_list * args)
11392 {
11393   u8 **matchp = va_arg (*args, u8 **);
11394   u8 *match = 0;
11395   ip6_header_t *ip;
11396   int version = 0;
11397   u32 version_val;
11398   u8 traffic_class = 0;
11399   u32 traffic_class_val = 0;
11400   u8 flow_label = 0;
11401   u8 flow_label_val;
11402   int src = 0, dst = 0;
11403   ip6_address_t src_val, dst_val;
11404   int proto = 0;
11405   u32 proto_val;
11406   int payload_length = 0;
11407   u32 payload_length_val;
11408   int hop_limit = 0;
11409   int hop_limit_val;
11410   u32 ip_version_traffic_class_and_flow_label;
11411
11412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11413     {
11414       if (unformat (input, "version %d", &version_val))
11415         version = 1;
11416       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11417         traffic_class = 1;
11418       else if (unformat (input, "flow_label %d", &flow_label_val))
11419         flow_label = 1;
11420       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11421         src = 1;
11422       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11423         dst = 1;
11424       else if (unformat (input, "proto %d", &proto_val))
11425         proto = 1;
11426       else if (unformat (input, "payload_length %d", &payload_length_val))
11427         payload_length = 1;
11428       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11429         hop_limit = 1;
11430       else
11431         break;
11432     }
11433
11434   if (version + traffic_class + flow_label + src + dst + proto +
11435       payload_length + hop_limit == 0)
11436     return 0;
11437
11438   /*
11439    * Aligned because we use the real comparison functions
11440    */
11441   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11442
11443   ip = (ip6_header_t *) match;
11444
11445   if (src)
11446     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11447
11448   if (dst)
11449     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11450
11451   if (proto)
11452     ip->protocol = proto_val;
11453
11454   ip_version_traffic_class_and_flow_label = 0;
11455
11456   if (version)
11457     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11458
11459   if (traffic_class)
11460     ip_version_traffic_class_and_flow_label |=
11461       (traffic_class_val & 0xFF) << 20;
11462
11463   if (flow_label)
11464     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11465
11466   ip->ip_version_traffic_class_and_flow_label =
11467     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11468
11469   if (payload_length)
11470     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11471
11472   if (hop_limit)
11473     ip->hop_limit = hop_limit_val;
11474
11475   *matchp = match;
11476   return 1;
11477 }
11478
11479 uword
11480 unformat_l3_match (unformat_input_t * input, va_list * args)
11481 {
11482   u8 **matchp = va_arg (*args, u8 **);
11483
11484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11485     {
11486       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11487         return 1;
11488       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11489         return 1;
11490       else
11491         break;
11492     }
11493   return 0;
11494 }
11495
11496 uword
11497 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11498 {
11499   u8 *tagp = va_arg (*args, u8 *);
11500   u32 tag;
11501
11502   if (unformat (input, "%d", &tag))
11503     {
11504       tagp[0] = (tag >> 8) & 0x0F;
11505       tagp[1] = tag & 0xFF;
11506       return 1;
11507     }
11508
11509   return 0;
11510 }
11511
11512 uword
11513 unformat_l2_match (unformat_input_t * input, va_list * args)
11514 {
11515   u8 **matchp = va_arg (*args, u8 **);
11516   u8 *match = 0;
11517   u8 src = 0;
11518   u8 src_val[6];
11519   u8 dst = 0;
11520   u8 dst_val[6];
11521   u8 proto = 0;
11522   u16 proto_val;
11523   u8 tag1 = 0;
11524   u8 tag1_val[2];
11525   u8 tag2 = 0;
11526   u8 tag2_val[2];
11527   int len = 14;
11528   u8 ignore_tag1 = 0;
11529   u8 ignore_tag2 = 0;
11530   u8 cos1 = 0;
11531   u8 cos2 = 0;
11532   u32 cos1_val = 0;
11533   u32 cos2_val = 0;
11534
11535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11536     {
11537       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11538         src = 1;
11539       else
11540         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11541         dst = 1;
11542       else if (unformat (input, "proto %U",
11543                          unformat_ethernet_type_host_byte_order, &proto_val))
11544         proto = 1;
11545       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11546         tag1 = 1;
11547       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11548         tag2 = 1;
11549       else if (unformat (input, "ignore-tag1"))
11550         ignore_tag1 = 1;
11551       else if (unformat (input, "ignore-tag2"))
11552         ignore_tag2 = 1;
11553       else if (unformat (input, "cos1 %d", &cos1_val))
11554         cos1 = 1;
11555       else if (unformat (input, "cos2 %d", &cos2_val))
11556         cos2 = 1;
11557       else
11558         break;
11559     }
11560   if ((src + dst + proto + tag1 + tag2 +
11561        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11562     return 0;
11563
11564   if (tag1 || ignore_tag1 || cos1)
11565     len = 18;
11566   if (tag2 || ignore_tag2 || cos2)
11567     len = 22;
11568
11569   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11570
11571   if (dst)
11572     clib_memcpy (match, dst_val, 6);
11573
11574   if (src)
11575     clib_memcpy (match + 6, src_val, 6);
11576
11577   if (tag2)
11578     {
11579       /* inner vlan tag */
11580       match[19] = tag2_val[1];
11581       match[18] = tag2_val[0];
11582       if (cos2)
11583         match[18] |= (cos2_val & 0x7) << 5;
11584       if (proto)
11585         {
11586           match[21] = proto_val & 0xff;
11587           match[20] = proto_val >> 8;
11588         }
11589       if (tag1)
11590         {
11591           match[15] = tag1_val[1];
11592           match[14] = tag1_val[0];
11593         }
11594       if (cos1)
11595         match[14] |= (cos1_val & 0x7) << 5;
11596       *matchp = match;
11597       return 1;
11598     }
11599   if (tag1)
11600     {
11601       match[15] = tag1_val[1];
11602       match[14] = tag1_val[0];
11603       if (proto)
11604         {
11605           match[17] = proto_val & 0xff;
11606           match[16] = proto_val >> 8;
11607         }
11608       if (cos1)
11609         match[14] |= (cos1_val & 0x7) << 5;
11610
11611       *matchp = match;
11612       return 1;
11613     }
11614   if (cos2)
11615     match[18] |= (cos2_val & 0x7) << 5;
11616   if (cos1)
11617     match[14] |= (cos1_val & 0x7) << 5;
11618   if (proto)
11619     {
11620       match[13] = proto_val & 0xff;
11621       match[12] = proto_val >> 8;
11622     }
11623
11624   *matchp = match;
11625   return 1;
11626 }
11627
11628 uword
11629 unformat_qos_source (unformat_input_t * input, va_list * args)
11630 {
11631   int *qs = va_arg (*args, int *);
11632
11633   if (unformat (input, "ip"))
11634     *qs = QOS_SOURCE_IP;
11635   else if (unformat (input, "mpls"))
11636     *qs = QOS_SOURCE_MPLS;
11637   else if (unformat (input, "ext"))
11638     *qs = QOS_SOURCE_EXT;
11639   else if (unformat (input, "vlan"))
11640     *qs = QOS_SOURCE_VLAN;
11641   else
11642     return 0;
11643
11644   return 1;
11645 }
11646 #endif
11647
11648 uword
11649 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11650 {
11651   u8 **matchp = va_arg (*args, u8 **);
11652   u32 skip_n_vectors = va_arg (*args, u32);
11653   u32 match_n_vectors = va_arg (*args, u32);
11654
11655   u8 *match = 0;
11656   u8 *l2 = 0;
11657   u8 *l3 = 0;
11658   u8 *l4 = 0;
11659
11660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11661     {
11662       if (unformat (input, "hex %U", unformat_hex_string, &match))
11663         ;
11664       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11665         ;
11666       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11667         ;
11668       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11669         ;
11670       else
11671         break;
11672     }
11673
11674   if (l4 && !l3)
11675     {
11676       vec_free (match);
11677       vec_free (l2);
11678       vec_free (l4);
11679       return 0;
11680     }
11681
11682   if (match || l2 || l3 || l4)
11683     {
11684       if (l2 || l3 || l4)
11685         {
11686           /* "Win a free Ethernet header in every packet" */
11687           if (l2 == 0)
11688             vec_validate_aligned (l2, 13, sizeof (u32x4));
11689           match = l2;
11690           if (vec_len (l3))
11691             {
11692               vec_append_aligned (match, l3, sizeof (u32x4));
11693               vec_free (l3);
11694             }
11695           if (vec_len (l4))
11696             {
11697               vec_append_aligned (match, l4, sizeof (u32x4));
11698               vec_free (l4);
11699             }
11700         }
11701
11702       /* Make sure the vector is big enough even if key is all 0's */
11703       vec_validate_aligned
11704         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11705          sizeof (u32x4));
11706
11707       /* Set size, include skipped vectors */
11708       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11709
11710       *matchp = match;
11711
11712       return 1;
11713     }
11714
11715   return 0;
11716 }
11717
11718 static int
11719 api_classify_add_del_session (vat_main_t * vam)
11720 {
11721   unformat_input_t *i = vam->input;
11722   vl_api_classify_add_del_session_t *mp;
11723   int is_add = 1;
11724   u32 table_index = ~0;
11725   u32 hit_next_index = ~0;
11726   u32 opaque_index = ~0;
11727   u8 *match = 0;
11728   i32 advance = 0;
11729   u32 skip_n_vectors = 0;
11730   u32 match_n_vectors = 0;
11731   u32 action = 0;
11732   u32 metadata = 0;
11733   int ret;
11734
11735   /*
11736    * Warning: you have to supply skip_n and match_n
11737    * because the API client cant simply look at the classify
11738    * table object.
11739    */
11740
11741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11742     {
11743       if (unformat (i, "del"))
11744         is_add = 0;
11745       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11746                          &hit_next_index))
11747         ;
11748       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11749                          &hit_next_index))
11750         ;
11751       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11752                          &hit_next_index))
11753         ;
11754       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11755         ;
11756       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11757         ;
11758       else if (unformat (i, "opaque-index %d", &opaque_index))
11759         ;
11760       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11761         ;
11762       else if (unformat (i, "match_n %d", &match_n_vectors))
11763         ;
11764       else if (unformat (i, "match %U", api_unformat_classify_match,
11765                          &match, skip_n_vectors, match_n_vectors))
11766         ;
11767       else if (unformat (i, "advance %d", &advance))
11768         ;
11769       else if (unformat (i, "table-index %d", &table_index))
11770         ;
11771       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11772         action = 1;
11773       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11774         action = 2;
11775       else if (unformat (i, "action %d", &action))
11776         ;
11777       else if (unformat (i, "metadata %d", &metadata))
11778         ;
11779       else
11780         break;
11781     }
11782
11783   if (table_index == ~0)
11784     {
11785       errmsg ("Table index required");
11786       return -99;
11787     }
11788
11789   if (is_add && match == 0)
11790     {
11791       errmsg ("Match value required");
11792       return -99;
11793     }
11794
11795   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11796
11797   mp->is_add = is_add;
11798   mp->table_index = ntohl (table_index);
11799   mp->hit_next_index = ntohl (hit_next_index);
11800   mp->opaque_index = ntohl (opaque_index);
11801   mp->advance = ntohl (advance);
11802   mp->action = action;
11803   mp->metadata = ntohl (metadata);
11804   mp->match_len = ntohl (vec_len (match));
11805   clib_memcpy (mp->match, match, vec_len (match));
11806   vec_free (match);
11807
11808   S (mp);
11809   W (ret);
11810   return ret;
11811 }
11812
11813 static int
11814 api_classify_set_interface_ip_table (vat_main_t * vam)
11815 {
11816   unformat_input_t *i = vam->input;
11817   vl_api_classify_set_interface_ip_table_t *mp;
11818   u32 sw_if_index;
11819   int sw_if_index_set;
11820   u32 table_index = ~0;
11821   u8 is_ipv6 = 0;
11822   int ret;
11823
11824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11825     {
11826       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11827         sw_if_index_set = 1;
11828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11829         sw_if_index_set = 1;
11830       else if (unformat (i, "table %d", &table_index))
11831         ;
11832       else
11833         {
11834           clib_warning ("parse error '%U'", format_unformat_error, i);
11835           return -99;
11836         }
11837     }
11838
11839   if (sw_if_index_set == 0)
11840     {
11841       errmsg ("missing interface name or sw_if_index");
11842       return -99;
11843     }
11844
11845
11846   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11847
11848   mp->sw_if_index = ntohl (sw_if_index);
11849   mp->table_index = ntohl (table_index);
11850   mp->is_ipv6 = is_ipv6;
11851
11852   S (mp);
11853   W (ret);
11854   return ret;
11855 }
11856
11857 static int
11858 api_classify_set_interface_l2_tables (vat_main_t * vam)
11859 {
11860   unformat_input_t *i = vam->input;
11861   vl_api_classify_set_interface_l2_tables_t *mp;
11862   u32 sw_if_index;
11863   int sw_if_index_set;
11864   u32 ip4_table_index = ~0;
11865   u32 ip6_table_index = ~0;
11866   u32 other_table_index = ~0;
11867   u32 is_input = 1;
11868   int ret;
11869
11870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11871     {
11872       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11873         sw_if_index_set = 1;
11874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11875         sw_if_index_set = 1;
11876       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11877         ;
11878       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11879         ;
11880       else if (unformat (i, "other-table %d", &other_table_index))
11881         ;
11882       else if (unformat (i, "is-input %d", &is_input))
11883         ;
11884       else
11885         {
11886           clib_warning ("parse error '%U'", format_unformat_error, i);
11887           return -99;
11888         }
11889     }
11890
11891   if (sw_if_index_set == 0)
11892     {
11893       errmsg ("missing interface name or sw_if_index");
11894       return -99;
11895     }
11896
11897
11898   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11899
11900   mp->sw_if_index = ntohl (sw_if_index);
11901   mp->ip4_table_index = ntohl (ip4_table_index);
11902   mp->ip6_table_index = ntohl (ip6_table_index);
11903   mp->other_table_index = ntohl (other_table_index);
11904   mp->is_input = (u8) is_input;
11905
11906   S (mp);
11907   W (ret);
11908   return ret;
11909 }
11910
11911 static int
11912 api_set_ipfix_exporter (vat_main_t * vam)
11913 {
11914   unformat_input_t *i = vam->input;
11915   vl_api_set_ipfix_exporter_t *mp;
11916   ip4_address_t collector_address;
11917   u8 collector_address_set = 0;
11918   u32 collector_port = ~0;
11919   ip4_address_t src_address;
11920   u8 src_address_set = 0;
11921   u32 vrf_id = ~0;
11922   u32 path_mtu = ~0;
11923   u32 template_interval = ~0;
11924   u8 udp_checksum = 0;
11925   int ret;
11926
11927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11928     {
11929       if (unformat (i, "collector_address %U", unformat_ip4_address,
11930                     &collector_address))
11931         collector_address_set = 1;
11932       else if (unformat (i, "collector_port %d", &collector_port))
11933         ;
11934       else if (unformat (i, "src_address %U", unformat_ip4_address,
11935                          &src_address))
11936         src_address_set = 1;
11937       else if (unformat (i, "vrf_id %d", &vrf_id))
11938         ;
11939       else if (unformat (i, "path_mtu %d", &path_mtu))
11940         ;
11941       else if (unformat (i, "template_interval %d", &template_interval))
11942         ;
11943       else if (unformat (i, "udp_checksum"))
11944         udp_checksum = 1;
11945       else
11946         break;
11947     }
11948
11949   if (collector_address_set == 0)
11950     {
11951       errmsg ("collector_address required");
11952       return -99;
11953     }
11954
11955   if (src_address_set == 0)
11956     {
11957       errmsg ("src_address required");
11958       return -99;
11959     }
11960
11961   M (SET_IPFIX_EXPORTER, mp);
11962
11963   memcpy (mp->collector_address, collector_address.data,
11964           sizeof (collector_address.data));
11965   mp->collector_port = htons ((u16) collector_port);
11966   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11967   mp->vrf_id = htonl (vrf_id);
11968   mp->path_mtu = htonl (path_mtu);
11969   mp->template_interval = htonl (template_interval);
11970   mp->udp_checksum = udp_checksum;
11971
11972   S (mp);
11973   W (ret);
11974   return ret;
11975 }
11976
11977 static int
11978 api_set_ipfix_classify_stream (vat_main_t * vam)
11979 {
11980   unformat_input_t *i = vam->input;
11981   vl_api_set_ipfix_classify_stream_t *mp;
11982   u32 domain_id = 0;
11983   u32 src_port = UDP_DST_PORT_ipfix;
11984   int ret;
11985
11986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11987     {
11988       if (unformat (i, "domain %d", &domain_id))
11989         ;
11990       else if (unformat (i, "src_port %d", &src_port))
11991         ;
11992       else
11993         {
11994           errmsg ("unknown input `%U'", format_unformat_error, i);
11995           return -99;
11996         }
11997     }
11998
11999   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12000
12001   mp->domain_id = htonl (domain_id);
12002   mp->src_port = htons ((u16) src_port);
12003
12004   S (mp);
12005   W (ret);
12006   return ret;
12007 }
12008
12009 static int
12010 api_ipfix_classify_table_add_del (vat_main_t * vam)
12011 {
12012   unformat_input_t *i = vam->input;
12013   vl_api_ipfix_classify_table_add_del_t *mp;
12014   int is_add = -1;
12015   u32 classify_table_index = ~0;
12016   u8 ip_version = 0;
12017   u8 transport_protocol = 255;
12018   int ret;
12019
12020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12021     {
12022       if (unformat (i, "add"))
12023         is_add = 1;
12024       else if (unformat (i, "del"))
12025         is_add = 0;
12026       else if (unformat (i, "table %d", &classify_table_index))
12027         ;
12028       else if (unformat (i, "ip4"))
12029         ip_version = 4;
12030       else if (unformat (i, "ip6"))
12031         ip_version = 6;
12032       else if (unformat (i, "tcp"))
12033         transport_protocol = 6;
12034       else if (unformat (i, "udp"))
12035         transport_protocol = 17;
12036       else
12037         {
12038           errmsg ("unknown input `%U'", format_unformat_error, i);
12039           return -99;
12040         }
12041     }
12042
12043   if (is_add == -1)
12044     {
12045       errmsg ("expecting: add|del");
12046       return -99;
12047     }
12048   if (classify_table_index == ~0)
12049     {
12050       errmsg ("classifier table not specified");
12051       return -99;
12052     }
12053   if (ip_version == 0)
12054     {
12055       errmsg ("IP version not specified");
12056       return -99;
12057     }
12058
12059   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12060
12061   mp->is_add = is_add;
12062   mp->table_id = htonl (classify_table_index);
12063   mp->ip_version = ip_version;
12064   mp->transport_protocol = transport_protocol;
12065
12066   S (mp);
12067   W (ret);
12068   return ret;
12069 }
12070
12071 static int
12072 api_get_node_index (vat_main_t * vam)
12073 {
12074   unformat_input_t *i = vam->input;
12075   vl_api_get_node_index_t *mp;
12076   u8 *name = 0;
12077   int ret;
12078
12079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12080     {
12081       if (unformat (i, "node %s", &name))
12082         ;
12083       else
12084         break;
12085     }
12086   if (name == 0)
12087     {
12088       errmsg ("node name required");
12089       return -99;
12090     }
12091   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12092     {
12093       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12094       return -99;
12095     }
12096
12097   M (GET_NODE_INDEX, mp);
12098   clib_memcpy (mp->node_name, name, vec_len (name));
12099   vec_free (name);
12100
12101   S (mp);
12102   W (ret);
12103   return ret;
12104 }
12105
12106 static int
12107 api_get_next_index (vat_main_t * vam)
12108 {
12109   unformat_input_t *i = vam->input;
12110   vl_api_get_next_index_t *mp;
12111   u8 *node_name = 0, *next_node_name = 0;
12112   int ret;
12113
12114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12115     {
12116       if (unformat (i, "node-name %s", &node_name))
12117         ;
12118       else if (unformat (i, "next-node-name %s", &next_node_name))
12119         break;
12120     }
12121
12122   if (node_name == 0)
12123     {
12124       errmsg ("node name required");
12125       return -99;
12126     }
12127   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12128     {
12129       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12130       return -99;
12131     }
12132
12133   if (next_node_name == 0)
12134     {
12135       errmsg ("next node name required");
12136       return -99;
12137     }
12138   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12139     {
12140       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12141       return -99;
12142     }
12143
12144   M (GET_NEXT_INDEX, mp);
12145   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12146   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12147   vec_free (node_name);
12148   vec_free (next_node_name);
12149
12150   S (mp);
12151   W (ret);
12152   return ret;
12153 }
12154
12155 static int
12156 api_add_node_next (vat_main_t * vam)
12157 {
12158   unformat_input_t *i = vam->input;
12159   vl_api_add_node_next_t *mp;
12160   u8 *name = 0;
12161   u8 *next = 0;
12162   int ret;
12163
12164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12165     {
12166       if (unformat (i, "node %s", &name))
12167         ;
12168       else if (unformat (i, "next %s", &next))
12169         ;
12170       else
12171         break;
12172     }
12173   if (name == 0)
12174     {
12175       errmsg ("node name required");
12176       return -99;
12177     }
12178   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12179     {
12180       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12181       return -99;
12182     }
12183   if (next == 0)
12184     {
12185       errmsg ("next node required");
12186       return -99;
12187     }
12188   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12189     {
12190       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12191       return -99;
12192     }
12193
12194   M (ADD_NODE_NEXT, mp);
12195   clib_memcpy (mp->node_name, name, vec_len (name));
12196   clib_memcpy (mp->next_name, next, vec_len (next));
12197   vec_free (name);
12198   vec_free (next);
12199
12200   S (mp);
12201   W (ret);
12202   return ret;
12203 }
12204
12205 static int
12206 api_l2tpv3_create_tunnel (vat_main_t * vam)
12207 {
12208   unformat_input_t *i = vam->input;
12209   ip6_address_t client_address, our_address;
12210   int client_address_set = 0;
12211   int our_address_set = 0;
12212   u32 local_session_id = 0;
12213   u32 remote_session_id = 0;
12214   u64 local_cookie = 0;
12215   u64 remote_cookie = 0;
12216   u8 l2_sublayer_present = 0;
12217   vl_api_l2tpv3_create_tunnel_t *mp;
12218   int ret;
12219
12220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12221     {
12222       if (unformat (i, "client_address %U", unformat_ip6_address,
12223                     &client_address))
12224         client_address_set = 1;
12225       else if (unformat (i, "our_address %U", unformat_ip6_address,
12226                          &our_address))
12227         our_address_set = 1;
12228       else if (unformat (i, "local_session_id %d", &local_session_id))
12229         ;
12230       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12231         ;
12232       else if (unformat (i, "local_cookie %lld", &local_cookie))
12233         ;
12234       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12235         ;
12236       else if (unformat (i, "l2-sublayer-present"))
12237         l2_sublayer_present = 1;
12238       else
12239         break;
12240     }
12241
12242   if (client_address_set == 0)
12243     {
12244       errmsg ("client_address required");
12245       return -99;
12246     }
12247
12248   if (our_address_set == 0)
12249     {
12250       errmsg ("our_address required");
12251       return -99;
12252     }
12253
12254   M (L2TPV3_CREATE_TUNNEL, mp);
12255
12256   clib_memcpy (mp->client_address, client_address.as_u8,
12257                sizeof (mp->client_address));
12258
12259   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12260
12261   mp->local_session_id = ntohl (local_session_id);
12262   mp->remote_session_id = ntohl (remote_session_id);
12263   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12264   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12265   mp->l2_sublayer_present = l2_sublayer_present;
12266   mp->is_ipv6 = 1;
12267
12268   S (mp);
12269   W (ret);
12270   return ret;
12271 }
12272
12273 static int
12274 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12275 {
12276   unformat_input_t *i = vam->input;
12277   u32 sw_if_index;
12278   u8 sw_if_index_set = 0;
12279   u64 new_local_cookie = 0;
12280   u64 new_remote_cookie = 0;
12281   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12282   int ret;
12283
12284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12285     {
12286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12287         sw_if_index_set = 1;
12288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12289         sw_if_index_set = 1;
12290       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12291         ;
12292       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12293         ;
12294       else
12295         break;
12296     }
12297
12298   if (sw_if_index_set == 0)
12299     {
12300       errmsg ("missing interface name or sw_if_index");
12301       return -99;
12302     }
12303
12304   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12305
12306   mp->sw_if_index = ntohl (sw_if_index);
12307   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12308   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12309
12310   S (mp);
12311   W (ret);
12312   return ret;
12313 }
12314
12315 static int
12316 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12317 {
12318   unformat_input_t *i = vam->input;
12319   vl_api_l2tpv3_interface_enable_disable_t *mp;
12320   u32 sw_if_index;
12321   u8 sw_if_index_set = 0;
12322   u8 enable_disable = 1;
12323   int ret;
12324
12325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12326     {
12327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12328         sw_if_index_set = 1;
12329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12330         sw_if_index_set = 1;
12331       else if (unformat (i, "enable"))
12332         enable_disable = 1;
12333       else if (unformat (i, "disable"))
12334         enable_disable = 0;
12335       else
12336         break;
12337     }
12338
12339   if (sw_if_index_set == 0)
12340     {
12341       errmsg ("missing interface name or sw_if_index");
12342       return -99;
12343     }
12344
12345   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12346
12347   mp->sw_if_index = ntohl (sw_if_index);
12348   mp->enable_disable = enable_disable;
12349
12350   S (mp);
12351   W (ret);
12352   return ret;
12353 }
12354
12355 static int
12356 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12357 {
12358   unformat_input_t *i = vam->input;
12359   vl_api_l2tpv3_set_lookup_key_t *mp;
12360   u8 key = ~0;
12361   int ret;
12362
12363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12364     {
12365       if (unformat (i, "lookup_v6_src"))
12366         key = L2T_LOOKUP_SRC_ADDRESS;
12367       else if (unformat (i, "lookup_v6_dst"))
12368         key = L2T_LOOKUP_DST_ADDRESS;
12369       else if (unformat (i, "lookup_session_id"))
12370         key = L2T_LOOKUP_SESSION_ID;
12371       else
12372         break;
12373     }
12374
12375   if (key == (u8) ~ 0)
12376     {
12377       errmsg ("l2tp session lookup key unset");
12378       return -99;
12379     }
12380
12381   M (L2TPV3_SET_LOOKUP_KEY, mp);
12382
12383   mp->key = key;
12384
12385   S (mp);
12386   W (ret);
12387   return ret;
12388 }
12389
12390 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12391   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12392 {
12393   vat_main_t *vam = &vat_main;
12394
12395   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12396          format_ip6_address, mp->our_address,
12397          format_ip6_address, mp->client_address,
12398          clib_net_to_host_u32 (mp->sw_if_index));
12399
12400   print (vam->ofp,
12401          "   local cookies %016llx %016llx remote cookie %016llx",
12402          clib_net_to_host_u64 (mp->local_cookie[0]),
12403          clib_net_to_host_u64 (mp->local_cookie[1]),
12404          clib_net_to_host_u64 (mp->remote_cookie));
12405
12406   print (vam->ofp, "   local session-id %d remote session-id %d",
12407          clib_net_to_host_u32 (mp->local_session_id),
12408          clib_net_to_host_u32 (mp->remote_session_id));
12409
12410   print (vam->ofp, "   l2 specific sublayer %s\n",
12411          mp->l2_sublayer_present ? "preset" : "absent");
12412
12413 }
12414
12415 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12416   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12417 {
12418   vat_main_t *vam = &vat_main;
12419   vat_json_node_t *node = NULL;
12420   struct in6_addr addr;
12421
12422   if (VAT_JSON_ARRAY != vam->json_tree.type)
12423     {
12424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12425       vat_json_init_array (&vam->json_tree);
12426     }
12427   node = vat_json_array_add (&vam->json_tree);
12428
12429   vat_json_init_object (node);
12430
12431   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12432   vat_json_object_add_ip6 (node, "our_address", addr);
12433   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12434   vat_json_object_add_ip6 (node, "client_address", addr);
12435
12436   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12437   vat_json_init_array (lc);
12438   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12439   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12440   vat_json_object_add_uint (node, "remote_cookie",
12441                             clib_net_to_host_u64 (mp->remote_cookie));
12442
12443   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12444   vat_json_object_add_uint (node, "local_session_id",
12445                             clib_net_to_host_u32 (mp->local_session_id));
12446   vat_json_object_add_uint (node, "remote_session_id",
12447                             clib_net_to_host_u32 (mp->remote_session_id));
12448   vat_json_object_add_string_copy (node, "l2_sublayer",
12449                                    mp->l2_sublayer_present ? (u8 *) "present"
12450                                    : (u8 *) "absent");
12451 }
12452
12453 static int
12454 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12455 {
12456   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12457   vl_api_control_ping_t *mp_ping;
12458   int ret;
12459
12460   /* Get list of l2tpv3-tunnel interfaces */
12461   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12462   S (mp);
12463
12464   /* Use a control ping for synchronization */
12465   MPING (CONTROL_PING, mp_ping);
12466   S (mp_ping);
12467
12468   W (ret);
12469   return ret;
12470 }
12471
12472
12473 static void vl_api_sw_interface_tap_v2_details_t_handler
12474   (vl_api_sw_interface_tap_v2_details_t * mp)
12475 {
12476   vat_main_t *vam = &vat_main;
12477
12478   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12479                     mp->host_ip4_prefix_len);
12480   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12481                     mp->host_ip6_prefix_len);
12482
12483   print (vam->ofp,
12484          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12485          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12486          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12487          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12488          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12489
12490   vec_free (ip4);
12491   vec_free (ip6);
12492 }
12493
12494 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12495   (vl_api_sw_interface_tap_v2_details_t * mp)
12496 {
12497   vat_main_t *vam = &vat_main;
12498   vat_json_node_t *node = NULL;
12499
12500   if (VAT_JSON_ARRAY != vam->json_tree.type)
12501     {
12502       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12503       vat_json_init_array (&vam->json_tree);
12504     }
12505   node = vat_json_array_add (&vam->json_tree);
12506
12507   vat_json_init_object (node);
12508   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12509   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12510   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12511   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12512   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12513   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12514   vat_json_object_add_string_copy (node, "host_mac_addr",
12515                                    format (0, "%U", format_ethernet_address,
12516                                            &mp->host_mac_addr));
12517   vat_json_object_add_string_copy (node, "host_namespace",
12518                                    mp->host_namespace);
12519   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12520   vat_json_object_add_string_copy (node, "host_ip4_addr",
12521                                    format (0, "%U/%d", format_ip4_address,
12522                                            mp->host_ip4_addr,
12523                                            mp->host_ip4_prefix_len));
12524   vat_json_object_add_string_copy (node, "host_ip6_addr",
12525                                    format (0, "%U/%d", format_ip6_address,
12526                                            mp->host_ip6_addr,
12527                                            mp->host_ip6_prefix_len));
12528
12529 }
12530
12531 static int
12532 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12533 {
12534   vl_api_sw_interface_tap_v2_dump_t *mp;
12535   vl_api_control_ping_t *mp_ping;
12536   int ret;
12537
12538   print (vam->ofp,
12539          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12540          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12541          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12542          "host_ip6_addr");
12543
12544   /* Get list of tap interfaces */
12545   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12546   S (mp);
12547
12548   /* Use a control ping for synchronization */
12549   MPING (CONTROL_PING, mp_ping);
12550   S (mp_ping);
12551
12552   W (ret);
12553   return ret;
12554 }
12555
12556 static void vl_api_sw_interface_virtio_pci_details_t_handler
12557   (vl_api_sw_interface_virtio_pci_details_t * mp)
12558 {
12559   vat_main_t *vam = &vat_main;
12560
12561   typedef union
12562   {
12563     struct
12564     {
12565       u16 domain;
12566       u8 bus;
12567       u8 slot:5;
12568       u8 function:3;
12569     };
12570     u32 as_u32;
12571   } pci_addr_t;
12572   pci_addr_t addr;
12573   addr.as_u32 = ntohl (mp->pci_addr);
12574   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12575                          addr.slot, addr.function);
12576
12577   print (vam->ofp,
12578          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12579          pci_addr, ntohl (mp->sw_if_index),
12580          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12581          format_ethernet_address, mp->mac_addr,
12582          clib_net_to_host_u64 (mp->features));
12583   vec_free (pci_addr);
12584 }
12585
12586 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12587   (vl_api_sw_interface_virtio_pci_details_t * mp)
12588 {
12589   vat_main_t *vam = &vat_main;
12590   vat_json_node_t *node = NULL;
12591
12592   if (VAT_JSON_ARRAY != vam->json_tree.type)
12593     {
12594       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12595       vat_json_init_array (&vam->json_tree);
12596     }
12597   node = vat_json_array_add (&vam->json_tree);
12598
12599   vat_json_init_object (node);
12600   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12601   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12602   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12603   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12604   vat_json_object_add_uint (node, "features",
12605                             clib_net_to_host_u64 (mp->features));
12606   vat_json_object_add_string_copy (node, "mac_addr",
12607                                    format (0, "%U", format_ethernet_address,
12608                                            &mp->mac_addr));
12609 }
12610
12611 static int
12612 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12613 {
12614   vl_api_sw_interface_virtio_pci_dump_t *mp;
12615   vl_api_control_ping_t *mp_ping;
12616   int ret;
12617
12618   print (vam->ofp,
12619          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12620          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12621          "mac_addr", "features");
12622
12623   /* Get list of tap interfaces */
12624   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12625   S (mp);
12626
12627   /* Use a control ping for synchronization */
12628   MPING (CONTROL_PING, mp_ping);
12629   S (mp_ping);
12630
12631   W (ret);
12632   return ret;
12633 }
12634
12635 static int
12636 api_vxlan_offload_rx (vat_main_t * vam)
12637 {
12638   unformat_input_t *line_input = vam->input;
12639   vl_api_vxlan_offload_rx_t *mp;
12640   u32 hw_if_index = ~0, rx_if_index = ~0;
12641   u8 is_add = 1;
12642   int ret;
12643
12644   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12645     {
12646       if (unformat (line_input, "del"))
12647         is_add = 0;
12648       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12649                          &hw_if_index))
12650         ;
12651       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12652         ;
12653       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12654                          &rx_if_index))
12655         ;
12656       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12657         ;
12658       else
12659         {
12660           errmsg ("parse error '%U'", format_unformat_error, line_input);
12661           return -99;
12662         }
12663     }
12664
12665   if (hw_if_index == ~0)
12666     {
12667       errmsg ("no hw interface");
12668       return -99;
12669     }
12670
12671   if (rx_if_index == ~0)
12672     {
12673       errmsg ("no rx tunnel");
12674       return -99;
12675     }
12676
12677   M (VXLAN_OFFLOAD_RX, mp);
12678
12679   mp->hw_if_index = ntohl (hw_if_index);
12680   mp->sw_if_index = ntohl (rx_if_index);
12681   mp->enable = is_add;
12682
12683   S (mp);
12684   W (ret);
12685   return ret;
12686 }
12687
12688 static uword unformat_vxlan_decap_next
12689   (unformat_input_t * input, va_list * args)
12690 {
12691   u32 *result = va_arg (*args, u32 *);
12692   u32 tmp;
12693
12694   if (unformat (input, "l2"))
12695     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12696   else if (unformat (input, "%d", &tmp))
12697     *result = tmp;
12698   else
12699     return 0;
12700   return 1;
12701 }
12702
12703 static int
12704 api_vxlan_add_del_tunnel (vat_main_t * vam)
12705 {
12706   unformat_input_t *line_input = vam->input;
12707   vl_api_vxlan_add_del_tunnel_t *mp;
12708   ip46_address_t src, dst;
12709   u8 is_add = 1;
12710   u8 ipv4_set = 0, ipv6_set = 0;
12711   u8 src_set = 0;
12712   u8 dst_set = 0;
12713   u8 grp_set = 0;
12714   u32 instance = ~0;
12715   u32 mcast_sw_if_index = ~0;
12716   u32 encap_vrf_id = 0;
12717   u32 decap_next_index = ~0;
12718   u32 vni = 0;
12719   int ret;
12720
12721   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12722   clib_memset (&src, 0, sizeof src);
12723   clib_memset (&dst, 0, sizeof dst);
12724
12725   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12726     {
12727       if (unformat (line_input, "del"))
12728         is_add = 0;
12729       else if (unformat (line_input, "instance %d", &instance))
12730         ;
12731       else
12732         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12733         {
12734           ipv4_set = 1;
12735           src_set = 1;
12736         }
12737       else
12738         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12739         {
12740           ipv4_set = 1;
12741           dst_set = 1;
12742         }
12743       else
12744         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12745         {
12746           ipv6_set = 1;
12747           src_set = 1;
12748         }
12749       else
12750         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12751         {
12752           ipv6_set = 1;
12753           dst_set = 1;
12754         }
12755       else if (unformat (line_input, "group %U %U",
12756                          unformat_ip4_address, &dst.ip4,
12757                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12758         {
12759           grp_set = dst_set = 1;
12760           ipv4_set = 1;
12761         }
12762       else if (unformat (line_input, "group %U",
12763                          unformat_ip4_address, &dst.ip4))
12764         {
12765           grp_set = dst_set = 1;
12766           ipv4_set = 1;
12767         }
12768       else if (unformat (line_input, "group %U %U",
12769                          unformat_ip6_address, &dst.ip6,
12770                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12771         {
12772           grp_set = dst_set = 1;
12773           ipv6_set = 1;
12774         }
12775       else if (unformat (line_input, "group %U",
12776                          unformat_ip6_address, &dst.ip6))
12777         {
12778           grp_set = dst_set = 1;
12779           ipv6_set = 1;
12780         }
12781       else
12782         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12783         ;
12784       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12785         ;
12786       else if (unformat (line_input, "decap-next %U",
12787                          unformat_vxlan_decap_next, &decap_next_index))
12788         ;
12789       else if (unformat (line_input, "vni %d", &vni))
12790         ;
12791       else
12792         {
12793           errmsg ("parse error '%U'", format_unformat_error, line_input);
12794           return -99;
12795         }
12796     }
12797
12798   if (src_set == 0)
12799     {
12800       errmsg ("tunnel src address not specified");
12801       return -99;
12802     }
12803   if (dst_set == 0)
12804     {
12805       errmsg ("tunnel dst address not specified");
12806       return -99;
12807     }
12808
12809   if (grp_set && !ip46_address_is_multicast (&dst))
12810     {
12811       errmsg ("tunnel group address not multicast");
12812       return -99;
12813     }
12814   if (grp_set && mcast_sw_if_index == ~0)
12815     {
12816       errmsg ("tunnel nonexistent multicast device");
12817       return -99;
12818     }
12819   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12820     {
12821       errmsg ("tunnel dst address must be unicast");
12822       return -99;
12823     }
12824
12825
12826   if (ipv4_set && ipv6_set)
12827     {
12828       errmsg ("both IPv4 and IPv6 addresses specified");
12829       return -99;
12830     }
12831
12832   if ((vni == 0) || (vni >> 24))
12833     {
12834       errmsg ("vni not specified or out of range");
12835       return -99;
12836     }
12837
12838   M (VXLAN_ADD_DEL_TUNNEL, mp);
12839
12840   if (ipv6_set)
12841     {
12842       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12843       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12844     }
12845   else
12846     {
12847       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12848       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12849     }
12850
12851   mp->instance = htonl (instance);
12852   mp->encap_vrf_id = ntohl (encap_vrf_id);
12853   mp->decap_next_index = ntohl (decap_next_index);
12854   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12855   mp->vni = ntohl (vni);
12856   mp->is_add = is_add;
12857   mp->is_ipv6 = ipv6_set;
12858
12859   S (mp);
12860   W (ret);
12861   return ret;
12862 }
12863
12864 static void vl_api_vxlan_tunnel_details_t_handler
12865   (vl_api_vxlan_tunnel_details_t * mp)
12866 {
12867   vat_main_t *vam = &vat_main;
12868   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12869   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12870
12871   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12872          ntohl (mp->sw_if_index),
12873          ntohl (mp->instance),
12874          format_ip46_address, &src, IP46_TYPE_ANY,
12875          format_ip46_address, &dst, IP46_TYPE_ANY,
12876          ntohl (mp->encap_vrf_id),
12877          ntohl (mp->decap_next_index), ntohl (mp->vni),
12878          ntohl (mp->mcast_sw_if_index));
12879 }
12880
12881 static void vl_api_vxlan_tunnel_details_t_handler_json
12882   (vl_api_vxlan_tunnel_details_t * mp)
12883 {
12884   vat_main_t *vam = &vat_main;
12885   vat_json_node_t *node = NULL;
12886
12887   if (VAT_JSON_ARRAY != vam->json_tree.type)
12888     {
12889       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12890       vat_json_init_array (&vam->json_tree);
12891     }
12892   node = vat_json_array_add (&vam->json_tree);
12893
12894   vat_json_init_object (node);
12895   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12896
12897   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12898
12899   if (mp->is_ipv6)
12900     {
12901       struct in6_addr ip6;
12902
12903       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12904       vat_json_object_add_ip6 (node, "src_address", ip6);
12905       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12906       vat_json_object_add_ip6 (node, "dst_address", ip6);
12907     }
12908   else
12909     {
12910       struct in_addr ip4;
12911
12912       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12913       vat_json_object_add_ip4 (node, "src_address", ip4);
12914       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12915       vat_json_object_add_ip4 (node, "dst_address", ip4);
12916     }
12917   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12918   vat_json_object_add_uint (node, "decap_next_index",
12919                             ntohl (mp->decap_next_index));
12920   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12921   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12922   vat_json_object_add_uint (node, "mcast_sw_if_index",
12923                             ntohl (mp->mcast_sw_if_index));
12924 }
12925
12926 static int
12927 api_vxlan_tunnel_dump (vat_main_t * vam)
12928 {
12929   unformat_input_t *i = vam->input;
12930   vl_api_vxlan_tunnel_dump_t *mp;
12931   vl_api_control_ping_t *mp_ping;
12932   u32 sw_if_index;
12933   u8 sw_if_index_set = 0;
12934   int ret;
12935
12936   /* Parse args required to build the message */
12937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12938     {
12939       if (unformat (i, "sw_if_index %d", &sw_if_index))
12940         sw_if_index_set = 1;
12941       else
12942         break;
12943     }
12944
12945   if (sw_if_index_set == 0)
12946     {
12947       sw_if_index = ~0;
12948     }
12949
12950   if (!vam->json_output)
12951     {
12952       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12953              "sw_if_index", "instance", "src_address", "dst_address",
12954              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12955     }
12956
12957   /* Get list of vxlan-tunnel interfaces */
12958   M (VXLAN_TUNNEL_DUMP, mp);
12959
12960   mp->sw_if_index = htonl (sw_if_index);
12961
12962   S (mp);
12963
12964   /* Use a control ping for synchronization */
12965   MPING (CONTROL_PING, mp_ping);
12966   S (mp_ping);
12967
12968   W (ret);
12969   return ret;
12970 }
12971
12972 static uword unformat_geneve_decap_next
12973   (unformat_input_t * input, va_list * args)
12974 {
12975   u32 *result = va_arg (*args, u32 *);
12976   u32 tmp;
12977
12978   if (unformat (input, "l2"))
12979     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12980   else if (unformat (input, "%d", &tmp))
12981     *result = tmp;
12982   else
12983     return 0;
12984   return 1;
12985 }
12986
12987 static int
12988 api_geneve_add_del_tunnel (vat_main_t * vam)
12989 {
12990   unformat_input_t *line_input = vam->input;
12991   vl_api_geneve_add_del_tunnel_t *mp;
12992   ip46_address_t src, dst;
12993   u8 is_add = 1;
12994   u8 ipv4_set = 0, ipv6_set = 0;
12995   u8 src_set = 0;
12996   u8 dst_set = 0;
12997   u8 grp_set = 0;
12998   u32 mcast_sw_if_index = ~0;
12999   u32 encap_vrf_id = 0;
13000   u32 decap_next_index = ~0;
13001   u32 vni = 0;
13002   int ret;
13003
13004   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13005   clib_memset (&src, 0, sizeof src);
13006   clib_memset (&dst, 0, sizeof dst);
13007
13008   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13009     {
13010       if (unformat (line_input, "del"))
13011         is_add = 0;
13012       else
13013         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13014         {
13015           ipv4_set = 1;
13016           src_set = 1;
13017         }
13018       else
13019         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13020         {
13021           ipv4_set = 1;
13022           dst_set = 1;
13023         }
13024       else
13025         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13026         {
13027           ipv6_set = 1;
13028           src_set = 1;
13029         }
13030       else
13031         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13032         {
13033           ipv6_set = 1;
13034           dst_set = 1;
13035         }
13036       else if (unformat (line_input, "group %U %U",
13037                          unformat_ip4_address, &dst.ip4,
13038                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13039         {
13040           grp_set = dst_set = 1;
13041           ipv4_set = 1;
13042         }
13043       else if (unformat (line_input, "group %U",
13044                          unformat_ip4_address, &dst.ip4))
13045         {
13046           grp_set = dst_set = 1;
13047           ipv4_set = 1;
13048         }
13049       else if (unformat (line_input, "group %U %U",
13050                          unformat_ip6_address, &dst.ip6,
13051                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13052         {
13053           grp_set = dst_set = 1;
13054           ipv6_set = 1;
13055         }
13056       else if (unformat (line_input, "group %U",
13057                          unformat_ip6_address, &dst.ip6))
13058         {
13059           grp_set = dst_set = 1;
13060           ipv6_set = 1;
13061         }
13062       else
13063         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13064         ;
13065       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13066         ;
13067       else if (unformat (line_input, "decap-next %U",
13068                          unformat_geneve_decap_next, &decap_next_index))
13069         ;
13070       else if (unformat (line_input, "vni %d", &vni))
13071         ;
13072       else
13073         {
13074           errmsg ("parse error '%U'", format_unformat_error, line_input);
13075           return -99;
13076         }
13077     }
13078
13079   if (src_set == 0)
13080     {
13081       errmsg ("tunnel src address not specified");
13082       return -99;
13083     }
13084   if (dst_set == 0)
13085     {
13086       errmsg ("tunnel dst address not specified");
13087       return -99;
13088     }
13089
13090   if (grp_set && !ip46_address_is_multicast (&dst))
13091     {
13092       errmsg ("tunnel group address not multicast");
13093       return -99;
13094     }
13095   if (grp_set && mcast_sw_if_index == ~0)
13096     {
13097       errmsg ("tunnel nonexistent multicast device");
13098       return -99;
13099     }
13100   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13101     {
13102       errmsg ("tunnel dst address must be unicast");
13103       return -99;
13104     }
13105
13106
13107   if (ipv4_set && ipv6_set)
13108     {
13109       errmsg ("both IPv4 and IPv6 addresses specified");
13110       return -99;
13111     }
13112
13113   if ((vni == 0) || (vni >> 24))
13114     {
13115       errmsg ("vni not specified or out of range");
13116       return -99;
13117     }
13118
13119   M (GENEVE_ADD_DEL_TUNNEL, mp);
13120
13121   if (ipv6_set)
13122     {
13123       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13124       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13125     }
13126   else
13127     {
13128       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13129       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13130     }
13131   mp->encap_vrf_id = ntohl (encap_vrf_id);
13132   mp->decap_next_index = ntohl (decap_next_index);
13133   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13134   mp->vni = ntohl (vni);
13135   mp->is_add = is_add;
13136   mp->is_ipv6 = ipv6_set;
13137
13138   S (mp);
13139   W (ret);
13140   return ret;
13141 }
13142
13143 static void vl_api_geneve_tunnel_details_t_handler
13144   (vl_api_geneve_tunnel_details_t * mp)
13145 {
13146   vat_main_t *vam = &vat_main;
13147   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13148   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13149
13150   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13151          ntohl (mp->sw_if_index),
13152          format_ip46_address, &src, IP46_TYPE_ANY,
13153          format_ip46_address, &dst, IP46_TYPE_ANY,
13154          ntohl (mp->encap_vrf_id),
13155          ntohl (mp->decap_next_index), ntohl (mp->vni),
13156          ntohl (mp->mcast_sw_if_index));
13157 }
13158
13159 static void vl_api_geneve_tunnel_details_t_handler_json
13160   (vl_api_geneve_tunnel_details_t * mp)
13161 {
13162   vat_main_t *vam = &vat_main;
13163   vat_json_node_t *node = NULL;
13164
13165   if (VAT_JSON_ARRAY != vam->json_tree.type)
13166     {
13167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13168       vat_json_init_array (&vam->json_tree);
13169     }
13170   node = vat_json_array_add (&vam->json_tree);
13171
13172   vat_json_init_object (node);
13173   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13174   if (mp->is_ipv6)
13175     {
13176       struct in6_addr ip6;
13177
13178       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13179       vat_json_object_add_ip6 (node, "src_address", ip6);
13180       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13181       vat_json_object_add_ip6 (node, "dst_address", ip6);
13182     }
13183   else
13184     {
13185       struct in_addr ip4;
13186
13187       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13188       vat_json_object_add_ip4 (node, "src_address", ip4);
13189       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13190       vat_json_object_add_ip4 (node, "dst_address", ip4);
13191     }
13192   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13193   vat_json_object_add_uint (node, "decap_next_index",
13194                             ntohl (mp->decap_next_index));
13195   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13196   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13197   vat_json_object_add_uint (node, "mcast_sw_if_index",
13198                             ntohl (mp->mcast_sw_if_index));
13199 }
13200
13201 static int
13202 api_geneve_tunnel_dump (vat_main_t * vam)
13203 {
13204   unformat_input_t *i = vam->input;
13205   vl_api_geneve_tunnel_dump_t *mp;
13206   vl_api_control_ping_t *mp_ping;
13207   u32 sw_if_index;
13208   u8 sw_if_index_set = 0;
13209   int ret;
13210
13211   /* Parse args required to build the message */
13212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13213     {
13214       if (unformat (i, "sw_if_index %d", &sw_if_index))
13215         sw_if_index_set = 1;
13216       else
13217         break;
13218     }
13219
13220   if (sw_if_index_set == 0)
13221     {
13222       sw_if_index = ~0;
13223     }
13224
13225   if (!vam->json_output)
13226     {
13227       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13228              "sw_if_index", "local_address", "remote_address",
13229              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13230     }
13231
13232   /* Get list of geneve-tunnel interfaces */
13233   M (GENEVE_TUNNEL_DUMP, mp);
13234
13235   mp->sw_if_index = htonl (sw_if_index);
13236
13237   S (mp);
13238
13239   /* Use a control ping for synchronization */
13240   M (CONTROL_PING, mp_ping);
13241   S (mp_ping);
13242
13243   W (ret);
13244   return ret;
13245 }
13246
13247 static int
13248 api_gre_tunnel_add_del (vat_main_t * vam)
13249 {
13250   unformat_input_t *line_input = vam->input;
13251   vl_api_address_t src = { }, dst =
13252   {
13253   };
13254   vl_api_gre_tunnel_add_del_t *mp;
13255   vl_api_gre_tunnel_type_t t_type;
13256   u8 is_add = 1;
13257   u8 ipv4_set = 0;
13258   u8 ipv6_set = 0;
13259   u8 src_set = 0;
13260   u8 dst_set = 0;
13261   u32 outer_fib_id = 0;
13262   u32 session_id = 0;
13263   u32 instance = ~0;
13264   int ret;
13265
13266   t_type = GRE_API_TUNNEL_TYPE_L3;
13267
13268   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13269     {
13270       if (unformat (line_input, "del"))
13271         is_add = 0;
13272       else if (unformat (line_input, "instance %d", &instance))
13273         ;
13274       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13275         {
13276           src_set = 1;
13277         }
13278       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13279         {
13280           dst_set = 1;
13281         }
13282       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13283         ;
13284       else if (unformat (line_input, "teb"))
13285         t_type = GRE_API_TUNNEL_TYPE_TEB;
13286       else if (unformat (line_input, "erspan %d", &session_id))
13287         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13288       else
13289         {
13290           errmsg ("parse error '%U'", format_unformat_error, line_input);
13291           return -99;
13292         }
13293     }
13294
13295   if (src_set == 0)
13296     {
13297       errmsg ("tunnel src address not specified");
13298       return -99;
13299     }
13300   if (dst_set == 0)
13301     {
13302       errmsg ("tunnel dst address not specified");
13303       return -99;
13304     }
13305
13306   M (GRE_TUNNEL_ADD_DEL, mp);
13307
13308   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13309   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13310
13311   mp->tunnel.instance = htonl (instance);
13312   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13313   mp->is_add = is_add;
13314   mp->tunnel.session_id = htons ((u16) session_id);
13315   mp->tunnel.type = htonl (t_type);
13316
13317   S (mp);
13318   W (ret);
13319   return ret;
13320 }
13321
13322 static void vl_api_gre_tunnel_details_t_handler
13323   (vl_api_gre_tunnel_details_t * mp)
13324 {
13325   vat_main_t *vam = &vat_main;
13326
13327   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13328          ntohl (mp->tunnel.sw_if_index),
13329          ntohl (mp->tunnel.instance),
13330          format_vl_api_address, &mp->tunnel.src,
13331          format_vl_api_address, &mp->tunnel.dst,
13332          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13333          ntohl (mp->tunnel.session_id));
13334 }
13335
13336 static void
13337 vat_json_object_add_address (vat_json_node_t * node,
13338                              const char *str, const vl_api_address_t * addr)
13339 {
13340   if (ADDRESS_IP6 == addr->af)
13341     {
13342       struct in6_addr ip6;
13343
13344       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13345       vat_json_object_add_ip6 (node, str, ip6);
13346     }
13347   else
13348     {
13349       struct in_addr ip4;
13350
13351       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13352       vat_json_object_add_ip4 (node, str, ip4);
13353     }
13354 }
13355
13356 static void vl_api_gre_tunnel_details_t_handler_json
13357   (vl_api_gre_tunnel_details_t * mp)
13358 {
13359   vat_main_t *vam = &vat_main;
13360   vat_json_node_t *node = NULL;
13361   struct in_addr ip4;
13362   struct in6_addr ip6;
13363
13364   if (VAT_JSON_ARRAY != vam->json_tree.type)
13365     {
13366       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13367       vat_json_init_array (&vam->json_tree);
13368     }
13369   node = vat_json_array_add (&vam->json_tree);
13370
13371   vat_json_init_object (node);
13372   vat_json_object_add_uint (node, "sw_if_index",
13373                             ntohl (mp->tunnel.sw_if_index));
13374   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13375
13376   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13377   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13378   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13379   vat_json_object_add_uint (node, "outer_fib_id",
13380                             ntohl (mp->tunnel.outer_fib_id));
13381   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13382 }
13383
13384 static int
13385 api_gre_tunnel_dump (vat_main_t * vam)
13386 {
13387   unformat_input_t *i = vam->input;
13388   vl_api_gre_tunnel_dump_t *mp;
13389   vl_api_control_ping_t *mp_ping;
13390   u32 sw_if_index;
13391   u8 sw_if_index_set = 0;
13392   int ret;
13393
13394   /* Parse args required to build the message */
13395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13396     {
13397       if (unformat (i, "sw_if_index %d", &sw_if_index))
13398         sw_if_index_set = 1;
13399       else
13400         break;
13401     }
13402
13403   if (sw_if_index_set == 0)
13404     {
13405       sw_if_index = ~0;
13406     }
13407
13408   if (!vam->json_output)
13409     {
13410       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13411              "sw_if_index", "instance", "src_address", "dst_address",
13412              "tunnel_type", "outer_fib_id", "session_id");
13413     }
13414
13415   /* Get list of gre-tunnel interfaces */
13416   M (GRE_TUNNEL_DUMP, mp);
13417
13418   mp->sw_if_index = htonl (sw_if_index);
13419
13420   S (mp);
13421
13422   /* Use a control ping for synchronization */
13423   MPING (CONTROL_PING, mp_ping);
13424   S (mp_ping);
13425
13426   W (ret);
13427   return ret;
13428 }
13429
13430 static int
13431 api_l2_fib_clear_table (vat_main_t * vam)
13432 {
13433 //  unformat_input_t * i = vam->input;
13434   vl_api_l2_fib_clear_table_t *mp;
13435   int ret;
13436
13437   M (L2_FIB_CLEAR_TABLE, mp);
13438
13439   S (mp);
13440   W (ret);
13441   return ret;
13442 }
13443
13444 static int
13445 api_l2_interface_efp_filter (vat_main_t * vam)
13446 {
13447   unformat_input_t *i = vam->input;
13448   vl_api_l2_interface_efp_filter_t *mp;
13449   u32 sw_if_index;
13450   u8 enable = 1;
13451   u8 sw_if_index_set = 0;
13452   int ret;
13453
13454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13455     {
13456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13457         sw_if_index_set = 1;
13458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13459         sw_if_index_set = 1;
13460       else if (unformat (i, "enable"))
13461         enable = 1;
13462       else if (unformat (i, "disable"))
13463         enable = 0;
13464       else
13465         {
13466           clib_warning ("parse error '%U'", format_unformat_error, i);
13467           return -99;
13468         }
13469     }
13470
13471   if (sw_if_index_set == 0)
13472     {
13473       errmsg ("missing sw_if_index");
13474       return -99;
13475     }
13476
13477   M (L2_INTERFACE_EFP_FILTER, mp);
13478
13479   mp->sw_if_index = ntohl (sw_if_index);
13480   mp->enable_disable = enable;
13481
13482   S (mp);
13483   W (ret);
13484   return ret;
13485 }
13486
13487 #define foreach_vtr_op                          \
13488 _("disable",  L2_VTR_DISABLED)                  \
13489 _("push-1",  L2_VTR_PUSH_1)                     \
13490 _("push-2",  L2_VTR_PUSH_2)                     \
13491 _("pop-1",  L2_VTR_POP_1)                       \
13492 _("pop-2",  L2_VTR_POP_2)                       \
13493 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13494 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13495 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13496 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13497
13498 static int
13499 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13500 {
13501   unformat_input_t *i = vam->input;
13502   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13503   u32 sw_if_index;
13504   u8 sw_if_index_set = 0;
13505   u8 vtr_op_set = 0;
13506   u32 vtr_op = 0;
13507   u32 push_dot1q = 1;
13508   u32 tag1 = ~0;
13509   u32 tag2 = ~0;
13510   int ret;
13511
13512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13513     {
13514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13515         sw_if_index_set = 1;
13516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13517         sw_if_index_set = 1;
13518       else if (unformat (i, "vtr_op %d", &vtr_op))
13519         vtr_op_set = 1;
13520 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13521       foreach_vtr_op
13522 #undef _
13523         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13524         ;
13525       else if (unformat (i, "tag1 %d", &tag1))
13526         ;
13527       else if (unformat (i, "tag2 %d", &tag2))
13528         ;
13529       else
13530         {
13531           clib_warning ("parse error '%U'", format_unformat_error, i);
13532           return -99;
13533         }
13534     }
13535
13536   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13537     {
13538       errmsg ("missing vtr operation or sw_if_index");
13539       return -99;
13540     }
13541
13542   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13543   mp->sw_if_index = ntohl (sw_if_index);
13544   mp->vtr_op = ntohl (vtr_op);
13545   mp->push_dot1q = ntohl (push_dot1q);
13546   mp->tag1 = ntohl (tag1);
13547   mp->tag2 = ntohl (tag2);
13548
13549   S (mp);
13550   W (ret);
13551   return ret;
13552 }
13553
13554 static int
13555 api_create_vhost_user_if (vat_main_t * vam)
13556 {
13557   unformat_input_t *i = vam->input;
13558   vl_api_create_vhost_user_if_t *mp;
13559   u8 *file_name;
13560   u8 is_server = 0;
13561   u8 file_name_set = 0;
13562   u32 custom_dev_instance = ~0;
13563   u8 hwaddr[6];
13564   u8 use_custom_mac = 0;
13565   u8 disable_mrg_rxbuf = 0;
13566   u8 disable_indirect_desc = 0;
13567   u8 *tag = 0;
13568   int ret;
13569
13570   /* Shut up coverity */
13571   clib_memset (hwaddr, 0, sizeof (hwaddr));
13572
13573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13574     {
13575       if (unformat (i, "socket %s", &file_name))
13576         {
13577           file_name_set = 1;
13578         }
13579       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13580         ;
13581       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13582         use_custom_mac = 1;
13583       else if (unformat (i, "server"))
13584         is_server = 1;
13585       else if (unformat (i, "disable_mrg_rxbuf"))
13586         disable_mrg_rxbuf = 1;
13587       else if (unformat (i, "disable_indirect_desc"))
13588         disable_indirect_desc = 1;
13589       else if (unformat (i, "tag %s", &tag))
13590         ;
13591       else
13592         break;
13593     }
13594
13595   if (file_name_set == 0)
13596     {
13597       errmsg ("missing socket file name");
13598       return -99;
13599     }
13600
13601   if (vec_len (file_name) > 255)
13602     {
13603       errmsg ("socket file name too long");
13604       return -99;
13605     }
13606   vec_add1 (file_name, 0);
13607
13608   M (CREATE_VHOST_USER_IF, mp);
13609
13610   mp->is_server = is_server;
13611   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13612   mp->disable_indirect_desc = disable_indirect_desc;
13613   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13614   vec_free (file_name);
13615   if (custom_dev_instance != ~0)
13616     {
13617       mp->renumber = 1;
13618       mp->custom_dev_instance = ntohl (custom_dev_instance);
13619     }
13620
13621   mp->use_custom_mac = use_custom_mac;
13622   clib_memcpy (mp->mac_address, hwaddr, 6);
13623   if (tag)
13624     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13625   vec_free (tag);
13626
13627   S (mp);
13628   W (ret);
13629   return ret;
13630 }
13631
13632 static int
13633 api_modify_vhost_user_if (vat_main_t * vam)
13634 {
13635   unformat_input_t *i = vam->input;
13636   vl_api_modify_vhost_user_if_t *mp;
13637   u8 *file_name;
13638   u8 is_server = 0;
13639   u8 file_name_set = 0;
13640   u32 custom_dev_instance = ~0;
13641   u8 sw_if_index_set = 0;
13642   u32 sw_if_index = (u32) ~ 0;
13643   int ret;
13644
13645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13646     {
13647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13648         sw_if_index_set = 1;
13649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13650         sw_if_index_set = 1;
13651       else if (unformat (i, "socket %s", &file_name))
13652         {
13653           file_name_set = 1;
13654         }
13655       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13656         ;
13657       else if (unformat (i, "server"))
13658         is_server = 1;
13659       else
13660         break;
13661     }
13662
13663   if (sw_if_index_set == 0)
13664     {
13665       errmsg ("missing sw_if_index or interface name");
13666       return -99;
13667     }
13668
13669   if (file_name_set == 0)
13670     {
13671       errmsg ("missing socket file name");
13672       return -99;
13673     }
13674
13675   if (vec_len (file_name) > 255)
13676     {
13677       errmsg ("socket file name too long");
13678       return -99;
13679     }
13680   vec_add1 (file_name, 0);
13681
13682   M (MODIFY_VHOST_USER_IF, mp);
13683
13684   mp->sw_if_index = ntohl (sw_if_index);
13685   mp->is_server = is_server;
13686   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13687   vec_free (file_name);
13688   if (custom_dev_instance != ~0)
13689     {
13690       mp->renumber = 1;
13691       mp->custom_dev_instance = ntohl (custom_dev_instance);
13692     }
13693
13694   S (mp);
13695   W (ret);
13696   return ret;
13697 }
13698
13699 static int
13700 api_delete_vhost_user_if (vat_main_t * vam)
13701 {
13702   unformat_input_t *i = vam->input;
13703   vl_api_delete_vhost_user_if_t *mp;
13704   u32 sw_if_index = ~0;
13705   u8 sw_if_index_set = 0;
13706   int ret;
13707
13708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13709     {
13710       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13711         sw_if_index_set = 1;
13712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13713         sw_if_index_set = 1;
13714       else
13715         break;
13716     }
13717
13718   if (sw_if_index_set == 0)
13719     {
13720       errmsg ("missing sw_if_index or interface name");
13721       return -99;
13722     }
13723
13724
13725   M (DELETE_VHOST_USER_IF, mp);
13726
13727   mp->sw_if_index = ntohl (sw_if_index);
13728
13729   S (mp);
13730   W (ret);
13731   return ret;
13732 }
13733
13734 static void vl_api_sw_interface_vhost_user_details_t_handler
13735   (vl_api_sw_interface_vhost_user_details_t * mp)
13736 {
13737   vat_main_t *vam = &vat_main;
13738
13739   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13740          (char *) mp->interface_name,
13741          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13742          clib_net_to_host_u64 (mp->features), mp->is_server,
13743          ntohl (mp->num_regions), (char *) mp->sock_filename);
13744   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13745 }
13746
13747 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13748   (vl_api_sw_interface_vhost_user_details_t * mp)
13749 {
13750   vat_main_t *vam = &vat_main;
13751   vat_json_node_t *node = NULL;
13752
13753   if (VAT_JSON_ARRAY != vam->json_tree.type)
13754     {
13755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13756       vat_json_init_array (&vam->json_tree);
13757     }
13758   node = vat_json_array_add (&vam->json_tree);
13759
13760   vat_json_init_object (node);
13761   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13762   vat_json_object_add_string_copy (node, "interface_name",
13763                                    mp->interface_name);
13764   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13765                             ntohl (mp->virtio_net_hdr_sz));
13766   vat_json_object_add_uint (node, "features",
13767                             clib_net_to_host_u64 (mp->features));
13768   vat_json_object_add_uint (node, "is_server", mp->is_server);
13769   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13770   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13771   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13772 }
13773
13774 static int
13775 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13776 {
13777   vl_api_sw_interface_vhost_user_dump_t *mp;
13778   vl_api_control_ping_t *mp_ping;
13779   int ret;
13780   print (vam->ofp,
13781          "Interface name            idx hdr_sz features server regions filename");
13782
13783   /* Get list of vhost-user interfaces */
13784   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13785   S (mp);
13786
13787   /* Use a control ping for synchronization */
13788   MPING (CONTROL_PING, mp_ping);
13789   S (mp_ping);
13790
13791   W (ret);
13792   return ret;
13793 }
13794
13795 static int
13796 api_show_version (vat_main_t * vam)
13797 {
13798   vl_api_show_version_t *mp;
13799   int ret;
13800
13801   M (SHOW_VERSION, mp);
13802
13803   S (mp);
13804   W (ret);
13805   return ret;
13806 }
13807
13808
13809 static int
13810 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13811 {
13812   unformat_input_t *line_input = vam->input;
13813   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13814   ip4_address_t local4, remote4;
13815   ip6_address_t local6, remote6;
13816   u8 is_add = 1;
13817   u8 ipv4_set = 0, ipv6_set = 0;
13818   u8 local_set = 0;
13819   u8 remote_set = 0;
13820   u8 grp_set = 0;
13821   u32 mcast_sw_if_index = ~0;
13822   u32 encap_vrf_id = 0;
13823   u32 decap_vrf_id = 0;
13824   u8 protocol = ~0;
13825   u32 vni;
13826   u8 vni_set = 0;
13827   int ret;
13828
13829   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13830   clib_memset (&local4, 0, sizeof local4);
13831   clib_memset (&remote4, 0, sizeof remote4);
13832   clib_memset (&local6, 0, sizeof local6);
13833   clib_memset (&remote6, 0, sizeof remote6);
13834
13835   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13836     {
13837       if (unformat (line_input, "del"))
13838         is_add = 0;
13839       else if (unformat (line_input, "local %U",
13840                          unformat_ip4_address, &local4))
13841         {
13842           local_set = 1;
13843           ipv4_set = 1;
13844         }
13845       else if (unformat (line_input, "remote %U",
13846                          unformat_ip4_address, &remote4))
13847         {
13848           remote_set = 1;
13849           ipv4_set = 1;
13850         }
13851       else if (unformat (line_input, "local %U",
13852                          unformat_ip6_address, &local6))
13853         {
13854           local_set = 1;
13855           ipv6_set = 1;
13856         }
13857       else if (unformat (line_input, "remote %U",
13858                          unformat_ip6_address, &remote6))
13859         {
13860           remote_set = 1;
13861           ipv6_set = 1;
13862         }
13863       else if (unformat (line_input, "group %U %U",
13864                          unformat_ip4_address, &remote4,
13865                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13866         {
13867           grp_set = remote_set = 1;
13868           ipv4_set = 1;
13869         }
13870       else if (unformat (line_input, "group %U",
13871                          unformat_ip4_address, &remote4))
13872         {
13873           grp_set = remote_set = 1;
13874           ipv4_set = 1;
13875         }
13876       else if (unformat (line_input, "group %U %U",
13877                          unformat_ip6_address, &remote6,
13878                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13879         {
13880           grp_set = remote_set = 1;
13881           ipv6_set = 1;
13882         }
13883       else if (unformat (line_input, "group %U",
13884                          unformat_ip6_address, &remote6))
13885         {
13886           grp_set = remote_set = 1;
13887           ipv6_set = 1;
13888         }
13889       else
13890         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13891         ;
13892       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13893         ;
13894       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13895         ;
13896       else if (unformat (line_input, "vni %d", &vni))
13897         vni_set = 1;
13898       else if (unformat (line_input, "next-ip4"))
13899         protocol = 1;
13900       else if (unformat (line_input, "next-ip6"))
13901         protocol = 2;
13902       else if (unformat (line_input, "next-ethernet"))
13903         protocol = 3;
13904       else if (unformat (line_input, "next-nsh"))
13905         protocol = 4;
13906       else
13907         {
13908           errmsg ("parse error '%U'", format_unformat_error, line_input);
13909           return -99;
13910         }
13911     }
13912
13913   if (local_set == 0)
13914     {
13915       errmsg ("tunnel local address not specified");
13916       return -99;
13917     }
13918   if (remote_set == 0)
13919     {
13920       errmsg ("tunnel remote address not specified");
13921       return -99;
13922     }
13923   if (grp_set && mcast_sw_if_index == ~0)
13924     {
13925       errmsg ("tunnel nonexistent multicast device");
13926       return -99;
13927     }
13928   if (ipv4_set && ipv6_set)
13929     {
13930       errmsg ("both IPv4 and IPv6 addresses specified");
13931       return -99;
13932     }
13933
13934   if (vni_set == 0)
13935     {
13936       errmsg ("vni not specified");
13937       return -99;
13938     }
13939
13940   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13941
13942
13943   if (ipv6_set)
13944     {
13945       clib_memcpy (&mp->local, &local6, sizeof (local6));
13946       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13947     }
13948   else
13949     {
13950       clib_memcpy (&mp->local, &local4, sizeof (local4));
13951       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13952     }
13953
13954   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13955   mp->encap_vrf_id = ntohl (encap_vrf_id);
13956   mp->decap_vrf_id = ntohl (decap_vrf_id);
13957   mp->protocol = protocol;
13958   mp->vni = ntohl (vni);
13959   mp->is_add = is_add;
13960   mp->is_ipv6 = ipv6_set;
13961
13962   S (mp);
13963   W (ret);
13964   return ret;
13965 }
13966
13967 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13968   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13969 {
13970   vat_main_t *vam = &vat_main;
13971   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13972   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13973
13974   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13975          ntohl (mp->sw_if_index),
13976          format_ip46_address, &local, IP46_TYPE_ANY,
13977          format_ip46_address, &remote, IP46_TYPE_ANY,
13978          ntohl (mp->vni), mp->protocol,
13979          ntohl (mp->mcast_sw_if_index),
13980          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13981 }
13982
13983
13984 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13985   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13986 {
13987   vat_main_t *vam = &vat_main;
13988   vat_json_node_t *node = NULL;
13989   struct in_addr ip4;
13990   struct in6_addr ip6;
13991
13992   if (VAT_JSON_ARRAY != vam->json_tree.type)
13993     {
13994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13995       vat_json_init_array (&vam->json_tree);
13996     }
13997   node = vat_json_array_add (&vam->json_tree);
13998
13999   vat_json_init_object (node);
14000   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14001   if (mp->is_ipv6)
14002     {
14003       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14004       vat_json_object_add_ip6 (node, "local", ip6);
14005       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14006       vat_json_object_add_ip6 (node, "remote", ip6);
14007     }
14008   else
14009     {
14010       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14011       vat_json_object_add_ip4 (node, "local", ip4);
14012       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14013       vat_json_object_add_ip4 (node, "remote", ip4);
14014     }
14015   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14016   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14017   vat_json_object_add_uint (node, "mcast_sw_if_index",
14018                             ntohl (mp->mcast_sw_if_index));
14019   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14020   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14021   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14022 }
14023
14024 static int
14025 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14026 {
14027   unformat_input_t *i = vam->input;
14028   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14029   vl_api_control_ping_t *mp_ping;
14030   u32 sw_if_index;
14031   u8 sw_if_index_set = 0;
14032   int ret;
14033
14034   /* Parse args required to build the message */
14035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14036     {
14037       if (unformat (i, "sw_if_index %d", &sw_if_index))
14038         sw_if_index_set = 1;
14039       else
14040         break;
14041     }
14042
14043   if (sw_if_index_set == 0)
14044     {
14045       sw_if_index = ~0;
14046     }
14047
14048   if (!vam->json_output)
14049     {
14050       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14051              "sw_if_index", "local", "remote", "vni",
14052              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14053     }
14054
14055   /* Get list of vxlan-tunnel interfaces */
14056   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14057
14058   mp->sw_if_index = htonl (sw_if_index);
14059
14060   S (mp);
14061
14062   /* Use a control ping for synchronization */
14063   MPING (CONTROL_PING, mp_ping);
14064   S (mp_ping);
14065
14066   W (ret);
14067   return ret;
14068 }
14069
14070 static void vl_api_l2_fib_table_details_t_handler
14071   (vl_api_l2_fib_table_details_t * mp)
14072 {
14073   vat_main_t *vam = &vat_main;
14074
14075   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14076          "       %d       %d     %d",
14077          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14078          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14079          mp->bvi_mac);
14080 }
14081
14082 static void vl_api_l2_fib_table_details_t_handler_json
14083   (vl_api_l2_fib_table_details_t * mp)
14084 {
14085   vat_main_t *vam = &vat_main;
14086   vat_json_node_t *node = NULL;
14087
14088   if (VAT_JSON_ARRAY != vam->json_tree.type)
14089     {
14090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14091       vat_json_init_array (&vam->json_tree);
14092     }
14093   node = vat_json_array_add (&vam->json_tree);
14094
14095   vat_json_init_object (node);
14096   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14097   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14098   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14099   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14100   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14101   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14102 }
14103
14104 static int
14105 api_l2_fib_table_dump (vat_main_t * vam)
14106 {
14107   unformat_input_t *i = vam->input;
14108   vl_api_l2_fib_table_dump_t *mp;
14109   vl_api_control_ping_t *mp_ping;
14110   u32 bd_id;
14111   u8 bd_id_set = 0;
14112   int ret;
14113
14114   /* Parse args required to build the message */
14115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14116     {
14117       if (unformat (i, "bd_id %d", &bd_id))
14118         bd_id_set = 1;
14119       else
14120         break;
14121     }
14122
14123   if (bd_id_set == 0)
14124     {
14125       errmsg ("missing bridge domain");
14126       return -99;
14127     }
14128
14129   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14130
14131   /* Get list of l2 fib entries */
14132   M (L2_FIB_TABLE_DUMP, mp);
14133
14134   mp->bd_id = ntohl (bd_id);
14135   S (mp);
14136
14137   /* Use a control ping for synchronization */
14138   MPING (CONTROL_PING, mp_ping);
14139   S (mp_ping);
14140
14141   W (ret);
14142   return ret;
14143 }
14144
14145
14146 static int
14147 api_interface_name_renumber (vat_main_t * vam)
14148 {
14149   unformat_input_t *line_input = vam->input;
14150   vl_api_interface_name_renumber_t *mp;
14151   u32 sw_if_index = ~0;
14152   u32 new_show_dev_instance = ~0;
14153   int ret;
14154
14155   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14156     {
14157       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14158                     &sw_if_index))
14159         ;
14160       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14161         ;
14162       else if (unformat (line_input, "new_show_dev_instance %d",
14163                          &new_show_dev_instance))
14164         ;
14165       else
14166         break;
14167     }
14168
14169   if (sw_if_index == ~0)
14170     {
14171       errmsg ("missing interface name or sw_if_index");
14172       return -99;
14173     }
14174
14175   if (new_show_dev_instance == ~0)
14176     {
14177       errmsg ("missing new_show_dev_instance");
14178       return -99;
14179     }
14180
14181   M (INTERFACE_NAME_RENUMBER, mp);
14182
14183   mp->sw_if_index = ntohl (sw_if_index);
14184   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14185
14186   S (mp);
14187   W (ret);
14188   return ret;
14189 }
14190
14191 static int
14192 api_ip_probe_neighbor (vat_main_t * vam)
14193 {
14194   unformat_input_t *i = vam->input;
14195   vl_api_ip_probe_neighbor_t *mp;
14196   vl_api_address_t dst_adr;
14197   u8 int_set = 0;
14198   u8 adr_set = 0;
14199   u32 sw_if_index;
14200   int ret;
14201
14202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14205         int_set = 1;
14206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14207         int_set = 1;
14208       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14209         adr_set = 1;
14210       else
14211         break;
14212     }
14213
14214   if (int_set == 0)
14215     {
14216       errmsg ("missing interface");
14217       return -99;
14218     }
14219
14220   if (adr_set == 0)
14221     {
14222       errmsg ("missing addresses");
14223       return -99;
14224     }
14225
14226   M (IP_PROBE_NEIGHBOR, mp);
14227
14228   mp->sw_if_index = ntohl (sw_if_index);
14229   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14230
14231   S (mp);
14232   W (ret);
14233   return ret;
14234 }
14235
14236 static int
14237 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14238 {
14239   unformat_input_t *i = vam->input;
14240   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14241   u8 mode = IP_SCAN_V46_NEIGHBORS;
14242   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14243   int ret;
14244
14245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14246     {
14247       if (unformat (i, "ip4"))
14248         mode = IP_SCAN_V4_NEIGHBORS;
14249       else if (unformat (i, "ip6"))
14250         mode = IP_SCAN_V6_NEIGHBORS;
14251       if (unformat (i, "both"))
14252         mode = IP_SCAN_V46_NEIGHBORS;
14253       else if (unformat (i, "disable"))
14254         mode = IP_SCAN_DISABLED;
14255       else if (unformat (i, "interval %d", &interval))
14256         ;
14257       else if (unformat (i, "max-time %d", &time))
14258         ;
14259       else if (unformat (i, "max-update %d", &update))
14260         ;
14261       else if (unformat (i, "delay %d", &delay))
14262         ;
14263       else if (unformat (i, "stale %d", &stale))
14264         ;
14265       else
14266         break;
14267     }
14268
14269   if (interval > 255)
14270     {
14271       errmsg ("interval cannot exceed 255 minutes.");
14272       return -99;
14273     }
14274   if (time > 255)
14275     {
14276       errmsg ("max-time cannot exceed 255 usec.");
14277       return -99;
14278     }
14279   if (update > 255)
14280     {
14281       errmsg ("max-update cannot exceed 255.");
14282       return -99;
14283     }
14284   if (delay > 255)
14285     {
14286       errmsg ("delay cannot exceed 255 msec.");
14287       return -99;
14288     }
14289   if (stale > 255)
14290     {
14291       errmsg ("stale cannot exceed 255 minutes.");
14292       return -99;
14293     }
14294
14295   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14296   mp->mode = mode;
14297   mp->scan_interval = interval;
14298   mp->max_proc_time = time;
14299   mp->max_update = update;
14300   mp->scan_int_delay = delay;
14301   mp->stale_threshold = stale;
14302
14303   S (mp);
14304   W (ret);
14305   return ret;
14306 }
14307
14308 static int
14309 api_want_ip4_arp_events (vat_main_t * vam)
14310 {
14311   unformat_input_t *line_input = vam->input;
14312   vl_api_want_ip4_arp_events_t *mp;
14313   ip4_address_t address;
14314   int address_set = 0;
14315   u32 enable_disable = 1;
14316   int ret;
14317
14318   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14319     {
14320       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14321         address_set = 1;
14322       else if (unformat (line_input, "del"))
14323         enable_disable = 0;
14324       else
14325         break;
14326     }
14327
14328   if (address_set == 0)
14329     {
14330       errmsg ("missing addresses");
14331       return -99;
14332     }
14333
14334   M (WANT_IP4_ARP_EVENTS, mp);
14335   mp->enable_disable = enable_disable;
14336   mp->pid = htonl (getpid ());
14337   clib_memcpy (mp->ip, &address, sizeof (address));
14338
14339   S (mp);
14340   W (ret);
14341   return ret;
14342 }
14343
14344 static int
14345 api_want_ip6_nd_events (vat_main_t * vam)
14346 {
14347   unformat_input_t *line_input = vam->input;
14348   vl_api_want_ip6_nd_events_t *mp;
14349   vl_api_ip6_address_t address;
14350   int address_set = 0;
14351   u32 enable_disable = 1;
14352   int ret;
14353
14354   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14355     {
14356       if (unformat
14357           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14358         address_set = 1;
14359       else if (unformat (line_input, "del"))
14360         enable_disable = 0;
14361       else
14362         break;
14363     }
14364
14365   if (address_set == 0)
14366     {
14367       errmsg ("missing addresses");
14368       return -99;
14369     }
14370
14371   M (WANT_IP6_ND_EVENTS, mp);
14372   mp->enable_disable = enable_disable;
14373   mp->pid = htonl (getpid ());
14374   clib_memcpy (&mp->ip, &address, sizeof (address));
14375
14376   S (mp);
14377   W (ret);
14378   return ret;
14379 }
14380
14381 static int
14382 api_want_l2_macs_events (vat_main_t * vam)
14383 {
14384   unformat_input_t *line_input = vam->input;
14385   vl_api_want_l2_macs_events_t *mp;
14386   u8 enable_disable = 1;
14387   u32 scan_delay = 0;
14388   u32 max_macs_in_event = 0;
14389   u32 learn_limit = 0;
14390   int ret;
14391
14392   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14393     {
14394       if (unformat (line_input, "learn-limit %d", &learn_limit))
14395         ;
14396       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14397         ;
14398       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14399         ;
14400       else if (unformat (line_input, "disable"))
14401         enable_disable = 0;
14402       else
14403         break;
14404     }
14405
14406   M (WANT_L2_MACS_EVENTS, mp);
14407   mp->enable_disable = enable_disable;
14408   mp->pid = htonl (getpid ());
14409   mp->learn_limit = htonl (learn_limit);
14410   mp->scan_delay = (u8) scan_delay;
14411   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14412   S (mp);
14413   W (ret);
14414   return ret;
14415 }
14416
14417 static int
14418 api_input_acl_set_interface (vat_main_t * vam)
14419 {
14420   unformat_input_t *i = vam->input;
14421   vl_api_input_acl_set_interface_t *mp;
14422   u32 sw_if_index;
14423   int sw_if_index_set;
14424   u32 ip4_table_index = ~0;
14425   u32 ip6_table_index = ~0;
14426   u32 l2_table_index = ~0;
14427   u8 is_add = 1;
14428   int ret;
14429
14430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14431     {
14432       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14433         sw_if_index_set = 1;
14434       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14435         sw_if_index_set = 1;
14436       else if (unformat (i, "del"))
14437         is_add = 0;
14438       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14439         ;
14440       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14441         ;
14442       else if (unformat (i, "l2-table %d", &l2_table_index))
14443         ;
14444       else
14445         {
14446           clib_warning ("parse error '%U'", format_unformat_error, i);
14447           return -99;
14448         }
14449     }
14450
14451   if (sw_if_index_set == 0)
14452     {
14453       errmsg ("missing interface name or sw_if_index");
14454       return -99;
14455     }
14456
14457   M (INPUT_ACL_SET_INTERFACE, mp);
14458
14459   mp->sw_if_index = ntohl (sw_if_index);
14460   mp->ip4_table_index = ntohl (ip4_table_index);
14461   mp->ip6_table_index = ntohl (ip6_table_index);
14462   mp->l2_table_index = ntohl (l2_table_index);
14463   mp->is_add = is_add;
14464
14465   S (mp);
14466   W (ret);
14467   return ret;
14468 }
14469
14470 static int
14471 api_output_acl_set_interface (vat_main_t * vam)
14472 {
14473   unformat_input_t *i = vam->input;
14474   vl_api_output_acl_set_interface_t *mp;
14475   u32 sw_if_index;
14476   int sw_if_index_set;
14477   u32 ip4_table_index = ~0;
14478   u32 ip6_table_index = ~0;
14479   u32 l2_table_index = ~0;
14480   u8 is_add = 1;
14481   int ret;
14482
14483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14484     {
14485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14486         sw_if_index_set = 1;
14487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14488         sw_if_index_set = 1;
14489       else if (unformat (i, "del"))
14490         is_add = 0;
14491       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14492         ;
14493       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14494         ;
14495       else if (unformat (i, "l2-table %d", &l2_table_index))
14496         ;
14497       else
14498         {
14499           clib_warning ("parse error '%U'", format_unformat_error, i);
14500           return -99;
14501         }
14502     }
14503
14504   if (sw_if_index_set == 0)
14505     {
14506       errmsg ("missing interface name or sw_if_index");
14507       return -99;
14508     }
14509
14510   M (OUTPUT_ACL_SET_INTERFACE, mp);
14511
14512   mp->sw_if_index = ntohl (sw_if_index);
14513   mp->ip4_table_index = ntohl (ip4_table_index);
14514   mp->ip6_table_index = ntohl (ip6_table_index);
14515   mp->l2_table_index = ntohl (l2_table_index);
14516   mp->is_add = is_add;
14517
14518   S (mp);
14519   W (ret);
14520   return ret;
14521 }
14522
14523 static int
14524 api_ip_address_dump (vat_main_t * vam)
14525 {
14526   unformat_input_t *i = vam->input;
14527   vl_api_ip_address_dump_t *mp;
14528   vl_api_control_ping_t *mp_ping;
14529   u32 sw_if_index = ~0;
14530   u8 sw_if_index_set = 0;
14531   u8 ipv4_set = 0;
14532   u8 ipv6_set = 0;
14533   int ret;
14534
14535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14536     {
14537       if (unformat (i, "sw_if_index %d", &sw_if_index))
14538         sw_if_index_set = 1;
14539       else
14540         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14541         sw_if_index_set = 1;
14542       else if (unformat (i, "ipv4"))
14543         ipv4_set = 1;
14544       else if (unformat (i, "ipv6"))
14545         ipv6_set = 1;
14546       else
14547         break;
14548     }
14549
14550   if (ipv4_set && ipv6_set)
14551     {
14552       errmsg ("ipv4 and ipv6 flags cannot be both set");
14553       return -99;
14554     }
14555
14556   if ((!ipv4_set) && (!ipv6_set))
14557     {
14558       errmsg ("no ipv4 nor ipv6 flag set");
14559       return -99;
14560     }
14561
14562   if (sw_if_index_set == 0)
14563     {
14564       errmsg ("missing interface name or sw_if_index");
14565       return -99;
14566     }
14567
14568   vam->current_sw_if_index = sw_if_index;
14569   vam->is_ipv6 = ipv6_set;
14570
14571   M (IP_ADDRESS_DUMP, mp);
14572   mp->sw_if_index = ntohl (sw_if_index);
14573   mp->is_ipv6 = ipv6_set;
14574   S (mp);
14575
14576   /* Use a control ping for synchronization */
14577   MPING (CONTROL_PING, mp_ping);
14578   S (mp_ping);
14579
14580   W (ret);
14581   return ret;
14582 }
14583
14584 static int
14585 api_ip_dump (vat_main_t * vam)
14586 {
14587   vl_api_ip_dump_t *mp;
14588   vl_api_control_ping_t *mp_ping;
14589   unformat_input_t *in = vam->input;
14590   int ipv4_set = 0;
14591   int ipv6_set = 0;
14592   int is_ipv6;
14593   int i;
14594   int ret;
14595
14596   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14597     {
14598       if (unformat (in, "ipv4"))
14599         ipv4_set = 1;
14600       else if (unformat (in, "ipv6"))
14601         ipv6_set = 1;
14602       else
14603         break;
14604     }
14605
14606   if (ipv4_set && ipv6_set)
14607     {
14608       errmsg ("ipv4 and ipv6 flags cannot be both set");
14609       return -99;
14610     }
14611
14612   if ((!ipv4_set) && (!ipv6_set))
14613     {
14614       errmsg ("no ipv4 nor ipv6 flag set");
14615       return -99;
14616     }
14617
14618   is_ipv6 = ipv6_set;
14619   vam->is_ipv6 = is_ipv6;
14620
14621   /* free old data */
14622   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14623     {
14624       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14625     }
14626   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14627
14628   M (IP_DUMP, mp);
14629   mp->is_ipv6 = ipv6_set;
14630   S (mp);
14631
14632   /* Use a control ping for synchronization */
14633   MPING (CONTROL_PING, mp_ping);
14634   S (mp_ping);
14635
14636   W (ret);
14637   return ret;
14638 }
14639
14640 static int
14641 api_ipsec_spd_add_del (vat_main_t * vam)
14642 {
14643   unformat_input_t *i = vam->input;
14644   vl_api_ipsec_spd_add_del_t *mp;
14645   u32 spd_id = ~0;
14646   u8 is_add = 1;
14647   int ret;
14648
14649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14650     {
14651       if (unformat (i, "spd_id %d", &spd_id))
14652         ;
14653       else if (unformat (i, "del"))
14654         is_add = 0;
14655       else
14656         {
14657           clib_warning ("parse error '%U'", format_unformat_error, i);
14658           return -99;
14659         }
14660     }
14661   if (spd_id == ~0)
14662     {
14663       errmsg ("spd_id must be set");
14664       return -99;
14665     }
14666
14667   M (IPSEC_SPD_ADD_DEL, mp);
14668
14669   mp->spd_id = ntohl (spd_id);
14670   mp->is_add = is_add;
14671
14672   S (mp);
14673   W (ret);
14674   return ret;
14675 }
14676
14677 static int
14678 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14679 {
14680   unformat_input_t *i = vam->input;
14681   vl_api_ipsec_interface_add_del_spd_t *mp;
14682   u32 sw_if_index;
14683   u8 sw_if_index_set = 0;
14684   u32 spd_id = (u32) ~ 0;
14685   u8 is_add = 1;
14686   int ret;
14687
14688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14689     {
14690       if (unformat (i, "del"))
14691         is_add = 0;
14692       else if (unformat (i, "spd_id %d", &spd_id))
14693         ;
14694       else
14695         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14696         sw_if_index_set = 1;
14697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14698         sw_if_index_set = 1;
14699       else
14700         {
14701           clib_warning ("parse error '%U'", format_unformat_error, i);
14702           return -99;
14703         }
14704
14705     }
14706
14707   if (spd_id == (u32) ~ 0)
14708     {
14709       errmsg ("spd_id must be set");
14710       return -99;
14711     }
14712
14713   if (sw_if_index_set == 0)
14714     {
14715       errmsg ("missing interface name or sw_if_index");
14716       return -99;
14717     }
14718
14719   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14720
14721   mp->spd_id = ntohl (spd_id);
14722   mp->sw_if_index = ntohl (sw_if_index);
14723   mp->is_add = is_add;
14724
14725   S (mp);
14726   W (ret);
14727   return ret;
14728 }
14729
14730 static int
14731 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14732 {
14733   unformat_input_t *i = vam->input;
14734   vl_api_ipsec_spd_entry_add_del_t *mp;
14735   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14736   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14737   i32 priority = 0;
14738   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14739   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14740   vl_api_address_t laddr_start = { }, laddr_stop =
14741   {
14742   }, raddr_start =
14743   {
14744   }, raddr_stop =
14745   {
14746   };
14747   int ret;
14748
14749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14750     {
14751       if (unformat (i, "del"))
14752         is_add = 0;
14753       if (unformat (i, "outbound"))
14754         is_outbound = 1;
14755       if (unformat (i, "inbound"))
14756         is_outbound = 0;
14757       else if (unformat (i, "spd_id %d", &spd_id))
14758         ;
14759       else if (unformat (i, "sa_id %d", &sa_id))
14760         ;
14761       else if (unformat (i, "priority %d", &priority))
14762         ;
14763       else if (unformat (i, "protocol %d", &protocol))
14764         ;
14765       else if (unformat (i, "lport_start %d", &lport_start))
14766         ;
14767       else if (unformat (i, "lport_stop %d", &lport_stop))
14768         ;
14769       else if (unformat (i, "rport_start %d", &rport_start))
14770         ;
14771       else if (unformat (i, "rport_stop %d", &rport_stop))
14772         ;
14773       else if (unformat (i, "laddr_start %U",
14774                          unformat_vl_api_address, &laddr_start))
14775         is_ip_any = 0;
14776       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14777                          &laddr_stop))
14778         is_ip_any = 0;
14779       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14780                          &raddr_start))
14781         is_ip_any = 0;
14782       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14783                          &raddr_stop))
14784         is_ip_any = 0;
14785       else
14786         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14787         {
14788           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14789             {
14790               clib_warning ("unsupported action: 'resolve'");
14791               return -99;
14792             }
14793         }
14794       else
14795         {
14796           clib_warning ("parse error '%U'", format_unformat_error, i);
14797           return -99;
14798         }
14799
14800     }
14801
14802   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14803
14804   mp->is_add = is_add;
14805
14806   mp->entry.spd_id = ntohl (spd_id);
14807   mp->entry.priority = ntohl (priority);
14808   mp->entry.is_outbound = is_outbound;
14809
14810   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14811                sizeof (vl_api_address_t));
14812   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14813                sizeof (vl_api_address_t));
14814   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14815                sizeof (vl_api_address_t));
14816   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14817                sizeof (vl_api_address_t));
14818
14819   mp->entry.protocol = (u8) protocol;
14820   mp->entry.local_port_start = ntohs ((u16) lport_start);
14821   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14822   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14823   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14824   mp->entry.policy = (u8) policy;
14825   mp->entry.sa_id = ntohl (sa_id);
14826
14827   S (mp);
14828   W (ret);
14829   return ret;
14830 }
14831
14832 static int
14833 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14834 {
14835   unformat_input_t *i = vam->input;
14836   vl_api_ipsec_sad_entry_add_del_t *mp;
14837   u32 sad_id = 0, spi = 0;
14838   u8 *ck = 0, *ik = 0;
14839   u8 is_add = 1;
14840
14841   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14842   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14843   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14844   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14845   vl_api_address_t tun_src, tun_dst;
14846   int ret;
14847
14848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14849     {
14850       if (unformat (i, "del"))
14851         is_add = 0;
14852       else if (unformat (i, "sad_id %d", &sad_id))
14853         ;
14854       else if (unformat (i, "spi %d", &spi))
14855         ;
14856       else if (unformat (i, "esp"))
14857         protocol = IPSEC_API_PROTO_ESP;
14858       else
14859         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14860         {
14861           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14862           if (ADDRESS_IP6 == tun_src.af)
14863             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14864         }
14865       else
14866         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14867         {
14868           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14869           if (ADDRESS_IP6 == tun_src.af)
14870             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14871         }
14872       else
14873         if (unformat (i, "crypto_alg %U",
14874                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14875         ;
14876       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14877         ;
14878       else if (unformat (i, "integ_alg %U",
14879                          unformat_ipsec_api_integ_alg, &integ_alg))
14880         ;
14881       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14882         ;
14883       else
14884         {
14885           clib_warning ("parse error '%U'", format_unformat_error, i);
14886           return -99;
14887         }
14888
14889     }
14890
14891   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14892
14893   mp->is_add = is_add;
14894   mp->entry.sad_id = ntohl (sad_id);
14895   mp->entry.protocol = protocol;
14896   mp->entry.spi = ntohl (spi);
14897   mp->entry.flags = flags;
14898
14899   mp->entry.crypto_algorithm = crypto_alg;
14900   mp->entry.integrity_algorithm = integ_alg;
14901   mp->entry.crypto_key.length = vec_len (ck);
14902   mp->entry.integrity_key.length = vec_len (ik);
14903
14904   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14905     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14906
14907   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14908     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14909
14910   if (ck)
14911     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14912   if (ik)
14913     clib_memcpy (mp->entry.integrity_key.data, ik,
14914                  mp->entry.integrity_key.length);
14915
14916   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14917     {
14918       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14919                    sizeof (mp->entry.tunnel_src));
14920       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14921                    sizeof (mp->entry.tunnel_dst));
14922     }
14923
14924   S (mp);
14925   W (ret);
14926   return ret;
14927 }
14928
14929 static int
14930 api_ipsec_sa_set_key (vat_main_t * vam)
14931 {
14932   unformat_input_t *i = vam->input;
14933   vl_api_ipsec_sa_set_key_t *mp;
14934   u32 sa_id;
14935   u8 *ck = 0, *ik = 0;
14936   int ret;
14937
14938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14939     {
14940       if (unformat (i, "sa_id %d", &sa_id))
14941         ;
14942       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14943         ;
14944       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14945         ;
14946       else
14947         {
14948           clib_warning ("parse error '%U'", format_unformat_error, i);
14949           return -99;
14950         }
14951     }
14952
14953   M (IPSEC_SA_SET_KEY, mp);
14954
14955   mp->sa_id = ntohl (sa_id);
14956   mp->crypto_key.length = vec_len (ck);
14957   mp->integrity_key.length = vec_len (ik);
14958
14959   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
14960     mp->crypto_key.length = sizeof (mp->crypto_key.data);
14961
14962   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
14963     mp->integrity_key.length = sizeof (mp->integrity_key.data);
14964
14965   if (ck)
14966     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
14967   if (ik)
14968     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
14969
14970   S (mp);
14971   W (ret);
14972   return ret;
14973 }
14974
14975 static int
14976 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14977 {
14978   unformat_input_t *i = vam->input;
14979   vl_api_ipsec_tunnel_if_add_del_t *mp;
14980   u32 local_spi = 0, remote_spi = 0;
14981   u32 crypto_alg = 0, integ_alg = 0;
14982   u8 *lck = NULL, *rck = NULL;
14983   u8 *lik = NULL, *rik = NULL;
14984   vl_api_address_t local_ip = { 0 };
14985   vl_api_address_t remote_ip = { 0 };
14986   f64 before = 0;
14987   u8 is_add = 1;
14988   u8 esn = 0;
14989   u8 anti_replay = 0;
14990   u8 renumber = 0;
14991   u32 instance = ~0;
14992   u32 count = 1, jj;
14993   int ret;
14994
14995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14996     {
14997       if (unformat (i, "del"))
14998         is_add = 0;
14999       else if (unformat (i, "esn"))
15000         esn = 1;
15001       else if (unformat (i, "anti-replay"))
15002         anti_replay = 1;
15003       else if (unformat (i, "count %d", &count))
15004         ;
15005       else if (unformat (i, "local_spi %d", &local_spi))
15006         ;
15007       else if (unformat (i, "remote_spi %d", &remote_spi))
15008         ;
15009       else
15010         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
15011         ;
15012       else
15013         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
15014         ;
15015       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15016         ;
15017       else
15018         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15019         ;
15020       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15021         ;
15022       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15023         ;
15024       else
15025         if (unformat
15026             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15027         {
15028           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15029             {
15030               errmsg ("unsupported crypto-alg: '%U'\n",
15031                       format_ipsec_crypto_alg, crypto_alg);
15032               return -99;
15033             }
15034         }
15035       else
15036         if (unformat
15037             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15038         {
15039           if (integ_alg >= IPSEC_INTEG_N_ALG)
15040             {
15041               errmsg ("unsupported integ-alg: '%U'\n",
15042                       format_ipsec_integ_alg, integ_alg);
15043               return -99;
15044             }
15045         }
15046       else if (unformat (i, "instance %u", &instance))
15047         renumber = 1;
15048       else
15049         {
15050           errmsg ("parse error '%U'\n", format_unformat_error, i);
15051           return -99;
15052         }
15053     }
15054
15055   if (count > 1)
15056     {
15057       /* Turn on async mode */
15058       vam->async_mode = 1;
15059       vam->async_errors = 0;
15060       before = vat_time_now (vam);
15061     }
15062
15063   for (jj = 0; jj < count; jj++)
15064     {
15065       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15066
15067       mp->is_add = is_add;
15068       mp->esn = esn;
15069       mp->anti_replay = anti_replay;
15070
15071       if (jj > 0)
15072         increment_vl_address (&remote_ip);
15073
15074       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15075       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15076
15077       mp->local_spi = htonl (local_spi + jj);
15078       mp->remote_spi = htonl (remote_spi + jj);
15079       mp->crypto_alg = (u8) crypto_alg;
15080
15081       mp->local_crypto_key_len = 0;
15082       if (lck)
15083         {
15084           mp->local_crypto_key_len = vec_len (lck);
15085           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15086             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15087           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15088         }
15089
15090       mp->remote_crypto_key_len = 0;
15091       if (rck)
15092         {
15093           mp->remote_crypto_key_len = vec_len (rck);
15094           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15095             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15096           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15097         }
15098
15099       mp->integ_alg = (u8) integ_alg;
15100
15101       mp->local_integ_key_len = 0;
15102       if (lik)
15103         {
15104           mp->local_integ_key_len = vec_len (lik);
15105           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15106             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15107           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15108         }
15109
15110       mp->remote_integ_key_len = 0;
15111       if (rik)
15112         {
15113           mp->remote_integ_key_len = vec_len (rik);
15114           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15115             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15116           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15117         }
15118
15119       if (renumber)
15120         {
15121           mp->renumber = renumber;
15122           mp->show_instance = ntohl (instance);
15123         }
15124       S (mp);
15125     }
15126
15127   /* When testing multiple add/del ops, use a control-ping to sync */
15128   if (count > 1)
15129     {
15130       vl_api_control_ping_t *mp_ping;
15131       f64 after;
15132       f64 timeout;
15133
15134       /* Shut off async mode */
15135       vam->async_mode = 0;
15136
15137       MPING (CONTROL_PING, mp_ping);
15138       S (mp_ping);
15139
15140       timeout = vat_time_now (vam) + 1.0;
15141       while (vat_time_now (vam) < timeout)
15142         if (vam->result_ready == 1)
15143           goto out;
15144       vam->retval = -99;
15145
15146     out:
15147       if (vam->retval == -99)
15148         errmsg ("timeout");
15149
15150       if (vam->async_errors > 0)
15151         {
15152           errmsg ("%d asynchronous errors", vam->async_errors);
15153           vam->retval = -98;
15154         }
15155       vam->async_errors = 0;
15156       after = vat_time_now (vam);
15157
15158       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15159       if (jj > 0)
15160         count = jj;
15161
15162       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15163              count, after - before, count / (after - before));
15164     }
15165   else
15166     {
15167       /* Wait for a reply... */
15168       W (ret);
15169       return ret;
15170     }
15171
15172   return ret;
15173 }
15174
15175 static void
15176 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15177 {
15178   vat_main_t *vam = &vat_main;
15179
15180   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15181          "crypto_key %U integ_alg %u integ_key %U flags %x "
15182          "tunnel_src_addr %U tunnel_dst_addr %U "
15183          "salt %u seq_outbound %lu last_seq_inbound %lu "
15184          "replay_window %lu\n",
15185          ntohl (mp->entry.sad_id),
15186          ntohl (mp->sw_if_index),
15187          ntohl (mp->entry.spi),
15188          ntohl (mp->entry.protocol),
15189          ntohl (mp->entry.crypto_algorithm),
15190          format_hex_bytes, mp->entry.crypto_key.data,
15191          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15192          format_hex_bytes, mp->entry.integrity_key.data,
15193          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15194          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15195          &mp->entry.tunnel_dst, ntohl (mp->salt),
15196          clib_net_to_host_u64 (mp->seq_outbound),
15197          clib_net_to_host_u64 (mp->last_seq_inbound),
15198          clib_net_to_host_u64 (mp->replay_window));
15199 }
15200
15201 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15202 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15203
15204 static void vl_api_ipsec_sa_details_t_handler_json
15205   (vl_api_ipsec_sa_details_t * mp)
15206 {
15207   vat_main_t *vam = &vat_main;
15208   vat_json_node_t *node = NULL;
15209   vl_api_ipsec_sad_flags_t flags;
15210
15211   if (VAT_JSON_ARRAY != vam->json_tree.type)
15212     {
15213       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15214       vat_json_init_array (&vam->json_tree);
15215     }
15216   node = vat_json_array_add (&vam->json_tree);
15217
15218   vat_json_init_object (node);
15219   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15220   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15221   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15222   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15223   vat_json_object_add_uint (node, "crypto_alg",
15224                             ntohl (mp->entry.crypto_algorithm));
15225   vat_json_object_add_uint (node, "integ_alg",
15226                             ntohl (mp->entry.integrity_algorithm));
15227   flags = ntohl (mp->entry.flags);
15228   vat_json_object_add_uint (node, "use_esn",
15229                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15230   vat_json_object_add_uint (node, "use_anti_replay",
15231                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15232   vat_json_object_add_uint (node, "is_tunnel",
15233                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15234   vat_json_object_add_uint (node, "is_tunnel_ip6",
15235                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15236   vat_json_object_add_uint (node, "udp_encap",
15237                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15238   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15239                              mp->entry.crypto_key.length);
15240   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15241                              mp->entry.integrity_key.length);
15242   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15243   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15244   vat_json_object_add_uint (node, "replay_window",
15245                             clib_net_to_host_u64 (mp->replay_window));
15246 }
15247
15248 static int
15249 api_ipsec_sa_dump (vat_main_t * vam)
15250 {
15251   unformat_input_t *i = vam->input;
15252   vl_api_ipsec_sa_dump_t *mp;
15253   vl_api_control_ping_t *mp_ping;
15254   u32 sa_id = ~0;
15255   int ret;
15256
15257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15258     {
15259       if (unformat (i, "sa_id %d", &sa_id))
15260         ;
15261       else
15262         {
15263           clib_warning ("parse error '%U'", format_unformat_error, i);
15264           return -99;
15265         }
15266     }
15267
15268   M (IPSEC_SA_DUMP, mp);
15269
15270   mp->sa_id = ntohl (sa_id);
15271
15272   S (mp);
15273
15274   /* Use a control ping for synchronization */
15275   M (CONTROL_PING, mp_ping);
15276   S (mp_ping);
15277
15278   W (ret);
15279   return ret;
15280 }
15281
15282 static int
15283 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15284 {
15285   unformat_input_t *i = vam->input;
15286   vl_api_ipsec_tunnel_if_set_key_t *mp;
15287   u32 sw_if_index = ~0;
15288   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15289   u8 *key = 0;
15290   u32 alg = ~0;
15291   int ret;
15292
15293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15294     {
15295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15296         ;
15297       else
15298         if (unformat
15299             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15300         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15301       else
15302         if (unformat
15303             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15304         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15305       else
15306         if (unformat
15307             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15308         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15309       else
15310         if (unformat
15311             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15312         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15313       else if (unformat (i, "%U", unformat_hex_string, &key))
15314         ;
15315       else
15316         {
15317           clib_warning ("parse error '%U'", format_unformat_error, i);
15318           return -99;
15319         }
15320     }
15321
15322   if (sw_if_index == ~0)
15323     {
15324       errmsg ("interface must be specified");
15325       return -99;
15326     }
15327
15328   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15329     {
15330       errmsg ("key type must be specified");
15331       return -99;
15332     }
15333
15334   if (alg == ~0)
15335     {
15336       errmsg ("algorithm must be specified");
15337       return -99;
15338     }
15339
15340   if (vec_len (key) == 0)
15341     {
15342       errmsg ("key must be specified");
15343       return -99;
15344     }
15345
15346   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15347
15348   mp->sw_if_index = htonl (sw_if_index);
15349   mp->alg = alg;
15350   mp->key_type = key_type;
15351   mp->key_len = vec_len (key);
15352   clib_memcpy (mp->key, key, vec_len (key));
15353
15354   S (mp);
15355   W (ret);
15356
15357   return ret;
15358 }
15359
15360 static int
15361 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15362 {
15363   unformat_input_t *i = vam->input;
15364   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15365   u32 sw_if_index = ~0;
15366   u32 sa_id = ~0;
15367   u8 is_outbound = (u8) ~ 0;
15368   int ret;
15369
15370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15371     {
15372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15373         ;
15374       else if (unformat (i, "sa_id %d", &sa_id))
15375         ;
15376       else if (unformat (i, "outbound"))
15377         is_outbound = 1;
15378       else if (unformat (i, "inbound"))
15379         is_outbound = 0;
15380       else
15381         {
15382           clib_warning ("parse error '%U'", format_unformat_error, i);
15383           return -99;
15384         }
15385     }
15386
15387   if (sw_if_index == ~0)
15388     {
15389       errmsg ("interface must be specified");
15390       return -99;
15391     }
15392
15393   if (sa_id == ~0)
15394     {
15395       errmsg ("SA ID must be specified");
15396       return -99;
15397     }
15398
15399   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15400
15401   mp->sw_if_index = htonl (sw_if_index);
15402   mp->sa_id = htonl (sa_id);
15403   mp->is_outbound = is_outbound;
15404
15405   S (mp);
15406   W (ret);
15407
15408   return ret;
15409 }
15410
15411 static int
15412 api_get_first_msg_id (vat_main_t * vam)
15413 {
15414   vl_api_get_first_msg_id_t *mp;
15415   unformat_input_t *i = vam->input;
15416   u8 *name;
15417   u8 name_set = 0;
15418   int ret;
15419
15420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15421     {
15422       if (unformat (i, "client %s", &name))
15423         name_set = 1;
15424       else
15425         break;
15426     }
15427
15428   if (name_set == 0)
15429     {
15430       errmsg ("missing client name");
15431       return -99;
15432     }
15433   vec_add1 (name, 0);
15434
15435   if (vec_len (name) > 63)
15436     {
15437       errmsg ("client name too long");
15438       return -99;
15439     }
15440
15441   M (GET_FIRST_MSG_ID, mp);
15442   clib_memcpy (mp->name, name, vec_len (name));
15443   S (mp);
15444   W (ret);
15445   return ret;
15446 }
15447
15448 static int
15449 api_cop_interface_enable_disable (vat_main_t * vam)
15450 {
15451   unformat_input_t *line_input = vam->input;
15452   vl_api_cop_interface_enable_disable_t *mp;
15453   u32 sw_if_index = ~0;
15454   u8 enable_disable = 1;
15455   int ret;
15456
15457   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15458     {
15459       if (unformat (line_input, "disable"))
15460         enable_disable = 0;
15461       if (unformat (line_input, "enable"))
15462         enable_disable = 1;
15463       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15464                          vam, &sw_if_index))
15465         ;
15466       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15467         ;
15468       else
15469         break;
15470     }
15471
15472   if (sw_if_index == ~0)
15473     {
15474       errmsg ("missing interface name or sw_if_index");
15475       return -99;
15476     }
15477
15478   /* Construct the API message */
15479   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15480   mp->sw_if_index = ntohl (sw_if_index);
15481   mp->enable_disable = enable_disable;
15482
15483   /* send it... */
15484   S (mp);
15485   /* Wait for the reply */
15486   W (ret);
15487   return ret;
15488 }
15489
15490 static int
15491 api_cop_whitelist_enable_disable (vat_main_t * vam)
15492 {
15493   unformat_input_t *line_input = vam->input;
15494   vl_api_cop_whitelist_enable_disable_t *mp;
15495   u32 sw_if_index = ~0;
15496   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15497   u32 fib_id = 0;
15498   int ret;
15499
15500   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15501     {
15502       if (unformat (line_input, "ip4"))
15503         ip4 = 1;
15504       else if (unformat (line_input, "ip6"))
15505         ip6 = 1;
15506       else if (unformat (line_input, "default"))
15507         default_cop = 1;
15508       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15509                          vam, &sw_if_index))
15510         ;
15511       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15512         ;
15513       else if (unformat (line_input, "fib-id %d", &fib_id))
15514         ;
15515       else
15516         break;
15517     }
15518
15519   if (sw_if_index == ~0)
15520     {
15521       errmsg ("missing interface name or sw_if_index");
15522       return -99;
15523     }
15524
15525   /* Construct the API message */
15526   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15527   mp->sw_if_index = ntohl (sw_if_index);
15528   mp->fib_id = ntohl (fib_id);
15529   mp->ip4 = ip4;
15530   mp->ip6 = ip6;
15531   mp->default_cop = default_cop;
15532
15533   /* send it... */
15534   S (mp);
15535   /* Wait for the reply */
15536   W (ret);
15537   return ret;
15538 }
15539
15540 static int
15541 api_get_node_graph (vat_main_t * vam)
15542 {
15543   vl_api_get_node_graph_t *mp;
15544   int ret;
15545
15546   M (GET_NODE_GRAPH, mp);
15547
15548   /* send it... */
15549   S (mp);
15550   /* Wait for the reply */
15551   W (ret);
15552   return ret;
15553 }
15554
15555 /* *INDENT-OFF* */
15556 /** Used for parsing LISP eids */
15557 typedef CLIB_PACKED(struct{
15558   u8 addr[16];   /**< eid address */
15559   u32 len;       /**< prefix length if IP */
15560   u8 type;      /**< type of eid */
15561 }) lisp_eid_vat_t;
15562 /* *INDENT-ON* */
15563
15564 static uword
15565 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15566 {
15567   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15568
15569   clib_memset (a, 0, sizeof (a[0]));
15570
15571   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15572     {
15573       a->type = 0;              /* ipv4 type */
15574     }
15575   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15576     {
15577       a->type = 1;              /* ipv6 type */
15578     }
15579   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15580     {
15581       a->type = 2;              /* mac type */
15582     }
15583   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15584     {
15585       a->type = 3;              /* NSH type */
15586       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15587       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15588     }
15589   else
15590     {
15591       return 0;
15592     }
15593
15594   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15595     {
15596       return 0;
15597     }
15598
15599   return 1;
15600 }
15601
15602 static int
15603 lisp_eid_size_vat (u8 type)
15604 {
15605   switch (type)
15606     {
15607     case 0:
15608       return 4;
15609     case 1:
15610       return 16;
15611     case 2:
15612       return 6;
15613     case 3:
15614       return 5;
15615     }
15616   return 0;
15617 }
15618
15619 static void
15620 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15621 {
15622   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15623 }
15624
15625 static int
15626 api_one_add_del_locator_set (vat_main_t * vam)
15627 {
15628   unformat_input_t *input = vam->input;
15629   vl_api_one_add_del_locator_set_t *mp;
15630   u8 is_add = 1;
15631   u8 *locator_set_name = NULL;
15632   u8 locator_set_name_set = 0;
15633   vl_api_local_locator_t locator, *locators = 0;
15634   u32 sw_if_index, priority, weight;
15635   u32 data_len = 0;
15636
15637   int ret;
15638   /* Parse args required to build the message */
15639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15640     {
15641       if (unformat (input, "del"))
15642         {
15643           is_add = 0;
15644         }
15645       else if (unformat (input, "locator-set %s", &locator_set_name))
15646         {
15647           locator_set_name_set = 1;
15648         }
15649       else if (unformat (input, "sw_if_index %u p %u w %u",
15650                          &sw_if_index, &priority, &weight))
15651         {
15652           locator.sw_if_index = htonl (sw_if_index);
15653           locator.priority = priority;
15654           locator.weight = weight;
15655           vec_add1 (locators, locator);
15656         }
15657       else
15658         if (unformat
15659             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15660              &sw_if_index, &priority, &weight))
15661         {
15662           locator.sw_if_index = htonl (sw_if_index);
15663           locator.priority = priority;
15664           locator.weight = weight;
15665           vec_add1 (locators, locator);
15666         }
15667       else
15668         break;
15669     }
15670
15671   if (locator_set_name_set == 0)
15672     {
15673       errmsg ("missing locator-set name");
15674       vec_free (locators);
15675       return -99;
15676     }
15677
15678   if (vec_len (locator_set_name) > 64)
15679     {
15680       errmsg ("locator-set name too long");
15681       vec_free (locator_set_name);
15682       vec_free (locators);
15683       return -99;
15684     }
15685   vec_add1 (locator_set_name, 0);
15686
15687   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15688
15689   /* Construct the API message */
15690   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15691
15692   mp->is_add = is_add;
15693   clib_memcpy (mp->locator_set_name, locator_set_name,
15694                vec_len (locator_set_name));
15695   vec_free (locator_set_name);
15696
15697   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15698   if (locators)
15699     clib_memcpy (mp->locators, locators, data_len);
15700   vec_free (locators);
15701
15702   /* send it... */
15703   S (mp);
15704
15705   /* Wait for a reply... */
15706   W (ret);
15707   return ret;
15708 }
15709
15710 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15711
15712 static int
15713 api_one_add_del_locator (vat_main_t * vam)
15714 {
15715   unformat_input_t *input = vam->input;
15716   vl_api_one_add_del_locator_t *mp;
15717   u32 tmp_if_index = ~0;
15718   u32 sw_if_index = ~0;
15719   u8 sw_if_index_set = 0;
15720   u8 sw_if_index_if_name_set = 0;
15721   u32 priority = ~0;
15722   u8 priority_set = 0;
15723   u32 weight = ~0;
15724   u8 weight_set = 0;
15725   u8 is_add = 1;
15726   u8 *locator_set_name = NULL;
15727   u8 locator_set_name_set = 0;
15728   int ret;
15729
15730   /* Parse args required to build the message */
15731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15732     {
15733       if (unformat (input, "del"))
15734         {
15735           is_add = 0;
15736         }
15737       else if (unformat (input, "locator-set %s", &locator_set_name))
15738         {
15739           locator_set_name_set = 1;
15740         }
15741       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15742                          &tmp_if_index))
15743         {
15744           sw_if_index_if_name_set = 1;
15745           sw_if_index = tmp_if_index;
15746         }
15747       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15748         {
15749           sw_if_index_set = 1;
15750           sw_if_index = tmp_if_index;
15751         }
15752       else if (unformat (input, "p %d", &priority))
15753         {
15754           priority_set = 1;
15755         }
15756       else if (unformat (input, "w %d", &weight))
15757         {
15758           weight_set = 1;
15759         }
15760       else
15761         break;
15762     }
15763
15764   if (locator_set_name_set == 0)
15765     {
15766       errmsg ("missing locator-set name");
15767       return -99;
15768     }
15769
15770   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15771     {
15772       errmsg ("missing sw_if_index");
15773       vec_free (locator_set_name);
15774       return -99;
15775     }
15776
15777   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15778     {
15779       errmsg ("cannot use both params interface name and sw_if_index");
15780       vec_free (locator_set_name);
15781       return -99;
15782     }
15783
15784   if (priority_set == 0)
15785     {
15786       errmsg ("missing locator-set priority");
15787       vec_free (locator_set_name);
15788       return -99;
15789     }
15790
15791   if (weight_set == 0)
15792     {
15793       errmsg ("missing locator-set weight");
15794       vec_free (locator_set_name);
15795       return -99;
15796     }
15797
15798   if (vec_len (locator_set_name) > 64)
15799     {
15800       errmsg ("locator-set name too long");
15801       vec_free (locator_set_name);
15802       return -99;
15803     }
15804   vec_add1 (locator_set_name, 0);
15805
15806   /* Construct the API message */
15807   M (ONE_ADD_DEL_LOCATOR, mp);
15808
15809   mp->is_add = is_add;
15810   mp->sw_if_index = ntohl (sw_if_index);
15811   mp->priority = priority;
15812   mp->weight = weight;
15813   clib_memcpy (mp->locator_set_name, locator_set_name,
15814                vec_len (locator_set_name));
15815   vec_free (locator_set_name);
15816
15817   /* send it... */
15818   S (mp);
15819
15820   /* Wait for a reply... */
15821   W (ret);
15822   return ret;
15823 }
15824
15825 #define api_lisp_add_del_locator api_one_add_del_locator
15826
15827 uword
15828 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15829 {
15830   u32 *key_id = va_arg (*args, u32 *);
15831   u8 *s = 0;
15832
15833   if (unformat (input, "%s", &s))
15834     {
15835       if (!strcmp ((char *) s, "sha1"))
15836         key_id[0] = HMAC_SHA_1_96;
15837       else if (!strcmp ((char *) s, "sha256"))
15838         key_id[0] = HMAC_SHA_256_128;
15839       else
15840         {
15841           clib_warning ("invalid key_id: '%s'", s);
15842           key_id[0] = HMAC_NO_KEY;
15843         }
15844     }
15845   else
15846     return 0;
15847
15848   vec_free (s);
15849   return 1;
15850 }
15851
15852 static int
15853 api_one_add_del_local_eid (vat_main_t * vam)
15854 {
15855   unformat_input_t *input = vam->input;
15856   vl_api_one_add_del_local_eid_t *mp;
15857   u8 is_add = 1;
15858   u8 eid_set = 0;
15859   lisp_eid_vat_t _eid, *eid = &_eid;
15860   u8 *locator_set_name = 0;
15861   u8 locator_set_name_set = 0;
15862   u32 vni = 0;
15863   u16 key_id = 0;
15864   u8 *key = 0;
15865   int ret;
15866
15867   /* Parse args required to build the message */
15868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15869     {
15870       if (unformat (input, "del"))
15871         {
15872           is_add = 0;
15873         }
15874       else if (unformat (input, "vni %d", &vni))
15875         {
15876           ;
15877         }
15878       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15879         {
15880           eid_set = 1;
15881         }
15882       else if (unformat (input, "locator-set %s", &locator_set_name))
15883         {
15884           locator_set_name_set = 1;
15885         }
15886       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15887         ;
15888       else if (unformat (input, "secret-key %_%v%_", &key))
15889         ;
15890       else
15891         break;
15892     }
15893
15894   if (locator_set_name_set == 0)
15895     {
15896       errmsg ("missing locator-set name");
15897       return -99;
15898     }
15899
15900   if (0 == eid_set)
15901     {
15902       errmsg ("EID address not set!");
15903       vec_free (locator_set_name);
15904       return -99;
15905     }
15906
15907   if (key && (0 == key_id))
15908     {
15909       errmsg ("invalid key_id!");
15910       return -99;
15911     }
15912
15913   if (vec_len (key) > 64)
15914     {
15915       errmsg ("key too long");
15916       vec_free (key);
15917       return -99;
15918     }
15919
15920   if (vec_len (locator_set_name) > 64)
15921     {
15922       errmsg ("locator-set name too long");
15923       vec_free (locator_set_name);
15924       return -99;
15925     }
15926   vec_add1 (locator_set_name, 0);
15927
15928   /* Construct the API message */
15929   M (ONE_ADD_DEL_LOCAL_EID, mp);
15930
15931   mp->is_add = is_add;
15932   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15933   mp->eid_type = eid->type;
15934   mp->prefix_len = eid->len;
15935   mp->vni = clib_host_to_net_u32 (vni);
15936   mp->key_id = clib_host_to_net_u16 (key_id);
15937   clib_memcpy (mp->locator_set_name, locator_set_name,
15938                vec_len (locator_set_name));
15939   clib_memcpy (mp->key, key, vec_len (key));
15940
15941   vec_free (locator_set_name);
15942   vec_free (key);
15943
15944   /* send it... */
15945   S (mp);
15946
15947   /* Wait for a reply... */
15948   W (ret);
15949   return ret;
15950 }
15951
15952 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15953
15954 static int
15955 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15956 {
15957   u32 dp_table = 0, vni = 0;;
15958   unformat_input_t *input = vam->input;
15959   vl_api_gpe_add_del_fwd_entry_t *mp;
15960   u8 is_add = 1;
15961   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15962   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15963   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15964   u32 action = ~0, w;
15965   ip4_address_t rmt_rloc4, lcl_rloc4;
15966   ip6_address_t rmt_rloc6, lcl_rloc6;
15967   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15968   int ret;
15969
15970   clib_memset (&rloc, 0, sizeof (rloc));
15971
15972   /* Parse args required to build the message */
15973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15974     {
15975       if (unformat (input, "del"))
15976         is_add = 0;
15977       else if (unformat (input, "add"))
15978         is_add = 1;
15979       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15980         {
15981           rmt_eid_set = 1;
15982         }
15983       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15984         {
15985           lcl_eid_set = 1;
15986         }
15987       else if (unformat (input, "vrf %d", &dp_table))
15988         ;
15989       else if (unformat (input, "bd %d", &dp_table))
15990         ;
15991       else if (unformat (input, "vni %d", &vni))
15992         ;
15993       else if (unformat (input, "w %d", &w))
15994         {
15995           if (!curr_rloc)
15996             {
15997               errmsg ("No RLOC configured for setting priority/weight!");
15998               return -99;
15999             }
16000           curr_rloc->weight = w;
16001         }
16002       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16003                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16004         {
16005           rloc.is_ip4 = 1;
16006
16007           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16008           rloc.weight = 0;
16009           vec_add1 (lcl_locs, rloc);
16010
16011           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16012           vec_add1 (rmt_locs, rloc);
16013           /* weight saved in rmt loc */
16014           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16015         }
16016       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16017                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16018         {
16019           rloc.is_ip4 = 0;
16020           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16021           rloc.weight = 0;
16022           vec_add1 (lcl_locs, rloc);
16023
16024           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16025           vec_add1 (rmt_locs, rloc);
16026           /* weight saved in rmt loc */
16027           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16028         }
16029       else if (unformat (input, "action %d", &action))
16030         {
16031           ;
16032         }
16033       else
16034         {
16035           clib_warning ("parse error '%U'", format_unformat_error, input);
16036           return -99;
16037         }
16038     }
16039
16040   if (!rmt_eid_set)
16041     {
16042       errmsg ("remote eid addresses not set");
16043       return -99;
16044     }
16045
16046   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16047     {
16048       errmsg ("eid types don't match");
16049       return -99;
16050     }
16051
16052   if (0 == rmt_locs && (u32) ~ 0 == action)
16053     {
16054       errmsg ("action not set for negative mapping");
16055       return -99;
16056     }
16057
16058   /* Construct the API message */
16059   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16060       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16061
16062   mp->is_add = is_add;
16063   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16064   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16065   mp->eid_type = rmt_eid->type;
16066   mp->dp_table = clib_host_to_net_u32 (dp_table);
16067   mp->vni = clib_host_to_net_u32 (vni);
16068   mp->rmt_len = rmt_eid->len;
16069   mp->lcl_len = lcl_eid->len;
16070   mp->action = action;
16071
16072   if (0 != rmt_locs && 0 != lcl_locs)
16073     {
16074       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16075       clib_memcpy (mp->locs, lcl_locs,
16076                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16077
16078       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16079       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16080                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16081     }
16082   vec_free (lcl_locs);
16083   vec_free (rmt_locs);
16084
16085   /* send it... */
16086   S (mp);
16087
16088   /* Wait for a reply... */
16089   W (ret);
16090   return ret;
16091 }
16092
16093 static int
16094 api_one_add_del_map_server (vat_main_t * vam)
16095 {
16096   unformat_input_t *input = vam->input;
16097   vl_api_one_add_del_map_server_t *mp;
16098   u8 is_add = 1;
16099   u8 ipv4_set = 0;
16100   u8 ipv6_set = 0;
16101   ip4_address_t ipv4;
16102   ip6_address_t ipv6;
16103   int ret;
16104
16105   /* Parse args required to build the message */
16106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16107     {
16108       if (unformat (input, "del"))
16109         {
16110           is_add = 0;
16111         }
16112       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16113         {
16114           ipv4_set = 1;
16115         }
16116       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16117         {
16118           ipv6_set = 1;
16119         }
16120       else
16121         break;
16122     }
16123
16124   if (ipv4_set && ipv6_set)
16125     {
16126       errmsg ("both eid v4 and v6 addresses set");
16127       return -99;
16128     }
16129
16130   if (!ipv4_set && !ipv6_set)
16131     {
16132       errmsg ("eid addresses not set");
16133       return -99;
16134     }
16135
16136   /* Construct the API message */
16137   M (ONE_ADD_DEL_MAP_SERVER, mp);
16138
16139   mp->is_add = is_add;
16140   if (ipv6_set)
16141     {
16142       mp->is_ipv6 = 1;
16143       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16144     }
16145   else
16146     {
16147       mp->is_ipv6 = 0;
16148       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16149     }
16150
16151   /* send it... */
16152   S (mp);
16153
16154   /* Wait for a reply... */
16155   W (ret);
16156   return ret;
16157 }
16158
16159 #define api_lisp_add_del_map_server api_one_add_del_map_server
16160
16161 static int
16162 api_one_add_del_map_resolver (vat_main_t * vam)
16163 {
16164   unformat_input_t *input = vam->input;
16165   vl_api_one_add_del_map_resolver_t *mp;
16166   u8 is_add = 1;
16167   u8 ipv4_set = 0;
16168   u8 ipv6_set = 0;
16169   ip4_address_t ipv4;
16170   ip6_address_t ipv6;
16171   int ret;
16172
16173   /* Parse args required to build the message */
16174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16175     {
16176       if (unformat (input, "del"))
16177         {
16178           is_add = 0;
16179         }
16180       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16181         {
16182           ipv4_set = 1;
16183         }
16184       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16185         {
16186           ipv6_set = 1;
16187         }
16188       else
16189         break;
16190     }
16191
16192   if (ipv4_set && ipv6_set)
16193     {
16194       errmsg ("both eid v4 and v6 addresses set");
16195       return -99;
16196     }
16197
16198   if (!ipv4_set && !ipv6_set)
16199     {
16200       errmsg ("eid addresses not set");
16201       return -99;
16202     }
16203
16204   /* Construct the API message */
16205   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16206
16207   mp->is_add = is_add;
16208   if (ipv6_set)
16209     {
16210       mp->is_ipv6 = 1;
16211       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16212     }
16213   else
16214     {
16215       mp->is_ipv6 = 0;
16216       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16217     }
16218
16219   /* send it... */
16220   S (mp);
16221
16222   /* Wait for a reply... */
16223   W (ret);
16224   return ret;
16225 }
16226
16227 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16228
16229 static int
16230 api_lisp_gpe_enable_disable (vat_main_t * vam)
16231 {
16232   unformat_input_t *input = vam->input;
16233   vl_api_gpe_enable_disable_t *mp;
16234   u8 is_set = 0;
16235   u8 is_en = 1;
16236   int ret;
16237
16238   /* Parse args required to build the message */
16239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16240     {
16241       if (unformat (input, "enable"))
16242         {
16243           is_set = 1;
16244           is_en = 1;
16245         }
16246       else if (unformat (input, "disable"))
16247         {
16248           is_set = 1;
16249           is_en = 0;
16250         }
16251       else
16252         break;
16253     }
16254
16255   if (is_set == 0)
16256     {
16257       errmsg ("Value not set");
16258       return -99;
16259     }
16260
16261   /* Construct the API message */
16262   M (GPE_ENABLE_DISABLE, mp);
16263
16264   mp->is_en = is_en;
16265
16266   /* send it... */
16267   S (mp);
16268
16269   /* Wait for a reply... */
16270   W (ret);
16271   return ret;
16272 }
16273
16274 static int
16275 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16276 {
16277   unformat_input_t *input = vam->input;
16278   vl_api_one_rloc_probe_enable_disable_t *mp;
16279   u8 is_set = 0;
16280   u8 is_en = 0;
16281   int ret;
16282
16283   /* Parse args required to build the message */
16284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16285     {
16286       if (unformat (input, "enable"))
16287         {
16288           is_set = 1;
16289           is_en = 1;
16290         }
16291       else if (unformat (input, "disable"))
16292         is_set = 1;
16293       else
16294         break;
16295     }
16296
16297   if (!is_set)
16298     {
16299       errmsg ("Value not set");
16300       return -99;
16301     }
16302
16303   /* Construct the API message */
16304   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16305
16306   mp->is_enabled = is_en;
16307
16308   /* send it... */
16309   S (mp);
16310
16311   /* Wait for a reply... */
16312   W (ret);
16313   return ret;
16314 }
16315
16316 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16317
16318 static int
16319 api_one_map_register_enable_disable (vat_main_t * vam)
16320 {
16321   unformat_input_t *input = vam->input;
16322   vl_api_one_map_register_enable_disable_t *mp;
16323   u8 is_set = 0;
16324   u8 is_en = 0;
16325   int ret;
16326
16327   /* Parse args required to build the message */
16328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16329     {
16330       if (unformat (input, "enable"))
16331         {
16332           is_set = 1;
16333           is_en = 1;
16334         }
16335       else if (unformat (input, "disable"))
16336         is_set = 1;
16337       else
16338         break;
16339     }
16340
16341   if (!is_set)
16342     {
16343       errmsg ("Value not set");
16344       return -99;
16345     }
16346
16347   /* Construct the API message */
16348   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16349
16350   mp->is_enabled = is_en;
16351
16352   /* send it... */
16353   S (mp);
16354
16355   /* Wait for a reply... */
16356   W (ret);
16357   return ret;
16358 }
16359
16360 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16361
16362 static int
16363 api_one_enable_disable (vat_main_t * vam)
16364 {
16365   unformat_input_t *input = vam->input;
16366   vl_api_one_enable_disable_t *mp;
16367   u8 is_set = 0;
16368   u8 is_en = 0;
16369   int ret;
16370
16371   /* Parse args required to build the message */
16372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16373     {
16374       if (unformat (input, "enable"))
16375         {
16376           is_set = 1;
16377           is_en = 1;
16378         }
16379       else if (unformat (input, "disable"))
16380         {
16381           is_set = 1;
16382         }
16383       else
16384         break;
16385     }
16386
16387   if (!is_set)
16388     {
16389       errmsg ("Value not set");
16390       return -99;
16391     }
16392
16393   /* Construct the API message */
16394   M (ONE_ENABLE_DISABLE, mp);
16395
16396   mp->is_en = is_en;
16397
16398   /* send it... */
16399   S (mp);
16400
16401   /* Wait for a reply... */
16402   W (ret);
16403   return ret;
16404 }
16405
16406 #define api_lisp_enable_disable api_one_enable_disable
16407
16408 static int
16409 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16410 {
16411   unformat_input_t *input = vam->input;
16412   vl_api_one_enable_disable_xtr_mode_t *mp;
16413   u8 is_set = 0;
16414   u8 is_en = 0;
16415   int ret;
16416
16417   /* Parse args required to build the message */
16418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16419     {
16420       if (unformat (input, "enable"))
16421         {
16422           is_set = 1;
16423           is_en = 1;
16424         }
16425       else if (unformat (input, "disable"))
16426         {
16427           is_set = 1;
16428         }
16429       else
16430         break;
16431     }
16432
16433   if (!is_set)
16434     {
16435       errmsg ("Value not set");
16436       return -99;
16437     }
16438
16439   /* Construct the API message */
16440   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16441
16442   mp->is_en = is_en;
16443
16444   /* send it... */
16445   S (mp);
16446
16447   /* Wait for a reply... */
16448   W (ret);
16449   return ret;
16450 }
16451
16452 static int
16453 api_one_show_xtr_mode (vat_main_t * vam)
16454 {
16455   vl_api_one_show_xtr_mode_t *mp;
16456   int ret;
16457
16458   /* Construct the API message */
16459   M (ONE_SHOW_XTR_MODE, mp);
16460
16461   /* send it... */
16462   S (mp);
16463
16464   /* Wait for a reply... */
16465   W (ret);
16466   return ret;
16467 }
16468
16469 static int
16470 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16471 {
16472   unformat_input_t *input = vam->input;
16473   vl_api_one_enable_disable_pitr_mode_t *mp;
16474   u8 is_set = 0;
16475   u8 is_en = 0;
16476   int ret;
16477
16478   /* Parse args required to build the message */
16479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16480     {
16481       if (unformat (input, "enable"))
16482         {
16483           is_set = 1;
16484           is_en = 1;
16485         }
16486       else if (unformat (input, "disable"))
16487         {
16488           is_set = 1;
16489         }
16490       else
16491         break;
16492     }
16493
16494   if (!is_set)
16495     {
16496       errmsg ("Value not set");
16497       return -99;
16498     }
16499
16500   /* Construct the API message */
16501   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16502
16503   mp->is_en = is_en;
16504
16505   /* send it... */
16506   S (mp);
16507
16508   /* Wait for a reply... */
16509   W (ret);
16510   return ret;
16511 }
16512
16513 static int
16514 api_one_show_pitr_mode (vat_main_t * vam)
16515 {
16516   vl_api_one_show_pitr_mode_t *mp;
16517   int ret;
16518
16519   /* Construct the API message */
16520   M (ONE_SHOW_PITR_MODE, mp);
16521
16522   /* send it... */
16523   S (mp);
16524
16525   /* Wait for a reply... */
16526   W (ret);
16527   return ret;
16528 }
16529
16530 static int
16531 api_one_enable_disable_petr_mode (vat_main_t * vam)
16532 {
16533   unformat_input_t *input = vam->input;
16534   vl_api_one_enable_disable_petr_mode_t *mp;
16535   u8 is_set = 0;
16536   u8 is_en = 0;
16537   int ret;
16538
16539   /* Parse args required to build the message */
16540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16541     {
16542       if (unformat (input, "enable"))
16543         {
16544           is_set = 1;
16545           is_en = 1;
16546         }
16547       else if (unformat (input, "disable"))
16548         {
16549           is_set = 1;
16550         }
16551       else
16552         break;
16553     }
16554
16555   if (!is_set)
16556     {
16557       errmsg ("Value not set");
16558       return -99;
16559     }
16560
16561   /* Construct the API message */
16562   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16563
16564   mp->is_en = is_en;
16565
16566   /* send it... */
16567   S (mp);
16568
16569   /* Wait for a reply... */
16570   W (ret);
16571   return ret;
16572 }
16573
16574 static int
16575 api_one_show_petr_mode (vat_main_t * vam)
16576 {
16577   vl_api_one_show_petr_mode_t *mp;
16578   int ret;
16579
16580   /* Construct the API message */
16581   M (ONE_SHOW_PETR_MODE, mp);
16582
16583   /* send it... */
16584   S (mp);
16585
16586   /* Wait for a reply... */
16587   W (ret);
16588   return ret;
16589 }
16590
16591 static int
16592 api_show_one_map_register_state (vat_main_t * vam)
16593 {
16594   vl_api_show_one_map_register_state_t *mp;
16595   int ret;
16596
16597   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16598
16599   /* send */
16600   S (mp);
16601
16602   /* wait for reply */
16603   W (ret);
16604   return ret;
16605 }
16606
16607 #define api_show_lisp_map_register_state api_show_one_map_register_state
16608
16609 static int
16610 api_show_one_rloc_probe_state (vat_main_t * vam)
16611 {
16612   vl_api_show_one_rloc_probe_state_t *mp;
16613   int ret;
16614
16615   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16616
16617   /* send */
16618   S (mp);
16619
16620   /* wait for reply */
16621   W (ret);
16622   return ret;
16623 }
16624
16625 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16626
16627 static int
16628 api_one_add_del_ndp_entry (vat_main_t * vam)
16629 {
16630   vl_api_one_add_del_ndp_entry_t *mp;
16631   unformat_input_t *input = vam->input;
16632   u8 is_add = 1;
16633   u8 mac_set = 0;
16634   u8 bd_set = 0;
16635   u8 ip_set = 0;
16636   u8 mac[6] = { 0, };
16637   u8 ip6[16] = { 0, };
16638   u32 bd = ~0;
16639   int ret;
16640
16641   /* Parse args required to build the message */
16642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16643     {
16644       if (unformat (input, "del"))
16645         is_add = 0;
16646       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16647         mac_set = 1;
16648       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16649         ip_set = 1;
16650       else if (unformat (input, "bd %d", &bd))
16651         bd_set = 1;
16652       else
16653         {
16654           errmsg ("parse error '%U'", format_unformat_error, input);
16655           return -99;
16656         }
16657     }
16658
16659   if (!bd_set || !ip_set || (!mac_set && is_add))
16660     {
16661       errmsg ("Missing BD, IP or MAC!");
16662       return -99;
16663     }
16664
16665   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16666   mp->is_add = is_add;
16667   clib_memcpy (mp->mac, mac, 6);
16668   mp->bd = clib_host_to_net_u32 (bd);
16669   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16670
16671   /* send */
16672   S (mp);
16673
16674   /* wait for reply */
16675   W (ret);
16676   return ret;
16677 }
16678
16679 static int
16680 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16681 {
16682   vl_api_one_add_del_l2_arp_entry_t *mp;
16683   unformat_input_t *input = vam->input;
16684   u8 is_add = 1;
16685   u8 mac_set = 0;
16686   u8 bd_set = 0;
16687   u8 ip_set = 0;
16688   u8 mac[6] = { 0, };
16689   u32 ip4 = 0, bd = ~0;
16690   int ret;
16691
16692   /* Parse args required to build the message */
16693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16694     {
16695       if (unformat (input, "del"))
16696         is_add = 0;
16697       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16698         mac_set = 1;
16699       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16700         ip_set = 1;
16701       else if (unformat (input, "bd %d", &bd))
16702         bd_set = 1;
16703       else
16704         {
16705           errmsg ("parse error '%U'", format_unformat_error, input);
16706           return -99;
16707         }
16708     }
16709
16710   if (!bd_set || !ip_set || (!mac_set && is_add))
16711     {
16712       errmsg ("Missing BD, IP or MAC!");
16713       return -99;
16714     }
16715
16716   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16717   mp->is_add = is_add;
16718   clib_memcpy (mp->mac, mac, 6);
16719   mp->bd = clib_host_to_net_u32 (bd);
16720   mp->ip4 = ip4;
16721
16722   /* send */
16723   S (mp);
16724
16725   /* wait for reply */
16726   W (ret);
16727   return ret;
16728 }
16729
16730 static int
16731 api_one_ndp_bd_get (vat_main_t * vam)
16732 {
16733   vl_api_one_ndp_bd_get_t *mp;
16734   int ret;
16735
16736   M (ONE_NDP_BD_GET, mp);
16737
16738   /* send */
16739   S (mp);
16740
16741   /* wait for reply */
16742   W (ret);
16743   return ret;
16744 }
16745
16746 static int
16747 api_one_ndp_entries_get (vat_main_t * vam)
16748 {
16749   vl_api_one_ndp_entries_get_t *mp;
16750   unformat_input_t *input = vam->input;
16751   u8 bd_set = 0;
16752   u32 bd = ~0;
16753   int ret;
16754
16755   /* Parse args required to build the message */
16756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16757     {
16758       if (unformat (input, "bd %d", &bd))
16759         bd_set = 1;
16760       else
16761         {
16762           errmsg ("parse error '%U'", format_unformat_error, input);
16763           return -99;
16764         }
16765     }
16766
16767   if (!bd_set)
16768     {
16769       errmsg ("Expected bridge domain!");
16770       return -99;
16771     }
16772
16773   M (ONE_NDP_ENTRIES_GET, mp);
16774   mp->bd = clib_host_to_net_u32 (bd);
16775
16776   /* send */
16777   S (mp);
16778
16779   /* wait for reply */
16780   W (ret);
16781   return ret;
16782 }
16783
16784 static int
16785 api_one_l2_arp_bd_get (vat_main_t * vam)
16786 {
16787   vl_api_one_l2_arp_bd_get_t *mp;
16788   int ret;
16789
16790   M (ONE_L2_ARP_BD_GET, mp);
16791
16792   /* send */
16793   S (mp);
16794
16795   /* wait for reply */
16796   W (ret);
16797   return ret;
16798 }
16799
16800 static int
16801 api_one_l2_arp_entries_get (vat_main_t * vam)
16802 {
16803   vl_api_one_l2_arp_entries_get_t *mp;
16804   unformat_input_t *input = vam->input;
16805   u8 bd_set = 0;
16806   u32 bd = ~0;
16807   int ret;
16808
16809   /* Parse args required to build the message */
16810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16811     {
16812       if (unformat (input, "bd %d", &bd))
16813         bd_set = 1;
16814       else
16815         {
16816           errmsg ("parse error '%U'", format_unformat_error, input);
16817           return -99;
16818         }
16819     }
16820
16821   if (!bd_set)
16822     {
16823       errmsg ("Expected bridge domain!");
16824       return -99;
16825     }
16826
16827   M (ONE_L2_ARP_ENTRIES_GET, mp);
16828   mp->bd = clib_host_to_net_u32 (bd);
16829
16830   /* send */
16831   S (mp);
16832
16833   /* wait for reply */
16834   W (ret);
16835   return ret;
16836 }
16837
16838 static int
16839 api_one_stats_enable_disable (vat_main_t * vam)
16840 {
16841   vl_api_one_stats_enable_disable_t *mp;
16842   unformat_input_t *input = vam->input;
16843   u8 is_set = 0;
16844   u8 is_en = 0;
16845   int ret;
16846
16847   /* Parse args required to build the message */
16848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16849     {
16850       if (unformat (input, "enable"))
16851         {
16852           is_set = 1;
16853           is_en = 1;
16854         }
16855       else if (unformat (input, "disable"))
16856         {
16857           is_set = 1;
16858         }
16859       else
16860         break;
16861     }
16862
16863   if (!is_set)
16864     {
16865       errmsg ("Value not set");
16866       return -99;
16867     }
16868
16869   M (ONE_STATS_ENABLE_DISABLE, mp);
16870   mp->is_en = is_en;
16871
16872   /* send */
16873   S (mp);
16874
16875   /* wait for reply */
16876   W (ret);
16877   return ret;
16878 }
16879
16880 static int
16881 api_show_one_stats_enable_disable (vat_main_t * vam)
16882 {
16883   vl_api_show_one_stats_enable_disable_t *mp;
16884   int ret;
16885
16886   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16887
16888   /* send */
16889   S (mp);
16890
16891   /* wait for reply */
16892   W (ret);
16893   return ret;
16894 }
16895
16896 static int
16897 api_show_one_map_request_mode (vat_main_t * vam)
16898 {
16899   vl_api_show_one_map_request_mode_t *mp;
16900   int ret;
16901
16902   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16903
16904   /* send */
16905   S (mp);
16906
16907   /* wait for reply */
16908   W (ret);
16909   return ret;
16910 }
16911
16912 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16913
16914 static int
16915 api_one_map_request_mode (vat_main_t * vam)
16916 {
16917   unformat_input_t *input = vam->input;
16918   vl_api_one_map_request_mode_t *mp;
16919   u8 mode = 0;
16920   int ret;
16921
16922   /* Parse args required to build the message */
16923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16924     {
16925       if (unformat (input, "dst-only"))
16926         mode = 0;
16927       else if (unformat (input, "src-dst"))
16928         mode = 1;
16929       else
16930         {
16931           errmsg ("parse error '%U'", format_unformat_error, input);
16932           return -99;
16933         }
16934     }
16935
16936   M (ONE_MAP_REQUEST_MODE, mp);
16937
16938   mp->mode = mode;
16939
16940   /* send */
16941   S (mp);
16942
16943   /* wait for reply */
16944   W (ret);
16945   return ret;
16946 }
16947
16948 #define api_lisp_map_request_mode api_one_map_request_mode
16949
16950 /**
16951  * Enable/disable ONE proxy ITR.
16952  *
16953  * @param vam vpp API test context
16954  * @return return code
16955  */
16956 static int
16957 api_one_pitr_set_locator_set (vat_main_t * vam)
16958 {
16959   u8 ls_name_set = 0;
16960   unformat_input_t *input = vam->input;
16961   vl_api_one_pitr_set_locator_set_t *mp;
16962   u8 is_add = 1;
16963   u8 *ls_name = 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, "del"))
16970         is_add = 0;
16971       else if (unformat (input, "locator-set %s", &ls_name))
16972         ls_name_set = 1;
16973       else
16974         {
16975           errmsg ("parse error '%U'", format_unformat_error, input);
16976           return -99;
16977         }
16978     }
16979
16980   if (!ls_name_set)
16981     {
16982       errmsg ("locator-set name not set!");
16983       return -99;
16984     }
16985
16986   M (ONE_PITR_SET_LOCATOR_SET, mp);
16987
16988   mp->is_add = is_add;
16989   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16990   vec_free (ls_name);
16991
16992   /* send */
16993   S (mp);
16994
16995   /* wait for reply */
16996   W (ret);
16997   return ret;
16998 }
16999
17000 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17001
17002 static int
17003 api_one_nsh_set_locator_set (vat_main_t * vam)
17004 {
17005   u8 ls_name_set = 0;
17006   unformat_input_t *input = vam->input;
17007   vl_api_one_nsh_set_locator_set_t *mp;
17008   u8 is_add = 1;
17009   u8 *ls_name = 0;
17010   int ret;
17011
17012   /* Parse args required to build the message */
17013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17014     {
17015       if (unformat (input, "del"))
17016         is_add = 0;
17017       else if (unformat (input, "ls %s", &ls_name))
17018         ls_name_set = 1;
17019       else
17020         {
17021           errmsg ("parse error '%U'", format_unformat_error, input);
17022           return -99;
17023         }
17024     }
17025
17026   if (!ls_name_set && is_add)
17027     {
17028       errmsg ("locator-set name not set!");
17029       return -99;
17030     }
17031
17032   M (ONE_NSH_SET_LOCATOR_SET, mp);
17033
17034   mp->is_add = is_add;
17035   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17036   vec_free (ls_name);
17037
17038   /* send */
17039   S (mp);
17040
17041   /* wait for reply */
17042   W (ret);
17043   return ret;
17044 }
17045
17046 static int
17047 api_show_one_pitr (vat_main_t * vam)
17048 {
17049   vl_api_show_one_pitr_t *mp;
17050   int ret;
17051
17052   if (!vam->json_output)
17053     {
17054       print (vam->ofp, "%=20s", "lisp status:");
17055     }
17056
17057   M (SHOW_ONE_PITR, mp);
17058   /* send it... */
17059   S (mp);
17060
17061   /* Wait for a reply... */
17062   W (ret);
17063   return ret;
17064 }
17065
17066 #define api_show_lisp_pitr api_show_one_pitr
17067
17068 static int
17069 api_one_use_petr (vat_main_t * vam)
17070 {
17071   unformat_input_t *input = vam->input;
17072   vl_api_one_use_petr_t *mp;
17073   u8 is_add = 0;
17074   ip_address_t ip;
17075   int ret;
17076
17077   clib_memset (&ip, 0, sizeof (ip));
17078
17079   /* Parse args required to build the message */
17080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17081     {
17082       if (unformat (input, "disable"))
17083         is_add = 0;
17084       else
17085         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17086         {
17087           is_add = 1;
17088           ip_addr_version (&ip) = IP4;
17089         }
17090       else
17091         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17092         {
17093           is_add = 1;
17094           ip_addr_version (&ip) = IP6;
17095         }
17096       else
17097         {
17098           errmsg ("parse error '%U'", format_unformat_error, input);
17099           return -99;
17100         }
17101     }
17102
17103   M (ONE_USE_PETR, mp);
17104
17105   mp->is_add = is_add;
17106   if (is_add)
17107     {
17108       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17109       if (mp->is_ip4)
17110         clib_memcpy (mp->address, &ip, 4);
17111       else
17112         clib_memcpy (mp->address, &ip, 16);
17113     }
17114
17115   /* send */
17116   S (mp);
17117
17118   /* wait for reply */
17119   W (ret);
17120   return ret;
17121 }
17122
17123 #define api_lisp_use_petr api_one_use_petr
17124
17125 static int
17126 api_show_one_nsh_mapping (vat_main_t * vam)
17127 {
17128   vl_api_show_one_use_petr_t *mp;
17129   int ret;
17130
17131   if (!vam->json_output)
17132     {
17133       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17134     }
17135
17136   M (SHOW_ONE_NSH_MAPPING, mp);
17137   /* send it... */
17138   S (mp);
17139
17140   /* Wait for a reply... */
17141   W (ret);
17142   return ret;
17143 }
17144
17145 static int
17146 api_show_one_use_petr (vat_main_t * vam)
17147 {
17148   vl_api_show_one_use_petr_t *mp;
17149   int ret;
17150
17151   if (!vam->json_output)
17152     {
17153       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17154     }
17155
17156   M (SHOW_ONE_USE_PETR, mp);
17157   /* send it... */
17158   S (mp);
17159
17160   /* Wait for a reply... */
17161   W (ret);
17162   return ret;
17163 }
17164
17165 #define api_show_lisp_use_petr api_show_one_use_petr
17166
17167 /**
17168  * Add/delete mapping between vni and vrf
17169  */
17170 static int
17171 api_one_eid_table_add_del_map (vat_main_t * vam)
17172 {
17173   unformat_input_t *input = vam->input;
17174   vl_api_one_eid_table_add_del_map_t *mp;
17175   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17176   u32 vni, vrf, bd_index;
17177   int ret;
17178
17179   /* Parse args required to build the message */
17180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17181     {
17182       if (unformat (input, "del"))
17183         is_add = 0;
17184       else if (unformat (input, "vrf %d", &vrf))
17185         vrf_set = 1;
17186       else if (unformat (input, "bd_index %d", &bd_index))
17187         bd_index_set = 1;
17188       else if (unformat (input, "vni %d", &vni))
17189         vni_set = 1;
17190       else
17191         break;
17192     }
17193
17194   if (!vni_set || (!vrf_set && !bd_index_set))
17195     {
17196       errmsg ("missing arguments!");
17197       return -99;
17198     }
17199
17200   if (vrf_set && bd_index_set)
17201     {
17202       errmsg ("error: both vrf and bd entered!");
17203       return -99;
17204     }
17205
17206   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17207
17208   mp->is_add = is_add;
17209   mp->vni = htonl (vni);
17210   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17211   mp->is_l2 = bd_index_set;
17212
17213   /* send */
17214   S (mp);
17215
17216   /* wait for reply */
17217   W (ret);
17218   return ret;
17219 }
17220
17221 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17222
17223 uword
17224 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17225 {
17226   u32 *action = va_arg (*args, u32 *);
17227   u8 *s = 0;
17228
17229   if (unformat (input, "%s", &s))
17230     {
17231       if (!strcmp ((char *) s, "no-action"))
17232         action[0] = 0;
17233       else if (!strcmp ((char *) s, "natively-forward"))
17234         action[0] = 1;
17235       else if (!strcmp ((char *) s, "send-map-request"))
17236         action[0] = 2;
17237       else if (!strcmp ((char *) s, "drop"))
17238         action[0] = 3;
17239       else
17240         {
17241           clib_warning ("invalid action: '%s'", s);
17242           action[0] = 3;
17243         }
17244     }
17245   else
17246     return 0;
17247
17248   vec_free (s);
17249   return 1;
17250 }
17251
17252 /**
17253  * Add/del remote mapping to/from ONE control plane
17254  *
17255  * @param vam vpp API test context
17256  * @return return code
17257  */
17258 static int
17259 api_one_add_del_remote_mapping (vat_main_t * vam)
17260 {
17261   unformat_input_t *input = vam->input;
17262   vl_api_one_add_del_remote_mapping_t *mp;
17263   u32 vni = 0;
17264   lisp_eid_vat_t _eid, *eid = &_eid;
17265   lisp_eid_vat_t _seid, *seid = &_seid;
17266   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17267   u32 action = ~0, p, w, data_len;
17268   ip4_address_t rloc4;
17269   ip6_address_t rloc6;
17270   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17271   int ret;
17272
17273   clib_memset (&rloc, 0, sizeof (rloc));
17274
17275   /* Parse args required to build the message */
17276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17277     {
17278       if (unformat (input, "del-all"))
17279         {
17280           del_all = 1;
17281         }
17282       else if (unformat (input, "del"))
17283         {
17284           is_add = 0;
17285         }
17286       else if (unformat (input, "add"))
17287         {
17288           is_add = 1;
17289         }
17290       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17291         {
17292           eid_set = 1;
17293         }
17294       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17295         {
17296           seid_set = 1;
17297         }
17298       else if (unformat (input, "vni %d", &vni))
17299         {
17300           ;
17301         }
17302       else if (unformat (input, "p %d w %d", &p, &w))
17303         {
17304           if (!curr_rloc)
17305             {
17306               errmsg ("No RLOC configured for setting priority/weight!");
17307               return -99;
17308             }
17309           curr_rloc->priority = p;
17310           curr_rloc->weight = w;
17311         }
17312       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17313         {
17314           rloc.is_ip4 = 1;
17315           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17316           vec_add1 (rlocs, rloc);
17317           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17318         }
17319       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17320         {
17321           rloc.is_ip4 = 0;
17322           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17323           vec_add1 (rlocs, rloc);
17324           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17325         }
17326       else if (unformat (input, "action %U",
17327                          unformat_negative_mapping_action, &action))
17328         {
17329           ;
17330         }
17331       else
17332         {
17333           clib_warning ("parse error '%U'", format_unformat_error, input);
17334           return -99;
17335         }
17336     }
17337
17338   if (0 == eid_set)
17339     {
17340       errmsg ("missing params!");
17341       return -99;
17342     }
17343
17344   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17345     {
17346       errmsg ("no action set for negative map-reply!");
17347       return -99;
17348     }
17349
17350   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17351
17352   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17353   mp->is_add = is_add;
17354   mp->vni = htonl (vni);
17355   mp->action = (u8) action;
17356   mp->is_src_dst = seid_set;
17357   mp->eid_len = eid->len;
17358   mp->seid_len = seid->len;
17359   mp->del_all = del_all;
17360   mp->eid_type = eid->type;
17361   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17362   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17363
17364   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17365   clib_memcpy (mp->rlocs, rlocs, data_len);
17366   vec_free (rlocs);
17367
17368   /* send it... */
17369   S (mp);
17370
17371   /* Wait for a reply... */
17372   W (ret);
17373   return ret;
17374 }
17375
17376 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17377
17378 /**
17379  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17380  * forwarding entries in data-plane accordingly.
17381  *
17382  * @param vam vpp API test context
17383  * @return return code
17384  */
17385 static int
17386 api_one_add_del_adjacency (vat_main_t * vam)
17387 {
17388   unformat_input_t *input = vam->input;
17389   vl_api_one_add_del_adjacency_t *mp;
17390   u32 vni = 0;
17391   ip4_address_t leid4, reid4;
17392   ip6_address_t leid6, reid6;
17393   u8 reid_mac[6] = { 0 };
17394   u8 leid_mac[6] = { 0 };
17395   u8 reid_type, leid_type;
17396   u32 leid_len = 0, reid_len = 0, len;
17397   u8 is_add = 1;
17398   int ret;
17399
17400   leid_type = reid_type = (u8) ~ 0;
17401
17402   /* Parse args required to build the message */
17403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17404     {
17405       if (unformat (input, "del"))
17406         {
17407           is_add = 0;
17408         }
17409       else if (unformat (input, "add"))
17410         {
17411           is_add = 1;
17412         }
17413       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17414                          &reid4, &len))
17415         {
17416           reid_type = 0;        /* ipv4 */
17417           reid_len = len;
17418         }
17419       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17420                          &reid6, &len))
17421         {
17422           reid_type = 1;        /* ipv6 */
17423           reid_len = len;
17424         }
17425       else if (unformat (input, "reid %U", unformat_ethernet_address,
17426                          reid_mac))
17427         {
17428           reid_type = 2;        /* mac */
17429         }
17430       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17431                          &leid4, &len))
17432         {
17433           leid_type = 0;        /* ipv4 */
17434           leid_len = len;
17435         }
17436       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17437                          &leid6, &len))
17438         {
17439           leid_type = 1;        /* ipv6 */
17440           leid_len = len;
17441         }
17442       else if (unformat (input, "leid %U", unformat_ethernet_address,
17443                          leid_mac))
17444         {
17445           leid_type = 2;        /* mac */
17446         }
17447       else if (unformat (input, "vni %d", &vni))
17448         {
17449           ;
17450         }
17451       else
17452         {
17453           errmsg ("parse error '%U'", format_unformat_error, input);
17454           return -99;
17455         }
17456     }
17457
17458   if ((u8) ~ 0 == reid_type)
17459     {
17460       errmsg ("missing params!");
17461       return -99;
17462     }
17463
17464   if (leid_type != reid_type)
17465     {
17466       errmsg ("remote and local EIDs are of different types!");
17467       return -99;
17468     }
17469
17470   M (ONE_ADD_DEL_ADJACENCY, mp);
17471   mp->is_add = is_add;
17472   mp->vni = htonl (vni);
17473   mp->leid_len = leid_len;
17474   mp->reid_len = reid_len;
17475   mp->eid_type = reid_type;
17476
17477   switch (mp->eid_type)
17478     {
17479     case 0:
17480       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17481       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17482       break;
17483     case 1:
17484       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17485       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17486       break;
17487     case 2:
17488       clib_memcpy (mp->leid, leid_mac, 6);
17489       clib_memcpy (mp->reid, reid_mac, 6);
17490       break;
17491     default:
17492       errmsg ("unknown EID type %d!", mp->eid_type);
17493       return 0;
17494     }
17495
17496   /* send it... */
17497   S (mp);
17498
17499   /* Wait for a reply... */
17500   W (ret);
17501   return ret;
17502 }
17503
17504 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17505
17506 uword
17507 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17508 {
17509   u32 *mode = va_arg (*args, u32 *);
17510
17511   if (unformat (input, "lisp"))
17512     *mode = 0;
17513   else if (unformat (input, "vxlan"))
17514     *mode = 1;
17515   else
17516     return 0;
17517
17518   return 1;
17519 }
17520
17521 static int
17522 api_gpe_get_encap_mode (vat_main_t * vam)
17523 {
17524   vl_api_gpe_get_encap_mode_t *mp;
17525   int ret;
17526
17527   /* Construct the API message */
17528   M (GPE_GET_ENCAP_MODE, mp);
17529
17530   /* send it... */
17531   S (mp);
17532
17533   /* Wait for a reply... */
17534   W (ret);
17535   return ret;
17536 }
17537
17538 static int
17539 api_gpe_set_encap_mode (vat_main_t * vam)
17540 {
17541   unformat_input_t *input = vam->input;
17542   vl_api_gpe_set_encap_mode_t *mp;
17543   int ret;
17544   u32 mode = 0;
17545
17546   /* Parse args required to build the message */
17547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17548     {
17549       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17550         ;
17551       else
17552         break;
17553     }
17554
17555   /* Construct the API message */
17556   M (GPE_SET_ENCAP_MODE, mp);
17557
17558   mp->mode = mode;
17559
17560   /* send it... */
17561   S (mp);
17562
17563   /* Wait for a reply... */
17564   W (ret);
17565   return ret;
17566 }
17567
17568 static int
17569 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17570 {
17571   unformat_input_t *input = vam->input;
17572   vl_api_gpe_add_del_iface_t *mp;
17573   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17574   u32 dp_table = 0, vni = 0;
17575   int ret;
17576
17577   /* Parse args required to build the message */
17578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17579     {
17580       if (unformat (input, "up"))
17581         {
17582           action_set = 1;
17583           is_add = 1;
17584         }
17585       else if (unformat (input, "down"))
17586         {
17587           action_set = 1;
17588           is_add = 0;
17589         }
17590       else if (unformat (input, "table_id %d", &dp_table))
17591         {
17592           dp_table_set = 1;
17593         }
17594       else if (unformat (input, "bd_id %d", &dp_table))
17595         {
17596           dp_table_set = 1;
17597           is_l2 = 1;
17598         }
17599       else if (unformat (input, "vni %d", &vni))
17600         {
17601           vni_set = 1;
17602         }
17603       else
17604         break;
17605     }
17606
17607   if (action_set == 0)
17608     {
17609       errmsg ("Action not set");
17610       return -99;
17611     }
17612   if (dp_table_set == 0 || vni_set == 0)
17613     {
17614       errmsg ("vni and dp_table must be set");
17615       return -99;
17616     }
17617
17618   /* Construct the API message */
17619   M (GPE_ADD_DEL_IFACE, mp);
17620
17621   mp->is_add = is_add;
17622   mp->dp_table = clib_host_to_net_u32 (dp_table);
17623   mp->is_l2 = is_l2;
17624   mp->vni = clib_host_to_net_u32 (vni);
17625
17626   /* send it... */
17627   S (mp);
17628
17629   /* Wait for a reply... */
17630   W (ret);
17631   return ret;
17632 }
17633
17634 static int
17635 api_one_map_register_fallback_threshold (vat_main_t * vam)
17636 {
17637   unformat_input_t *input = vam->input;
17638   vl_api_one_map_register_fallback_threshold_t *mp;
17639   u32 value = 0;
17640   u8 is_set = 0;
17641   int ret;
17642
17643   /* Parse args required to build the message */
17644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17645     {
17646       if (unformat (input, "%u", &value))
17647         is_set = 1;
17648       else
17649         {
17650           clib_warning ("parse error '%U'", format_unformat_error, input);
17651           return -99;
17652         }
17653     }
17654
17655   if (!is_set)
17656     {
17657       errmsg ("fallback threshold value is missing!");
17658       return -99;
17659     }
17660
17661   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17662   mp->value = clib_host_to_net_u32 (value);
17663
17664   /* send it... */
17665   S (mp);
17666
17667   /* Wait for a reply... */
17668   W (ret);
17669   return ret;
17670 }
17671
17672 static int
17673 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17674 {
17675   vl_api_show_one_map_register_fallback_threshold_t *mp;
17676   int ret;
17677
17678   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17679
17680   /* send it... */
17681   S (mp);
17682
17683   /* Wait for a reply... */
17684   W (ret);
17685   return ret;
17686 }
17687
17688 uword
17689 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17690 {
17691   u32 *proto = va_arg (*args, u32 *);
17692
17693   if (unformat (input, "udp"))
17694     *proto = 1;
17695   else if (unformat (input, "api"))
17696     *proto = 2;
17697   else
17698     return 0;
17699
17700   return 1;
17701 }
17702
17703 static int
17704 api_one_set_transport_protocol (vat_main_t * vam)
17705 {
17706   unformat_input_t *input = vam->input;
17707   vl_api_one_set_transport_protocol_t *mp;
17708   u8 is_set = 0;
17709   u32 protocol = 0;
17710   int ret;
17711
17712   /* Parse args required to build the message */
17713   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17714     {
17715       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17716         is_set = 1;
17717       else
17718         {
17719           clib_warning ("parse error '%U'", format_unformat_error, input);
17720           return -99;
17721         }
17722     }
17723
17724   if (!is_set)
17725     {
17726       errmsg ("Transport protocol missing!");
17727       return -99;
17728     }
17729
17730   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17731   mp->protocol = (u8) protocol;
17732
17733   /* send it... */
17734   S (mp);
17735
17736   /* Wait for a reply... */
17737   W (ret);
17738   return ret;
17739 }
17740
17741 static int
17742 api_one_get_transport_protocol (vat_main_t * vam)
17743 {
17744   vl_api_one_get_transport_protocol_t *mp;
17745   int ret;
17746
17747   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17748
17749   /* send it... */
17750   S (mp);
17751
17752   /* Wait for a reply... */
17753   W (ret);
17754   return ret;
17755 }
17756
17757 static int
17758 api_one_map_register_set_ttl (vat_main_t * vam)
17759 {
17760   unformat_input_t *input = vam->input;
17761   vl_api_one_map_register_set_ttl_t *mp;
17762   u32 ttl = 0;
17763   u8 is_set = 0;
17764   int ret;
17765
17766   /* Parse args required to build the message */
17767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17768     {
17769       if (unformat (input, "%u", &ttl))
17770         is_set = 1;
17771       else
17772         {
17773           clib_warning ("parse error '%U'", format_unformat_error, input);
17774           return -99;
17775         }
17776     }
17777
17778   if (!is_set)
17779     {
17780       errmsg ("TTL value missing!");
17781       return -99;
17782     }
17783
17784   M (ONE_MAP_REGISTER_SET_TTL, mp);
17785   mp->ttl = clib_host_to_net_u32 (ttl);
17786
17787   /* send it... */
17788   S (mp);
17789
17790   /* Wait for a reply... */
17791   W (ret);
17792   return ret;
17793 }
17794
17795 static int
17796 api_show_one_map_register_ttl (vat_main_t * vam)
17797 {
17798   vl_api_show_one_map_register_ttl_t *mp;
17799   int ret;
17800
17801   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17802
17803   /* send it... */
17804   S (mp);
17805
17806   /* Wait for a reply... */
17807   W (ret);
17808   return ret;
17809 }
17810
17811 /**
17812  * Add/del map request itr rlocs from ONE control plane and updates
17813  *
17814  * @param vam vpp API test context
17815  * @return return code
17816  */
17817 static int
17818 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17819 {
17820   unformat_input_t *input = vam->input;
17821   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17822   u8 *locator_set_name = 0;
17823   u8 locator_set_name_set = 0;
17824   u8 is_add = 1;
17825   int ret;
17826
17827   /* Parse args required to build the message */
17828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17829     {
17830       if (unformat (input, "del"))
17831         {
17832           is_add = 0;
17833         }
17834       else if (unformat (input, "%_%v%_", &locator_set_name))
17835         {
17836           locator_set_name_set = 1;
17837         }
17838       else
17839         {
17840           clib_warning ("parse error '%U'", format_unformat_error, input);
17841           return -99;
17842         }
17843     }
17844
17845   if (is_add && !locator_set_name_set)
17846     {
17847       errmsg ("itr-rloc is not set!");
17848       return -99;
17849     }
17850
17851   if (is_add && vec_len (locator_set_name) > 64)
17852     {
17853       errmsg ("itr-rloc locator-set name too long");
17854       vec_free (locator_set_name);
17855       return -99;
17856     }
17857
17858   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17859   mp->is_add = is_add;
17860   if (is_add)
17861     {
17862       clib_memcpy (mp->locator_set_name, locator_set_name,
17863                    vec_len (locator_set_name));
17864     }
17865   else
17866     {
17867       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17868     }
17869   vec_free (locator_set_name);
17870
17871   /* send it... */
17872   S (mp);
17873
17874   /* Wait for a reply... */
17875   W (ret);
17876   return ret;
17877 }
17878
17879 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17880
17881 static int
17882 api_one_locator_dump (vat_main_t * vam)
17883 {
17884   unformat_input_t *input = vam->input;
17885   vl_api_one_locator_dump_t *mp;
17886   vl_api_control_ping_t *mp_ping;
17887   u8 is_index_set = 0, is_name_set = 0;
17888   u8 *ls_name = 0;
17889   u32 ls_index = ~0;
17890   int ret;
17891
17892   /* Parse args required to build the message */
17893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17894     {
17895       if (unformat (input, "ls_name %_%v%_", &ls_name))
17896         {
17897           is_name_set = 1;
17898         }
17899       else if (unformat (input, "ls_index %d", &ls_index))
17900         {
17901           is_index_set = 1;
17902         }
17903       else
17904         {
17905           errmsg ("parse error '%U'", format_unformat_error, input);
17906           return -99;
17907         }
17908     }
17909
17910   if (!is_index_set && !is_name_set)
17911     {
17912       errmsg ("error: expected one of index or name!");
17913       return -99;
17914     }
17915
17916   if (is_index_set && is_name_set)
17917     {
17918       errmsg ("error: only one param expected!");
17919       return -99;
17920     }
17921
17922   if (vec_len (ls_name) > 62)
17923     {
17924       errmsg ("error: locator set name too long!");
17925       return -99;
17926     }
17927
17928   if (!vam->json_output)
17929     {
17930       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17931     }
17932
17933   M (ONE_LOCATOR_DUMP, mp);
17934   mp->is_index_set = is_index_set;
17935
17936   if (is_index_set)
17937     mp->ls_index = clib_host_to_net_u32 (ls_index);
17938   else
17939     {
17940       vec_add1 (ls_name, 0);
17941       strncpy ((char *) mp->ls_name, (char *) ls_name,
17942                sizeof (mp->ls_name) - 1);
17943     }
17944
17945   /* send it... */
17946   S (mp);
17947
17948   /* Use a control ping for synchronization */
17949   MPING (CONTROL_PING, mp_ping);
17950   S (mp_ping);
17951
17952   /* Wait for a reply... */
17953   W (ret);
17954   return ret;
17955 }
17956
17957 #define api_lisp_locator_dump api_one_locator_dump
17958
17959 static int
17960 api_one_locator_set_dump (vat_main_t * vam)
17961 {
17962   vl_api_one_locator_set_dump_t *mp;
17963   vl_api_control_ping_t *mp_ping;
17964   unformat_input_t *input = vam->input;
17965   u8 filter = 0;
17966   int ret;
17967
17968   /* Parse args required to build the message */
17969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17970     {
17971       if (unformat (input, "local"))
17972         {
17973           filter = 1;
17974         }
17975       else if (unformat (input, "remote"))
17976         {
17977           filter = 2;
17978         }
17979       else
17980         {
17981           errmsg ("parse error '%U'", format_unformat_error, input);
17982           return -99;
17983         }
17984     }
17985
17986   if (!vam->json_output)
17987     {
17988       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17989     }
17990
17991   M (ONE_LOCATOR_SET_DUMP, mp);
17992
17993   mp->filter = filter;
17994
17995   /* send it... */
17996   S (mp);
17997
17998   /* Use a control ping for synchronization */
17999   MPING (CONTROL_PING, mp_ping);
18000   S (mp_ping);
18001
18002   /* Wait for a reply... */
18003   W (ret);
18004   return ret;
18005 }
18006
18007 #define api_lisp_locator_set_dump api_one_locator_set_dump
18008
18009 static int
18010 api_one_eid_table_map_dump (vat_main_t * vam)
18011 {
18012   u8 is_l2 = 0;
18013   u8 mode_set = 0;
18014   unformat_input_t *input = vam->input;
18015   vl_api_one_eid_table_map_dump_t *mp;
18016   vl_api_control_ping_t *mp_ping;
18017   int ret;
18018
18019   /* Parse args required to build the message */
18020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18021     {
18022       if (unformat (input, "l2"))
18023         {
18024           is_l2 = 1;
18025           mode_set = 1;
18026         }
18027       else if (unformat (input, "l3"))
18028         {
18029           is_l2 = 0;
18030           mode_set = 1;
18031         }
18032       else
18033         {
18034           errmsg ("parse error '%U'", format_unformat_error, input);
18035           return -99;
18036         }
18037     }
18038
18039   if (!mode_set)
18040     {
18041       errmsg ("expected one of 'l2' or 'l3' parameter!");
18042       return -99;
18043     }
18044
18045   if (!vam->json_output)
18046     {
18047       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18048     }
18049
18050   M (ONE_EID_TABLE_MAP_DUMP, mp);
18051   mp->is_l2 = is_l2;
18052
18053   /* send it... */
18054   S (mp);
18055
18056   /* Use a control ping for synchronization */
18057   MPING (CONTROL_PING, mp_ping);
18058   S (mp_ping);
18059
18060   /* Wait for a reply... */
18061   W (ret);
18062   return ret;
18063 }
18064
18065 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18066
18067 static int
18068 api_one_eid_table_vni_dump (vat_main_t * vam)
18069 {
18070   vl_api_one_eid_table_vni_dump_t *mp;
18071   vl_api_control_ping_t *mp_ping;
18072   int ret;
18073
18074   if (!vam->json_output)
18075     {
18076       print (vam->ofp, "VNI");
18077     }
18078
18079   M (ONE_EID_TABLE_VNI_DUMP, mp);
18080
18081   /* send it... */
18082   S (mp);
18083
18084   /* Use a control ping for synchronization */
18085   MPING (CONTROL_PING, mp_ping);
18086   S (mp_ping);
18087
18088   /* Wait for a reply... */
18089   W (ret);
18090   return ret;
18091 }
18092
18093 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18094
18095 static int
18096 api_one_eid_table_dump (vat_main_t * vam)
18097 {
18098   unformat_input_t *i = vam->input;
18099   vl_api_one_eid_table_dump_t *mp;
18100   vl_api_control_ping_t *mp_ping;
18101   struct in_addr ip4;
18102   struct in6_addr ip6;
18103   u8 mac[6];
18104   u8 eid_type = ~0, eid_set = 0;
18105   u32 prefix_length = ~0, t, vni = 0;
18106   u8 filter = 0;
18107   int ret;
18108   lisp_nsh_api_t nsh;
18109
18110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18111     {
18112       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18113         {
18114           eid_set = 1;
18115           eid_type = 0;
18116           prefix_length = t;
18117         }
18118       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18119         {
18120           eid_set = 1;
18121           eid_type = 1;
18122           prefix_length = t;
18123         }
18124       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18125         {
18126           eid_set = 1;
18127           eid_type = 2;
18128         }
18129       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18130         {
18131           eid_set = 1;
18132           eid_type = 3;
18133         }
18134       else if (unformat (i, "vni %d", &t))
18135         {
18136           vni = t;
18137         }
18138       else if (unformat (i, "local"))
18139         {
18140           filter = 1;
18141         }
18142       else if (unformat (i, "remote"))
18143         {
18144           filter = 2;
18145         }
18146       else
18147         {
18148           errmsg ("parse error '%U'", format_unformat_error, i);
18149           return -99;
18150         }
18151     }
18152
18153   if (!vam->json_output)
18154     {
18155       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18156              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18157     }
18158
18159   M (ONE_EID_TABLE_DUMP, mp);
18160
18161   mp->filter = filter;
18162   if (eid_set)
18163     {
18164       mp->eid_set = 1;
18165       mp->vni = htonl (vni);
18166       mp->eid_type = eid_type;
18167       switch (eid_type)
18168         {
18169         case 0:
18170           mp->prefix_length = prefix_length;
18171           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18172           break;
18173         case 1:
18174           mp->prefix_length = prefix_length;
18175           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18176           break;
18177         case 2:
18178           clib_memcpy (mp->eid, mac, sizeof (mac));
18179           break;
18180         case 3:
18181           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18182           break;
18183         default:
18184           errmsg ("unknown EID type %d!", eid_type);
18185           return -99;
18186         }
18187     }
18188
18189   /* send it... */
18190   S (mp);
18191
18192   /* Use a control ping for synchronization */
18193   MPING (CONTROL_PING, mp_ping);
18194   S (mp_ping);
18195
18196   /* Wait for a reply... */
18197   W (ret);
18198   return ret;
18199 }
18200
18201 #define api_lisp_eid_table_dump api_one_eid_table_dump
18202
18203 static int
18204 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18205 {
18206   unformat_input_t *i = vam->input;
18207   vl_api_gpe_fwd_entries_get_t *mp;
18208   u8 vni_set = 0;
18209   u32 vni = ~0;
18210   int ret;
18211
18212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18213     {
18214       if (unformat (i, "vni %d", &vni))
18215         {
18216           vni_set = 1;
18217         }
18218       else
18219         {
18220           errmsg ("parse error '%U'", format_unformat_error, i);
18221           return -99;
18222         }
18223     }
18224
18225   if (!vni_set)
18226     {
18227       errmsg ("vni not set!");
18228       return -99;
18229     }
18230
18231   if (!vam->json_output)
18232     {
18233       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18234              "leid", "reid");
18235     }
18236
18237   M (GPE_FWD_ENTRIES_GET, mp);
18238   mp->vni = clib_host_to_net_u32 (vni);
18239
18240   /* send it... */
18241   S (mp);
18242
18243   /* Wait for a reply... */
18244   W (ret);
18245   return ret;
18246 }
18247
18248 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18249 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18250 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18251 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18252 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18253 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18254 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18255 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18256
18257 static int
18258 api_one_adjacencies_get (vat_main_t * vam)
18259 {
18260   unformat_input_t *i = vam->input;
18261   vl_api_one_adjacencies_get_t *mp;
18262   u8 vni_set = 0;
18263   u32 vni = ~0;
18264   int ret;
18265
18266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18267     {
18268       if (unformat (i, "vni %d", &vni))
18269         {
18270           vni_set = 1;
18271         }
18272       else
18273         {
18274           errmsg ("parse error '%U'", format_unformat_error, i);
18275           return -99;
18276         }
18277     }
18278
18279   if (!vni_set)
18280     {
18281       errmsg ("vni not set!");
18282       return -99;
18283     }
18284
18285   if (!vam->json_output)
18286     {
18287       print (vam->ofp, "%s %40s", "leid", "reid");
18288     }
18289
18290   M (ONE_ADJACENCIES_GET, mp);
18291   mp->vni = clib_host_to_net_u32 (vni);
18292
18293   /* send it... */
18294   S (mp);
18295
18296   /* Wait for a reply... */
18297   W (ret);
18298   return ret;
18299 }
18300
18301 #define api_lisp_adjacencies_get api_one_adjacencies_get
18302
18303 static int
18304 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18305 {
18306   unformat_input_t *i = vam->input;
18307   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18308   int ret;
18309   u8 ip_family_set = 0, is_ip4 = 1;
18310
18311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18312     {
18313       if (unformat (i, "ip4"))
18314         {
18315           ip_family_set = 1;
18316           is_ip4 = 1;
18317         }
18318       else if (unformat (i, "ip6"))
18319         {
18320           ip_family_set = 1;
18321           is_ip4 = 0;
18322         }
18323       else
18324         {
18325           errmsg ("parse error '%U'", format_unformat_error, i);
18326           return -99;
18327         }
18328     }
18329
18330   if (!ip_family_set)
18331     {
18332       errmsg ("ip family not set!");
18333       return -99;
18334     }
18335
18336   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18337   mp->is_ip4 = is_ip4;
18338
18339   /* send it... */
18340   S (mp);
18341
18342   /* Wait for a reply... */
18343   W (ret);
18344   return ret;
18345 }
18346
18347 static int
18348 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18349 {
18350   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18351   int ret;
18352
18353   if (!vam->json_output)
18354     {
18355       print (vam->ofp, "VNIs");
18356     }
18357
18358   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18359
18360   /* send it... */
18361   S (mp);
18362
18363   /* Wait for a reply... */
18364   W (ret);
18365   return ret;
18366 }
18367
18368 static int
18369 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18370 {
18371   unformat_input_t *i = vam->input;
18372   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18373   int ret = 0;
18374   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18375   struct in_addr ip4;
18376   struct in6_addr ip6;
18377   u32 table_id = 0, nh_sw_if_index = ~0;
18378
18379   clib_memset (&ip4, 0, sizeof (ip4));
18380   clib_memset (&ip6, 0, sizeof (ip6));
18381
18382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18383     {
18384       if (unformat (i, "del"))
18385         is_add = 0;
18386       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18387                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18388         {
18389           ip_set = 1;
18390           is_ip4 = 1;
18391         }
18392       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18393                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18394         {
18395           ip_set = 1;
18396           is_ip4 = 0;
18397         }
18398       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18399         {
18400           ip_set = 1;
18401           is_ip4 = 1;
18402           nh_sw_if_index = ~0;
18403         }
18404       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18405         {
18406           ip_set = 1;
18407           is_ip4 = 0;
18408           nh_sw_if_index = ~0;
18409         }
18410       else if (unformat (i, "table %d", &table_id))
18411         ;
18412       else
18413         {
18414           errmsg ("parse error '%U'", format_unformat_error, i);
18415           return -99;
18416         }
18417     }
18418
18419   if (!ip_set)
18420     {
18421       errmsg ("nh addr not set!");
18422       return -99;
18423     }
18424
18425   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18426   mp->is_add = is_add;
18427   mp->table_id = clib_host_to_net_u32 (table_id);
18428   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18429   mp->is_ip4 = is_ip4;
18430   if (is_ip4)
18431     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18432   else
18433     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18434
18435   /* send it... */
18436   S (mp);
18437
18438   /* Wait for a reply... */
18439   W (ret);
18440   return ret;
18441 }
18442
18443 static int
18444 api_one_map_server_dump (vat_main_t * vam)
18445 {
18446   vl_api_one_map_server_dump_t *mp;
18447   vl_api_control_ping_t *mp_ping;
18448   int ret;
18449
18450   if (!vam->json_output)
18451     {
18452       print (vam->ofp, "%=20s", "Map server");
18453     }
18454
18455   M (ONE_MAP_SERVER_DUMP, mp);
18456   /* send it... */
18457   S (mp);
18458
18459   /* Use a control ping for synchronization */
18460   MPING (CONTROL_PING, mp_ping);
18461   S (mp_ping);
18462
18463   /* Wait for a reply... */
18464   W (ret);
18465   return ret;
18466 }
18467
18468 #define api_lisp_map_server_dump api_one_map_server_dump
18469
18470 static int
18471 api_one_map_resolver_dump (vat_main_t * vam)
18472 {
18473   vl_api_one_map_resolver_dump_t *mp;
18474   vl_api_control_ping_t *mp_ping;
18475   int ret;
18476
18477   if (!vam->json_output)
18478     {
18479       print (vam->ofp, "%=20s", "Map resolver");
18480     }
18481
18482   M (ONE_MAP_RESOLVER_DUMP, mp);
18483   /* send it... */
18484   S (mp);
18485
18486   /* Use a control ping for synchronization */
18487   MPING (CONTROL_PING, mp_ping);
18488   S (mp_ping);
18489
18490   /* Wait for a reply... */
18491   W (ret);
18492   return ret;
18493 }
18494
18495 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18496
18497 static int
18498 api_one_stats_flush (vat_main_t * vam)
18499 {
18500   vl_api_one_stats_flush_t *mp;
18501   int ret = 0;
18502
18503   M (ONE_STATS_FLUSH, mp);
18504   S (mp);
18505   W (ret);
18506   return ret;
18507 }
18508
18509 static int
18510 api_one_stats_dump (vat_main_t * vam)
18511 {
18512   vl_api_one_stats_dump_t *mp;
18513   vl_api_control_ping_t *mp_ping;
18514   int ret;
18515
18516   M (ONE_STATS_DUMP, mp);
18517   /* send it... */
18518   S (mp);
18519
18520   /* Use a control ping for synchronization */
18521   MPING (CONTROL_PING, mp_ping);
18522   S (mp_ping);
18523
18524   /* Wait for a reply... */
18525   W (ret);
18526   return ret;
18527 }
18528
18529 static int
18530 api_show_one_status (vat_main_t * vam)
18531 {
18532   vl_api_show_one_status_t *mp;
18533   int ret;
18534
18535   if (!vam->json_output)
18536     {
18537       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18538     }
18539
18540   M (SHOW_ONE_STATUS, mp);
18541   /* send it... */
18542   S (mp);
18543   /* Wait for a reply... */
18544   W (ret);
18545   return ret;
18546 }
18547
18548 #define api_show_lisp_status api_show_one_status
18549
18550 static int
18551 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18552 {
18553   vl_api_gpe_fwd_entry_path_dump_t *mp;
18554   vl_api_control_ping_t *mp_ping;
18555   unformat_input_t *i = vam->input;
18556   u32 fwd_entry_index = ~0;
18557   int ret;
18558
18559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18560     {
18561       if (unformat (i, "index %d", &fwd_entry_index))
18562         ;
18563       else
18564         break;
18565     }
18566
18567   if (~0 == fwd_entry_index)
18568     {
18569       errmsg ("no index specified!");
18570       return -99;
18571     }
18572
18573   if (!vam->json_output)
18574     {
18575       print (vam->ofp, "first line");
18576     }
18577
18578   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18579
18580   /* send it... */
18581   S (mp);
18582   /* Use a control ping for synchronization */
18583   MPING (CONTROL_PING, mp_ping);
18584   S (mp_ping);
18585
18586   /* Wait for a reply... */
18587   W (ret);
18588   return ret;
18589 }
18590
18591 static int
18592 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18593 {
18594   vl_api_one_get_map_request_itr_rlocs_t *mp;
18595   int ret;
18596
18597   if (!vam->json_output)
18598     {
18599       print (vam->ofp, "%=20s", "itr-rlocs:");
18600     }
18601
18602   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18603   /* send it... */
18604   S (mp);
18605   /* Wait for a reply... */
18606   W (ret);
18607   return ret;
18608 }
18609
18610 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18611
18612 static int
18613 api_af_packet_create (vat_main_t * vam)
18614 {
18615   unformat_input_t *i = vam->input;
18616   vl_api_af_packet_create_t *mp;
18617   u8 *host_if_name = 0;
18618   u8 hw_addr[6];
18619   u8 random_hw_addr = 1;
18620   int ret;
18621
18622   clib_memset (hw_addr, 0, sizeof (hw_addr));
18623
18624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18625     {
18626       if (unformat (i, "name %s", &host_if_name))
18627         vec_add1 (host_if_name, 0);
18628       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18629         random_hw_addr = 0;
18630       else
18631         break;
18632     }
18633
18634   if (!vec_len (host_if_name))
18635     {
18636       errmsg ("host-interface name must be specified");
18637       return -99;
18638     }
18639
18640   if (vec_len (host_if_name) > 64)
18641     {
18642       errmsg ("host-interface name too long");
18643       return -99;
18644     }
18645
18646   M (AF_PACKET_CREATE, mp);
18647
18648   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18649   clib_memcpy (mp->hw_addr, hw_addr, 6);
18650   mp->use_random_hw_addr = random_hw_addr;
18651   vec_free (host_if_name);
18652
18653   S (mp);
18654
18655   /* *INDENT-OFF* */
18656   W2 (ret,
18657       ({
18658         if (ret == 0)
18659           fprintf (vam->ofp ? vam->ofp : stderr,
18660                    " new sw_if_index = %d\n", vam->sw_if_index);
18661       }));
18662   /* *INDENT-ON* */
18663   return ret;
18664 }
18665
18666 static int
18667 api_af_packet_delete (vat_main_t * vam)
18668 {
18669   unformat_input_t *i = vam->input;
18670   vl_api_af_packet_delete_t *mp;
18671   u8 *host_if_name = 0;
18672   int ret;
18673
18674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18675     {
18676       if (unformat (i, "name %s", &host_if_name))
18677         vec_add1 (host_if_name, 0);
18678       else
18679         break;
18680     }
18681
18682   if (!vec_len (host_if_name))
18683     {
18684       errmsg ("host-interface name must be specified");
18685       return -99;
18686     }
18687
18688   if (vec_len (host_if_name) > 64)
18689     {
18690       errmsg ("host-interface name too long");
18691       return -99;
18692     }
18693
18694   M (AF_PACKET_DELETE, mp);
18695
18696   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18697   vec_free (host_if_name);
18698
18699   S (mp);
18700   W (ret);
18701   return ret;
18702 }
18703
18704 static void vl_api_af_packet_details_t_handler
18705   (vl_api_af_packet_details_t * mp)
18706 {
18707   vat_main_t *vam = &vat_main;
18708
18709   print (vam->ofp, "%-16s %d",
18710          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18711 }
18712
18713 static void vl_api_af_packet_details_t_handler_json
18714   (vl_api_af_packet_details_t * mp)
18715 {
18716   vat_main_t *vam = &vat_main;
18717   vat_json_node_t *node = NULL;
18718
18719   if (VAT_JSON_ARRAY != vam->json_tree.type)
18720     {
18721       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18722       vat_json_init_array (&vam->json_tree);
18723     }
18724   node = vat_json_array_add (&vam->json_tree);
18725
18726   vat_json_init_object (node);
18727   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18728   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18729 }
18730
18731 static int
18732 api_af_packet_dump (vat_main_t * vam)
18733 {
18734   vl_api_af_packet_dump_t *mp;
18735   vl_api_control_ping_t *mp_ping;
18736   int ret;
18737
18738   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18739   /* Get list of tap interfaces */
18740   M (AF_PACKET_DUMP, mp);
18741   S (mp);
18742
18743   /* Use a control ping for synchronization */
18744   MPING (CONTROL_PING, mp_ping);
18745   S (mp_ping);
18746
18747   W (ret);
18748   return ret;
18749 }
18750
18751 static int
18752 api_policer_add_del (vat_main_t * vam)
18753 {
18754   unformat_input_t *i = vam->input;
18755   vl_api_policer_add_del_t *mp;
18756   u8 is_add = 1;
18757   u8 *name = 0;
18758   u32 cir = 0;
18759   u32 eir = 0;
18760   u64 cb = 0;
18761   u64 eb = 0;
18762   u8 rate_type = 0;
18763   u8 round_type = 0;
18764   u8 type = 0;
18765   u8 color_aware = 0;
18766   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18767   int ret;
18768
18769   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18770   conform_action.dscp = 0;
18771   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18772   exceed_action.dscp = 0;
18773   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18774   violate_action.dscp = 0;
18775
18776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18777     {
18778       if (unformat (i, "del"))
18779         is_add = 0;
18780       else if (unformat (i, "name %s", &name))
18781         vec_add1 (name, 0);
18782       else if (unformat (i, "cir %u", &cir))
18783         ;
18784       else if (unformat (i, "eir %u", &eir))
18785         ;
18786       else if (unformat (i, "cb %u", &cb))
18787         ;
18788       else if (unformat (i, "eb %u", &eb))
18789         ;
18790       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18791                          &rate_type))
18792         ;
18793       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18794                          &round_type))
18795         ;
18796       else if (unformat (i, "type %U", unformat_policer_type, &type))
18797         ;
18798       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18799                          &conform_action))
18800         ;
18801       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18802                          &exceed_action))
18803         ;
18804       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18805                          &violate_action))
18806         ;
18807       else if (unformat (i, "color-aware"))
18808         color_aware = 1;
18809       else
18810         break;
18811     }
18812
18813   if (!vec_len (name))
18814     {
18815       errmsg ("policer name must be specified");
18816       return -99;
18817     }
18818
18819   if (vec_len (name) > 64)
18820     {
18821       errmsg ("policer name too long");
18822       return -99;
18823     }
18824
18825   M (POLICER_ADD_DEL, mp);
18826
18827   clib_memcpy (mp->name, name, vec_len (name));
18828   vec_free (name);
18829   mp->is_add = is_add;
18830   mp->cir = ntohl (cir);
18831   mp->eir = ntohl (eir);
18832   mp->cb = clib_net_to_host_u64 (cb);
18833   mp->eb = clib_net_to_host_u64 (eb);
18834   mp->rate_type = rate_type;
18835   mp->round_type = round_type;
18836   mp->type = type;
18837   mp->conform_action_type = conform_action.action_type;
18838   mp->conform_dscp = conform_action.dscp;
18839   mp->exceed_action_type = exceed_action.action_type;
18840   mp->exceed_dscp = exceed_action.dscp;
18841   mp->violate_action_type = violate_action.action_type;
18842   mp->violate_dscp = violate_action.dscp;
18843   mp->color_aware = color_aware;
18844
18845   S (mp);
18846   W (ret);
18847   return ret;
18848 }
18849
18850 static int
18851 api_policer_dump (vat_main_t * vam)
18852 {
18853   unformat_input_t *i = vam->input;
18854   vl_api_policer_dump_t *mp;
18855   vl_api_control_ping_t *mp_ping;
18856   u8 *match_name = 0;
18857   u8 match_name_valid = 0;
18858   int ret;
18859
18860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18861     {
18862       if (unformat (i, "name %s", &match_name))
18863         {
18864           vec_add1 (match_name, 0);
18865           match_name_valid = 1;
18866         }
18867       else
18868         break;
18869     }
18870
18871   M (POLICER_DUMP, mp);
18872   mp->match_name_valid = match_name_valid;
18873   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18874   vec_free (match_name);
18875   /* send it... */
18876   S (mp);
18877
18878   /* Use a control ping for synchronization */
18879   MPING (CONTROL_PING, mp_ping);
18880   S (mp_ping);
18881
18882   /* Wait for a reply... */
18883   W (ret);
18884   return ret;
18885 }
18886
18887 static int
18888 api_policer_classify_set_interface (vat_main_t * vam)
18889 {
18890   unformat_input_t *i = vam->input;
18891   vl_api_policer_classify_set_interface_t *mp;
18892   u32 sw_if_index;
18893   int sw_if_index_set;
18894   u32 ip4_table_index = ~0;
18895   u32 ip6_table_index = ~0;
18896   u32 l2_table_index = ~0;
18897   u8 is_add = 1;
18898   int ret;
18899
18900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18901     {
18902       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18903         sw_if_index_set = 1;
18904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18905         sw_if_index_set = 1;
18906       else if (unformat (i, "del"))
18907         is_add = 0;
18908       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18909         ;
18910       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18911         ;
18912       else if (unformat (i, "l2-table %d", &l2_table_index))
18913         ;
18914       else
18915         {
18916           clib_warning ("parse error '%U'", format_unformat_error, i);
18917           return -99;
18918         }
18919     }
18920
18921   if (sw_if_index_set == 0)
18922     {
18923       errmsg ("missing interface name or sw_if_index");
18924       return -99;
18925     }
18926
18927   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18928
18929   mp->sw_if_index = ntohl (sw_if_index);
18930   mp->ip4_table_index = ntohl (ip4_table_index);
18931   mp->ip6_table_index = ntohl (ip6_table_index);
18932   mp->l2_table_index = ntohl (l2_table_index);
18933   mp->is_add = is_add;
18934
18935   S (mp);
18936   W (ret);
18937   return ret;
18938 }
18939
18940 static int
18941 api_policer_classify_dump (vat_main_t * vam)
18942 {
18943   unformat_input_t *i = vam->input;
18944   vl_api_policer_classify_dump_t *mp;
18945   vl_api_control_ping_t *mp_ping;
18946   u8 type = POLICER_CLASSIFY_N_TABLES;
18947   int ret;
18948
18949   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18950     ;
18951   else
18952     {
18953       errmsg ("classify table type must be specified");
18954       return -99;
18955     }
18956
18957   if (!vam->json_output)
18958     {
18959       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18960     }
18961
18962   M (POLICER_CLASSIFY_DUMP, mp);
18963   mp->type = type;
18964   /* send it... */
18965   S (mp);
18966
18967   /* Use a control ping for synchronization */
18968   MPING (CONTROL_PING, mp_ping);
18969   S (mp_ping);
18970
18971   /* Wait for a reply... */
18972   W (ret);
18973   return ret;
18974 }
18975
18976 static int
18977 api_netmap_create (vat_main_t * vam)
18978 {
18979   unformat_input_t *i = vam->input;
18980   vl_api_netmap_create_t *mp;
18981   u8 *if_name = 0;
18982   u8 hw_addr[6];
18983   u8 random_hw_addr = 1;
18984   u8 is_pipe = 0;
18985   u8 is_master = 0;
18986   int ret;
18987
18988   clib_memset (hw_addr, 0, sizeof (hw_addr));
18989
18990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18991     {
18992       if (unformat (i, "name %s", &if_name))
18993         vec_add1 (if_name, 0);
18994       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18995         random_hw_addr = 0;
18996       else if (unformat (i, "pipe"))
18997         is_pipe = 1;
18998       else if (unformat (i, "master"))
18999         is_master = 1;
19000       else if (unformat (i, "slave"))
19001         is_master = 0;
19002       else
19003         break;
19004     }
19005
19006   if (!vec_len (if_name))
19007     {
19008       errmsg ("interface name must be specified");
19009       return -99;
19010     }
19011
19012   if (vec_len (if_name) > 64)
19013     {
19014       errmsg ("interface name too long");
19015       return -99;
19016     }
19017
19018   M (NETMAP_CREATE, mp);
19019
19020   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19021   clib_memcpy (mp->hw_addr, hw_addr, 6);
19022   mp->use_random_hw_addr = random_hw_addr;
19023   mp->is_pipe = is_pipe;
19024   mp->is_master = is_master;
19025   vec_free (if_name);
19026
19027   S (mp);
19028   W (ret);
19029   return ret;
19030 }
19031
19032 static int
19033 api_netmap_delete (vat_main_t * vam)
19034 {
19035   unformat_input_t *i = vam->input;
19036   vl_api_netmap_delete_t *mp;
19037   u8 *if_name = 0;
19038   int ret;
19039
19040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19041     {
19042       if (unformat (i, "name %s", &if_name))
19043         vec_add1 (if_name, 0);
19044       else
19045         break;
19046     }
19047
19048   if (!vec_len (if_name))
19049     {
19050       errmsg ("interface name must be specified");
19051       return -99;
19052     }
19053
19054   if (vec_len (if_name) > 64)
19055     {
19056       errmsg ("interface name too long");
19057       return -99;
19058     }
19059
19060   M (NETMAP_DELETE, mp);
19061
19062   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19063   vec_free (if_name);
19064
19065   S (mp);
19066   W (ret);
19067   return ret;
19068 }
19069
19070 static void
19071 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19072 {
19073   if (fp->afi == IP46_TYPE_IP6)
19074     print (vam->ofp,
19075            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19076            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19077            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19078            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19079            format_ip6_address, fp->next_hop);
19080   else if (fp->afi == IP46_TYPE_IP4)
19081     print (vam->ofp,
19082            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19083            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19084            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19085            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19086            format_ip4_address, fp->next_hop);
19087 }
19088
19089 static void
19090 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19091                                  vl_api_fib_path_t * fp)
19092 {
19093   struct in_addr ip4;
19094   struct in6_addr ip6;
19095
19096   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19097   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19098   vat_json_object_add_uint (node, "is_local", fp->is_local);
19099   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19100   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19101   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19102   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19103   if (fp->afi == IP46_TYPE_IP4)
19104     {
19105       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19106       vat_json_object_add_ip4 (node, "next_hop", ip4);
19107     }
19108   else if (fp->afi == IP46_TYPE_IP6)
19109     {
19110       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19111       vat_json_object_add_ip6 (node, "next_hop", ip6);
19112     }
19113 }
19114
19115 static void
19116 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19117 {
19118   vat_main_t *vam = &vat_main;
19119   int count = ntohl (mp->mt_count);
19120   vl_api_fib_path_t *fp;
19121   i32 i;
19122
19123   print (vam->ofp, "[%d]: sw_if_index %d via:",
19124          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19125   fp = mp->mt_paths;
19126   for (i = 0; i < count; i++)
19127     {
19128       vl_api_mpls_fib_path_print (vam, fp);
19129       fp++;
19130     }
19131
19132   print (vam->ofp, "");
19133 }
19134
19135 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19136 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19137
19138 static void
19139 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19140 {
19141   vat_main_t *vam = &vat_main;
19142   vat_json_node_t *node = NULL;
19143   int count = ntohl (mp->mt_count);
19144   vl_api_fib_path_t *fp;
19145   i32 i;
19146
19147   if (VAT_JSON_ARRAY != vam->json_tree.type)
19148     {
19149       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19150       vat_json_init_array (&vam->json_tree);
19151     }
19152   node = vat_json_array_add (&vam->json_tree);
19153
19154   vat_json_init_object (node);
19155   vat_json_object_add_uint (node, "tunnel_index",
19156                             ntohl (mp->mt_tunnel_index));
19157   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19158
19159   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19160
19161   fp = mp->mt_paths;
19162   for (i = 0; i < count; i++)
19163     {
19164       vl_api_mpls_fib_path_json_print (node, fp);
19165       fp++;
19166     }
19167 }
19168
19169 static int
19170 api_mpls_tunnel_dump (vat_main_t * vam)
19171 {
19172   vl_api_mpls_tunnel_dump_t *mp;
19173   vl_api_control_ping_t *mp_ping;
19174   u32 sw_if_index = ~0;
19175   int ret;
19176
19177   /* Parse args required to build the message */
19178   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19179     {
19180       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19181         ;
19182     }
19183
19184   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19185
19186   M (MPLS_TUNNEL_DUMP, mp);
19187   mp->sw_if_index = htonl (sw_if_index);
19188   S (mp);
19189
19190   /* Use a control ping for synchronization */
19191   MPING (CONTROL_PING, mp_ping);
19192   S (mp_ping);
19193
19194   W (ret);
19195   return ret;
19196 }
19197
19198 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19199 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19200
19201
19202 static void
19203 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19204 {
19205   vat_main_t *vam = &vat_main;
19206   int count = ntohl (mp->count);
19207   vl_api_fib_path_t *fp;
19208   int i;
19209
19210   print (vam->ofp,
19211          "table-id %d, label %u, ess_bit %u",
19212          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19213   fp = mp->path;
19214   for (i = 0; i < count; i++)
19215     {
19216       vl_api_mpls_fib_path_print (vam, fp);
19217       fp++;
19218     }
19219 }
19220
19221 static void vl_api_mpls_fib_details_t_handler_json
19222   (vl_api_mpls_fib_details_t * mp)
19223 {
19224   vat_main_t *vam = &vat_main;
19225   int count = ntohl (mp->count);
19226   vat_json_node_t *node = NULL;
19227   vl_api_fib_path_t *fp;
19228   int i;
19229
19230   if (VAT_JSON_ARRAY != vam->json_tree.type)
19231     {
19232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19233       vat_json_init_array (&vam->json_tree);
19234     }
19235   node = vat_json_array_add (&vam->json_tree);
19236
19237   vat_json_init_object (node);
19238   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19239   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19240   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19241   vat_json_object_add_uint (node, "path_count", count);
19242   fp = mp->path;
19243   for (i = 0; i < count; i++)
19244     {
19245       vl_api_mpls_fib_path_json_print (node, fp);
19246       fp++;
19247     }
19248 }
19249
19250 static int
19251 api_mpls_fib_dump (vat_main_t * vam)
19252 {
19253   vl_api_mpls_fib_dump_t *mp;
19254   vl_api_control_ping_t *mp_ping;
19255   int ret;
19256
19257   M (MPLS_FIB_DUMP, mp);
19258   S (mp);
19259
19260   /* Use a control ping for synchronization */
19261   MPING (CONTROL_PING, mp_ping);
19262   S (mp_ping);
19263
19264   W (ret);
19265   return ret;
19266 }
19267
19268 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19269 #define vl_api_ip_fib_details_t_print vl_noop_handler
19270
19271 static void
19272 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19273 {
19274   vat_main_t *vam = &vat_main;
19275   int count = ntohl (mp->count);
19276   vl_api_fib_path_t *fp;
19277   int i;
19278
19279   print (vam->ofp,
19280          "table-id %d, prefix %U/%d stats-index %d",
19281          ntohl (mp->table_id), format_ip4_address, mp->address,
19282          mp->address_length, ntohl (mp->stats_index));
19283   fp = mp->path;
19284   for (i = 0; i < count; i++)
19285     {
19286       if (fp->afi == IP46_TYPE_IP6)
19287         print (vam->ofp,
19288                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19289                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19290                "next_hop_table %d",
19291                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19292                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19293                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19294       else if (fp->afi == IP46_TYPE_IP4)
19295         print (vam->ofp,
19296                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19297                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19298                "next_hop_table %d",
19299                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19300                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19301                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19302       fp++;
19303     }
19304 }
19305
19306 static void vl_api_ip_fib_details_t_handler_json
19307   (vl_api_ip_fib_details_t * mp)
19308 {
19309   vat_main_t *vam = &vat_main;
19310   int count = ntohl (mp->count);
19311   vat_json_node_t *node = NULL;
19312   struct in_addr ip4;
19313   struct in6_addr ip6;
19314   vl_api_fib_path_t *fp;
19315   int i;
19316
19317   if (VAT_JSON_ARRAY != vam->json_tree.type)
19318     {
19319       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19320       vat_json_init_array (&vam->json_tree);
19321     }
19322   node = vat_json_array_add (&vam->json_tree);
19323
19324   vat_json_init_object (node);
19325   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19326   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19327   vat_json_object_add_ip4 (node, "prefix", ip4);
19328   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19329   vat_json_object_add_uint (node, "path_count", count);
19330   fp = mp->path;
19331   for (i = 0; i < count; i++)
19332     {
19333       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19334       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19335       vat_json_object_add_uint (node, "is_local", fp->is_local);
19336       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19337       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19338       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19339       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19340       if (fp->afi == IP46_TYPE_IP4)
19341         {
19342           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19343           vat_json_object_add_ip4 (node, "next_hop", ip4);
19344         }
19345       else if (fp->afi == IP46_TYPE_IP6)
19346         {
19347           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19348           vat_json_object_add_ip6 (node, "next_hop", ip6);
19349         }
19350     }
19351 }
19352
19353 static int
19354 api_ip_fib_dump (vat_main_t * vam)
19355 {
19356   vl_api_ip_fib_dump_t *mp;
19357   vl_api_control_ping_t *mp_ping;
19358   int ret;
19359
19360   M (IP_FIB_DUMP, mp);
19361   S (mp);
19362
19363   /* Use a control ping for synchronization */
19364   MPING (CONTROL_PING, mp_ping);
19365   S (mp_ping);
19366
19367   W (ret);
19368   return ret;
19369 }
19370
19371 static int
19372 api_ip_mfib_dump (vat_main_t * vam)
19373 {
19374   vl_api_ip_mfib_dump_t *mp;
19375   vl_api_control_ping_t *mp_ping;
19376   int ret;
19377
19378   M (IP_MFIB_DUMP, mp);
19379   S (mp);
19380
19381   /* Use a control ping for synchronization */
19382   MPING (CONTROL_PING, mp_ping);
19383   S (mp_ping);
19384
19385   W (ret);
19386   return ret;
19387 }
19388
19389 static void vl_api_ip_neighbor_details_t_handler
19390   (vl_api_ip_neighbor_details_t * mp)
19391 {
19392   vat_main_t *vam = &vat_main;
19393
19394   print (vam->ofp, "%c %U %U",
19395          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19396          format_vl_api_mac_address, &mp->neighbor.mac_address,
19397          format_vl_api_address, &mp->neighbor.ip_address);
19398 }
19399
19400 static void vl_api_ip_neighbor_details_t_handler_json
19401   (vl_api_ip_neighbor_details_t * mp)
19402 {
19403
19404   vat_main_t *vam = &vat_main;
19405   vat_json_node_t *node;
19406
19407   if (VAT_JSON_ARRAY != vam->json_tree.type)
19408     {
19409       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19410       vat_json_init_array (&vam->json_tree);
19411     }
19412   node = vat_json_array_add (&vam->json_tree);
19413
19414   vat_json_init_object (node);
19415   vat_json_object_add_string_copy
19416     (node, "flag",
19417      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19418       (u8 *) "static" : (u8 *) "dynamic"));
19419
19420   vat_json_object_add_string_copy (node, "link_layer",
19421                                    format (0, "%U", format_vl_api_mac_address,
19422                                            &mp->neighbor.mac_address));
19423   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19424 }
19425
19426 static int
19427 api_ip_neighbor_dump (vat_main_t * vam)
19428 {
19429   unformat_input_t *i = vam->input;
19430   vl_api_ip_neighbor_dump_t *mp;
19431   vl_api_control_ping_t *mp_ping;
19432   u8 is_ipv6 = 0;
19433   u32 sw_if_index = ~0;
19434   int ret;
19435
19436   /* Parse args required to build the message */
19437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19438     {
19439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19440         ;
19441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19442         ;
19443       else if (unformat (i, "ip6"))
19444         is_ipv6 = 1;
19445       else
19446         break;
19447     }
19448
19449   if (sw_if_index == ~0)
19450     {
19451       errmsg ("missing interface name or sw_if_index");
19452       return -99;
19453     }
19454
19455   M (IP_NEIGHBOR_DUMP, mp);
19456   mp->is_ipv6 = (u8) is_ipv6;
19457   mp->sw_if_index = ntohl (sw_if_index);
19458   S (mp);
19459
19460   /* Use a control ping for synchronization */
19461   MPING (CONTROL_PING, mp_ping);
19462   S (mp_ping);
19463
19464   W (ret);
19465   return ret;
19466 }
19467
19468 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19469 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19470
19471 static void
19472 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19473 {
19474   vat_main_t *vam = &vat_main;
19475   int count = ntohl (mp->count);
19476   vl_api_fib_path_t *fp;
19477   int i;
19478
19479   print (vam->ofp,
19480          "table-id %d, prefix %U/%d stats-index %d",
19481          ntohl (mp->table_id), format_ip6_address, mp->address,
19482          mp->address_length, ntohl (mp->stats_index));
19483   fp = mp->path;
19484   for (i = 0; i < count; i++)
19485     {
19486       if (fp->afi == IP46_TYPE_IP6)
19487         print (vam->ofp,
19488                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19489                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19490                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19491                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19492                format_ip6_address, fp->next_hop);
19493       else if (fp->afi == IP46_TYPE_IP4)
19494         print (vam->ofp,
19495                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19496                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19497                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19498                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19499                format_ip4_address, fp->next_hop);
19500       fp++;
19501     }
19502 }
19503
19504 static void vl_api_ip6_fib_details_t_handler_json
19505   (vl_api_ip6_fib_details_t * mp)
19506 {
19507   vat_main_t *vam = &vat_main;
19508   int count = ntohl (mp->count);
19509   vat_json_node_t *node = NULL;
19510   struct in_addr ip4;
19511   struct in6_addr ip6;
19512   vl_api_fib_path_t *fp;
19513   int i;
19514
19515   if (VAT_JSON_ARRAY != vam->json_tree.type)
19516     {
19517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19518       vat_json_init_array (&vam->json_tree);
19519     }
19520   node = vat_json_array_add (&vam->json_tree);
19521
19522   vat_json_init_object (node);
19523   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19524   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19525   vat_json_object_add_ip6 (node, "prefix", ip6);
19526   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19527   vat_json_object_add_uint (node, "path_count", count);
19528   fp = mp->path;
19529   for (i = 0; i < count; i++)
19530     {
19531       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19532       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19533       vat_json_object_add_uint (node, "is_local", fp->is_local);
19534       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19535       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19536       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19537       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19538       if (fp->afi == IP46_TYPE_IP4)
19539         {
19540           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19541           vat_json_object_add_ip4 (node, "next_hop", ip4);
19542         }
19543       else if (fp->afi == IP46_TYPE_IP6)
19544         {
19545           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19546           vat_json_object_add_ip6 (node, "next_hop", ip6);
19547         }
19548     }
19549 }
19550
19551 static int
19552 api_ip6_fib_dump (vat_main_t * vam)
19553 {
19554   vl_api_ip6_fib_dump_t *mp;
19555   vl_api_control_ping_t *mp_ping;
19556   int ret;
19557
19558   M (IP6_FIB_DUMP, mp);
19559   S (mp);
19560
19561   /* Use a control ping for synchronization */
19562   MPING (CONTROL_PING, mp_ping);
19563   S (mp_ping);
19564
19565   W (ret);
19566   return ret;
19567 }
19568
19569 static int
19570 api_ip6_mfib_dump (vat_main_t * vam)
19571 {
19572   vl_api_ip6_mfib_dump_t *mp;
19573   vl_api_control_ping_t *mp_ping;
19574   int ret;
19575
19576   M (IP6_MFIB_DUMP, mp);
19577   S (mp);
19578
19579   /* Use a control ping for synchronization */
19580   MPING (CONTROL_PING, mp_ping);
19581   S (mp_ping);
19582
19583   W (ret);
19584   return ret;
19585 }
19586
19587 int
19588 api_classify_table_ids (vat_main_t * vam)
19589 {
19590   vl_api_classify_table_ids_t *mp;
19591   int ret;
19592
19593   /* Construct the API message */
19594   M (CLASSIFY_TABLE_IDS, mp);
19595   mp->context = 0;
19596
19597   S (mp);
19598   W (ret);
19599   return ret;
19600 }
19601
19602 int
19603 api_classify_table_by_interface (vat_main_t * vam)
19604 {
19605   unformat_input_t *input = vam->input;
19606   vl_api_classify_table_by_interface_t *mp;
19607
19608   u32 sw_if_index = ~0;
19609   int ret;
19610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19611     {
19612       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19613         ;
19614       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19615         ;
19616       else
19617         break;
19618     }
19619   if (sw_if_index == ~0)
19620     {
19621       errmsg ("missing interface name or sw_if_index");
19622       return -99;
19623     }
19624
19625   /* Construct the API message */
19626   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19627   mp->context = 0;
19628   mp->sw_if_index = ntohl (sw_if_index);
19629
19630   S (mp);
19631   W (ret);
19632   return ret;
19633 }
19634
19635 int
19636 api_classify_table_info (vat_main_t * vam)
19637 {
19638   unformat_input_t *input = vam->input;
19639   vl_api_classify_table_info_t *mp;
19640
19641   u32 table_id = ~0;
19642   int ret;
19643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19644     {
19645       if (unformat (input, "table_id %d", &table_id))
19646         ;
19647       else
19648         break;
19649     }
19650   if (table_id == ~0)
19651     {
19652       errmsg ("missing table id");
19653       return -99;
19654     }
19655
19656   /* Construct the API message */
19657   M (CLASSIFY_TABLE_INFO, mp);
19658   mp->context = 0;
19659   mp->table_id = ntohl (table_id);
19660
19661   S (mp);
19662   W (ret);
19663   return ret;
19664 }
19665
19666 int
19667 api_classify_session_dump (vat_main_t * vam)
19668 {
19669   unformat_input_t *input = vam->input;
19670   vl_api_classify_session_dump_t *mp;
19671   vl_api_control_ping_t *mp_ping;
19672
19673   u32 table_id = ~0;
19674   int ret;
19675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19676     {
19677       if (unformat (input, "table_id %d", &table_id))
19678         ;
19679       else
19680         break;
19681     }
19682   if (table_id == ~0)
19683     {
19684       errmsg ("missing table id");
19685       return -99;
19686     }
19687
19688   /* Construct the API message */
19689   M (CLASSIFY_SESSION_DUMP, mp);
19690   mp->context = 0;
19691   mp->table_id = ntohl (table_id);
19692   S (mp);
19693
19694   /* Use a control ping for synchronization */
19695   MPING (CONTROL_PING, mp_ping);
19696   S (mp_ping);
19697
19698   W (ret);
19699   return ret;
19700 }
19701
19702 static void
19703 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19704 {
19705   vat_main_t *vam = &vat_main;
19706
19707   print (vam->ofp, "collector_address %U, collector_port %d, "
19708          "src_address %U, vrf_id %d, path_mtu %u, "
19709          "template_interval %u, udp_checksum %d",
19710          format_ip4_address, mp->collector_address,
19711          ntohs (mp->collector_port),
19712          format_ip4_address, mp->src_address,
19713          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19714          ntohl (mp->template_interval), mp->udp_checksum);
19715
19716   vam->retval = 0;
19717   vam->result_ready = 1;
19718 }
19719
19720 static void
19721   vl_api_ipfix_exporter_details_t_handler_json
19722   (vl_api_ipfix_exporter_details_t * mp)
19723 {
19724   vat_main_t *vam = &vat_main;
19725   vat_json_node_t node;
19726   struct in_addr collector_address;
19727   struct in_addr src_address;
19728
19729   vat_json_init_object (&node);
19730   clib_memcpy (&collector_address, &mp->collector_address,
19731                sizeof (collector_address));
19732   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19733   vat_json_object_add_uint (&node, "collector_port",
19734                             ntohs (mp->collector_port));
19735   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19736   vat_json_object_add_ip4 (&node, "src_address", src_address);
19737   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19738   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19739   vat_json_object_add_uint (&node, "template_interval",
19740                             ntohl (mp->template_interval));
19741   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19742
19743   vat_json_print (vam->ofp, &node);
19744   vat_json_free (&node);
19745   vam->retval = 0;
19746   vam->result_ready = 1;
19747 }
19748
19749 int
19750 api_ipfix_exporter_dump (vat_main_t * vam)
19751 {
19752   vl_api_ipfix_exporter_dump_t *mp;
19753   int ret;
19754
19755   /* Construct the API message */
19756   M (IPFIX_EXPORTER_DUMP, mp);
19757   mp->context = 0;
19758
19759   S (mp);
19760   W (ret);
19761   return ret;
19762 }
19763
19764 static int
19765 api_ipfix_classify_stream_dump (vat_main_t * vam)
19766 {
19767   vl_api_ipfix_classify_stream_dump_t *mp;
19768   int ret;
19769
19770   /* Construct the API message */
19771   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19772   mp->context = 0;
19773
19774   S (mp);
19775   W (ret);
19776   return ret;
19777   /* NOTREACHED */
19778   return 0;
19779 }
19780
19781 static void
19782   vl_api_ipfix_classify_stream_details_t_handler
19783   (vl_api_ipfix_classify_stream_details_t * mp)
19784 {
19785   vat_main_t *vam = &vat_main;
19786   print (vam->ofp, "domain_id %d, src_port %d",
19787          ntohl (mp->domain_id), ntohs (mp->src_port));
19788   vam->retval = 0;
19789   vam->result_ready = 1;
19790 }
19791
19792 static void
19793   vl_api_ipfix_classify_stream_details_t_handler_json
19794   (vl_api_ipfix_classify_stream_details_t * mp)
19795 {
19796   vat_main_t *vam = &vat_main;
19797   vat_json_node_t node;
19798
19799   vat_json_init_object (&node);
19800   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19801   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19802
19803   vat_json_print (vam->ofp, &node);
19804   vat_json_free (&node);
19805   vam->retval = 0;
19806   vam->result_ready = 1;
19807 }
19808
19809 static int
19810 api_ipfix_classify_table_dump (vat_main_t * vam)
19811 {
19812   vl_api_ipfix_classify_table_dump_t *mp;
19813   vl_api_control_ping_t *mp_ping;
19814   int ret;
19815
19816   if (!vam->json_output)
19817     {
19818       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19819              "transport_protocol");
19820     }
19821
19822   /* Construct the API message */
19823   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19824
19825   /* send it... */
19826   S (mp);
19827
19828   /* Use a control ping for synchronization */
19829   MPING (CONTROL_PING, mp_ping);
19830   S (mp_ping);
19831
19832   W (ret);
19833   return ret;
19834 }
19835
19836 static void
19837   vl_api_ipfix_classify_table_details_t_handler
19838   (vl_api_ipfix_classify_table_details_t * mp)
19839 {
19840   vat_main_t *vam = &vat_main;
19841   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19842          mp->transport_protocol);
19843 }
19844
19845 static void
19846   vl_api_ipfix_classify_table_details_t_handler_json
19847   (vl_api_ipfix_classify_table_details_t * mp)
19848 {
19849   vat_json_node_t *node = NULL;
19850   vat_main_t *vam = &vat_main;
19851
19852   if (VAT_JSON_ARRAY != vam->json_tree.type)
19853     {
19854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19855       vat_json_init_array (&vam->json_tree);
19856     }
19857
19858   node = vat_json_array_add (&vam->json_tree);
19859   vat_json_init_object (node);
19860
19861   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19862   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19863   vat_json_object_add_uint (node, "transport_protocol",
19864                             mp->transport_protocol);
19865 }
19866
19867 static int
19868 api_sw_interface_span_enable_disable (vat_main_t * vam)
19869 {
19870   unformat_input_t *i = vam->input;
19871   vl_api_sw_interface_span_enable_disable_t *mp;
19872   u32 src_sw_if_index = ~0;
19873   u32 dst_sw_if_index = ~0;
19874   u8 state = 3;
19875   int ret;
19876   u8 is_l2 = 0;
19877
19878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19879     {
19880       if (unformat
19881           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19882         ;
19883       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19884         ;
19885       else
19886         if (unformat
19887             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19888         ;
19889       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19890         ;
19891       else if (unformat (i, "disable"))
19892         state = 0;
19893       else if (unformat (i, "rx"))
19894         state = 1;
19895       else if (unformat (i, "tx"))
19896         state = 2;
19897       else if (unformat (i, "both"))
19898         state = 3;
19899       else if (unformat (i, "l2"))
19900         is_l2 = 1;
19901       else
19902         break;
19903     }
19904
19905   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19906
19907   mp->sw_if_index_from = htonl (src_sw_if_index);
19908   mp->sw_if_index_to = htonl (dst_sw_if_index);
19909   mp->state = state;
19910   mp->is_l2 = is_l2;
19911
19912   S (mp);
19913   W (ret);
19914   return ret;
19915 }
19916
19917 static void
19918 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19919                                             * mp)
19920 {
19921   vat_main_t *vam = &vat_main;
19922   u8 *sw_if_from_name = 0;
19923   u8 *sw_if_to_name = 0;
19924   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19925   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19926   char *states[] = { "none", "rx", "tx", "both" };
19927   hash_pair_t *p;
19928
19929   /* *INDENT-OFF* */
19930   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19931   ({
19932     if ((u32) p->value[0] == sw_if_index_from)
19933       {
19934         sw_if_from_name = (u8 *)(p->key);
19935         if (sw_if_to_name)
19936           break;
19937       }
19938     if ((u32) p->value[0] == sw_if_index_to)
19939       {
19940         sw_if_to_name = (u8 *)(p->key);
19941         if (sw_if_from_name)
19942           break;
19943       }
19944   }));
19945   /* *INDENT-ON* */
19946   print (vam->ofp, "%20s => %20s (%s) %s",
19947          sw_if_from_name, sw_if_to_name, states[mp->state],
19948          mp->is_l2 ? "l2" : "device");
19949 }
19950
19951 static void
19952   vl_api_sw_interface_span_details_t_handler_json
19953   (vl_api_sw_interface_span_details_t * mp)
19954 {
19955   vat_main_t *vam = &vat_main;
19956   vat_json_node_t *node = NULL;
19957   u8 *sw_if_from_name = 0;
19958   u8 *sw_if_to_name = 0;
19959   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19960   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19961   hash_pair_t *p;
19962
19963   /* *INDENT-OFF* */
19964   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19965   ({
19966     if ((u32) p->value[0] == sw_if_index_from)
19967       {
19968         sw_if_from_name = (u8 *)(p->key);
19969         if (sw_if_to_name)
19970           break;
19971       }
19972     if ((u32) p->value[0] == sw_if_index_to)
19973       {
19974         sw_if_to_name = (u8 *)(p->key);
19975         if (sw_if_from_name)
19976           break;
19977       }
19978   }));
19979   /* *INDENT-ON* */
19980
19981   if (VAT_JSON_ARRAY != vam->json_tree.type)
19982     {
19983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19984       vat_json_init_array (&vam->json_tree);
19985     }
19986   node = vat_json_array_add (&vam->json_tree);
19987
19988   vat_json_init_object (node);
19989   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19990   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19991   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19992   if (0 != sw_if_to_name)
19993     {
19994       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19995     }
19996   vat_json_object_add_uint (node, "state", mp->state);
19997   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19998 }
19999
20000 static int
20001 api_sw_interface_span_dump (vat_main_t * vam)
20002 {
20003   unformat_input_t *input = vam->input;
20004   vl_api_sw_interface_span_dump_t *mp;
20005   vl_api_control_ping_t *mp_ping;
20006   u8 is_l2 = 0;
20007   int ret;
20008
20009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20010     {
20011       if (unformat (input, "l2"))
20012         is_l2 = 1;
20013       else
20014         break;
20015     }
20016
20017   M (SW_INTERFACE_SPAN_DUMP, mp);
20018   mp->is_l2 = is_l2;
20019   S (mp);
20020
20021   /* Use a control ping for synchronization */
20022   MPING (CONTROL_PING, mp_ping);
20023   S (mp_ping);
20024
20025   W (ret);
20026   return ret;
20027 }
20028
20029 int
20030 api_pg_create_interface (vat_main_t * vam)
20031 {
20032   unformat_input_t *input = vam->input;
20033   vl_api_pg_create_interface_t *mp;
20034
20035   u32 if_id = ~0;
20036   int ret;
20037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20038     {
20039       if (unformat (input, "if_id %d", &if_id))
20040         ;
20041       else
20042         break;
20043     }
20044   if (if_id == ~0)
20045     {
20046       errmsg ("missing pg interface index");
20047       return -99;
20048     }
20049
20050   /* Construct the API message */
20051   M (PG_CREATE_INTERFACE, mp);
20052   mp->context = 0;
20053   mp->interface_id = ntohl (if_id);
20054
20055   S (mp);
20056   W (ret);
20057   return ret;
20058 }
20059
20060 int
20061 api_pg_capture (vat_main_t * vam)
20062 {
20063   unformat_input_t *input = vam->input;
20064   vl_api_pg_capture_t *mp;
20065
20066   u32 if_id = ~0;
20067   u8 enable = 1;
20068   u32 count = 1;
20069   u8 pcap_file_set = 0;
20070   u8 *pcap_file = 0;
20071   int ret;
20072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20073     {
20074       if (unformat (input, "if_id %d", &if_id))
20075         ;
20076       else if (unformat (input, "pcap %s", &pcap_file))
20077         pcap_file_set = 1;
20078       else if (unformat (input, "count %d", &count))
20079         ;
20080       else if (unformat (input, "disable"))
20081         enable = 0;
20082       else
20083         break;
20084     }
20085   if (if_id == ~0)
20086     {
20087       errmsg ("missing pg interface index");
20088       return -99;
20089     }
20090   if (pcap_file_set > 0)
20091     {
20092       if (vec_len (pcap_file) > 255)
20093         {
20094           errmsg ("pcap file name is too long");
20095           return -99;
20096         }
20097     }
20098
20099   u32 name_len = vec_len (pcap_file);
20100   /* Construct the API message */
20101   M (PG_CAPTURE, mp);
20102   mp->context = 0;
20103   mp->interface_id = ntohl (if_id);
20104   mp->is_enabled = enable;
20105   mp->count = ntohl (count);
20106   mp->pcap_name_length = ntohl (name_len);
20107   if (pcap_file_set != 0)
20108     {
20109       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20110     }
20111   vec_free (pcap_file);
20112
20113   S (mp);
20114   W (ret);
20115   return ret;
20116 }
20117
20118 int
20119 api_pg_enable_disable (vat_main_t * vam)
20120 {
20121   unformat_input_t *input = vam->input;
20122   vl_api_pg_enable_disable_t *mp;
20123
20124   u8 enable = 1;
20125   u8 stream_name_set = 0;
20126   u8 *stream_name = 0;
20127   int ret;
20128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20129     {
20130       if (unformat (input, "stream %s", &stream_name))
20131         stream_name_set = 1;
20132       else if (unformat (input, "disable"))
20133         enable = 0;
20134       else
20135         break;
20136     }
20137
20138   if (stream_name_set > 0)
20139     {
20140       if (vec_len (stream_name) > 255)
20141         {
20142           errmsg ("stream name too long");
20143           return -99;
20144         }
20145     }
20146
20147   u32 name_len = vec_len (stream_name);
20148   /* Construct the API message */
20149   M (PG_ENABLE_DISABLE, mp);
20150   mp->context = 0;
20151   mp->is_enabled = enable;
20152   if (stream_name_set != 0)
20153     {
20154       mp->stream_name_length = ntohl (name_len);
20155       clib_memcpy (mp->stream_name, stream_name, name_len);
20156     }
20157   vec_free (stream_name);
20158
20159   S (mp);
20160   W (ret);
20161   return ret;
20162 }
20163
20164 int
20165 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20166 {
20167   unformat_input_t *input = vam->input;
20168   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20169
20170   u16 *low_ports = 0;
20171   u16 *high_ports = 0;
20172   u16 this_low;
20173   u16 this_hi;
20174   vl_api_prefix_t prefix;
20175   u32 tmp, tmp2;
20176   u8 prefix_set = 0;
20177   u32 vrf_id = ~0;
20178   u8 is_add = 1;
20179   u8 is_ipv6 = 0;
20180   int ret;
20181
20182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20183     {
20184       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20185         prefix_set = 1;
20186       else if (unformat (input, "vrf %d", &vrf_id))
20187         ;
20188       else if (unformat (input, "del"))
20189         is_add = 0;
20190       else if (unformat (input, "port %d", &tmp))
20191         {
20192           if (tmp == 0 || tmp > 65535)
20193             {
20194               errmsg ("port %d out of range", tmp);
20195               return -99;
20196             }
20197           this_low = tmp;
20198           this_hi = this_low + 1;
20199           vec_add1 (low_ports, this_low);
20200           vec_add1 (high_ports, this_hi);
20201         }
20202       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20203         {
20204           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20205             {
20206               errmsg ("incorrect range parameters");
20207               return -99;
20208             }
20209           this_low = tmp;
20210           /* Note: in debug CLI +1 is added to high before
20211              passing to real fn that does "the work"
20212              (ip_source_and_port_range_check_add_del).
20213              This fn is a wrapper around the binary API fn a
20214              control plane will call, which expects this increment
20215              to have occurred. Hence letting the binary API control
20216              plane fn do the increment for consistency between VAT
20217              and other control planes.
20218            */
20219           this_hi = tmp2;
20220           vec_add1 (low_ports, this_low);
20221           vec_add1 (high_ports, this_hi);
20222         }
20223       else
20224         break;
20225     }
20226
20227   if (prefix_set == 0)
20228     {
20229       errmsg ("<address>/<mask> not specified");
20230       return -99;
20231     }
20232
20233   if (vrf_id == ~0)
20234     {
20235       errmsg ("VRF ID required, not specified");
20236       return -99;
20237     }
20238
20239   if (vrf_id == 0)
20240     {
20241       errmsg
20242         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20243       return -99;
20244     }
20245
20246   if (vec_len (low_ports) == 0)
20247     {
20248       errmsg ("At least one port or port range required");
20249       return -99;
20250     }
20251
20252   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20253
20254   mp->is_add = is_add;
20255
20256   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20257
20258   mp->number_of_ranges = vec_len (low_ports);
20259
20260   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20261   vec_free (low_ports);
20262
20263   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20264   vec_free (high_ports);
20265
20266   mp->vrf_id = ntohl (vrf_id);
20267
20268   S (mp);
20269   W (ret);
20270   return ret;
20271 }
20272
20273 int
20274 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20275 {
20276   unformat_input_t *input = vam->input;
20277   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20278   u32 sw_if_index = ~0;
20279   int vrf_set = 0;
20280   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20281   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20282   u8 is_add = 1;
20283   int ret;
20284
20285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20286     {
20287       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20288         ;
20289       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20290         ;
20291       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20292         vrf_set = 1;
20293       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20294         vrf_set = 1;
20295       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20296         vrf_set = 1;
20297       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20298         vrf_set = 1;
20299       else if (unformat (input, "del"))
20300         is_add = 0;
20301       else
20302         break;
20303     }
20304
20305   if (sw_if_index == ~0)
20306     {
20307       errmsg ("Interface required but not specified");
20308       return -99;
20309     }
20310
20311   if (vrf_set == 0)
20312     {
20313       errmsg ("VRF ID required but not specified");
20314       return -99;
20315     }
20316
20317   if (tcp_out_vrf_id == 0
20318       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20319     {
20320       errmsg
20321         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20322       return -99;
20323     }
20324
20325   /* Construct the API message */
20326   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20327
20328   mp->sw_if_index = ntohl (sw_if_index);
20329   mp->is_add = is_add;
20330   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20331   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20332   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20333   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20334
20335   /* send it... */
20336   S (mp);
20337
20338   /* Wait for a reply... */
20339   W (ret);
20340   return ret;
20341 }
20342
20343 static int
20344 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20345 {
20346   unformat_input_t *i = vam->input;
20347   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20348   u32 local_sa_id = 0;
20349   u32 remote_sa_id = 0;
20350   vl_api_ip4_address_t src_address;
20351   vl_api_ip4_address_t dst_address;
20352   u8 is_add = 1;
20353   int ret;
20354
20355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20356     {
20357       if (unformat (i, "local_sa %d", &local_sa_id))
20358         ;
20359       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20360         ;
20361       else
20362         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20363         ;
20364       else
20365         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20366         ;
20367       else if (unformat (i, "del"))
20368         is_add = 0;
20369       else
20370         {
20371           clib_warning ("parse error '%U'", format_unformat_error, i);
20372           return -99;
20373         }
20374     }
20375
20376   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20377
20378   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20379   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20380   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20381   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20382   mp->is_add = is_add;
20383
20384   S (mp);
20385   W (ret);
20386   return ret;
20387 }
20388
20389 static int
20390 api_set_punt (vat_main_t * vam)
20391 {
20392   unformat_input_t *i = vam->input;
20393   vl_api_set_punt_t *mp;
20394   u32 ipv = ~0;
20395   u32 protocol = ~0;
20396   u32 port = ~0;
20397   int is_add = 1;
20398   int ret;
20399
20400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20401     {
20402       if (unformat (i, "ip %d", &ipv))
20403         ;
20404       else if (unformat (i, "protocol %d", &protocol))
20405         ;
20406       else if (unformat (i, "port %d", &port))
20407         ;
20408       else if (unformat (i, "del"))
20409         is_add = 0;
20410       else
20411         {
20412           clib_warning ("parse error '%U'", format_unformat_error, i);
20413           return -99;
20414         }
20415     }
20416
20417   M (SET_PUNT, mp);
20418
20419   mp->is_add = (u8) is_add;
20420   mp->punt.ipv = (u8) ipv;
20421   mp->punt.l4_protocol = (u8) protocol;
20422   mp->punt.l4_port = htons ((u16) port);
20423
20424   S (mp);
20425   W (ret);
20426   return ret;
20427 }
20428
20429 static void vl_api_ipsec_gre_tunnel_details_t_handler
20430   (vl_api_ipsec_gre_tunnel_details_t * mp)
20431 {
20432   vat_main_t *vam = &vat_main;
20433
20434   print (vam->ofp, "%11d%15U%15U%14d%14d",
20435          ntohl (mp->tunnel.sw_if_index),
20436          format_vl_api_ip4_address, mp->tunnel.src,
20437          format_vl_api_ip4_address, mp->tunnel.dst,
20438          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20439 }
20440
20441 static void
20442 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20443                                 const char *name,
20444                                 const vl_api_ip4_address_t addr)
20445 {
20446   struct in_addr ip4;
20447
20448   clib_memcpy (&ip4, addr, sizeof (ip4));
20449   vat_json_object_add_ip4 (node, name, ip4);
20450 }
20451
20452 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20453   (vl_api_ipsec_gre_tunnel_details_t * mp)
20454 {
20455   vat_main_t *vam = &vat_main;
20456   vat_json_node_t *node = NULL;
20457   struct in_addr ip4;
20458
20459   if (VAT_JSON_ARRAY != vam->json_tree.type)
20460     {
20461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20462       vat_json_init_array (&vam->json_tree);
20463     }
20464   node = vat_json_array_add (&vam->json_tree);
20465
20466   vat_json_init_object (node);
20467   vat_json_object_add_uint (node, "sw_if_index",
20468                             ntohl (mp->tunnel.sw_if_index));
20469   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20470   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20471   vat_json_object_add_uint (node, "local_sa_id",
20472                             ntohl (mp->tunnel.local_sa_id));
20473   vat_json_object_add_uint (node, "remote_sa_id",
20474                             ntohl (mp->tunnel.remote_sa_id));
20475 }
20476
20477 static int
20478 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20479 {
20480   unformat_input_t *i = vam->input;
20481   vl_api_ipsec_gre_tunnel_dump_t *mp;
20482   vl_api_control_ping_t *mp_ping;
20483   u32 sw_if_index;
20484   u8 sw_if_index_set = 0;
20485   int ret;
20486
20487   /* Parse args required to build the message */
20488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20489     {
20490       if (unformat (i, "sw_if_index %d", &sw_if_index))
20491         sw_if_index_set = 1;
20492       else
20493         break;
20494     }
20495
20496   if (sw_if_index_set == 0)
20497     {
20498       sw_if_index = ~0;
20499     }
20500
20501   if (!vam->json_output)
20502     {
20503       print (vam->ofp, "%11s%15s%15s%14s%14s",
20504              "sw_if_index", "src_address", "dst_address",
20505              "local_sa_id", "remote_sa_id");
20506     }
20507
20508   /* Get list of gre-tunnel interfaces */
20509   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20510
20511   mp->sw_if_index = htonl (sw_if_index);
20512
20513   S (mp);
20514
20515   /* Use a control ping for synchronization */
20516   MPING (CONTROL_PING, mp_ping);
20517   S (mp_ping);
20518
20519   W (ret);
20520   return ret;
20521 }
20522
20523 static int
20524 api_delete_subif (vat_main_t * vam)
20525 {
20526   unformat_input_t *i = vam->input;
20527   vl_api_delete_subif_t *mp;
20528   u32 sw_if_index = ~0;
20529   int ret;
20530
20531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20532     {
20533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20534         ;
20535       if (unformat (i, "sw_if_index %d", &sw_if_index))
20536         ;
20537       else
20538         break;
20539     }
20540
20541   if (sw_if_index == ~0)
20542     {
20543       errmsg ("missing sw_if_index");
20544       return -99;
20545     }
20546
20547   /* Construct the API message */
20548   M (DELETE_SUBIF, mp);
20549   mp->sw_if_index = ntohl (sw_if_index);
20550
20551   S (mp);
20552   W (ret);
20553   return ret;
20554 }
20555
20556 #define foreach_pbb_vtr_op      \
20557 _("disable",  L2_VTR_DISABLED)  \
20558 _("pop",  L2_VTR_POP_2)         \
20559 _("push",  L2_VTR_PUSH_2)
20560
20561 static int
20562 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20563 {
20564   unformat_input_t *i = vam->input;
20565   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20566   u32 sw_if_index = ~0, vtr_op = ~0;
20567   u16 outer_tag = ~0;
20568   u8 dmac[6], smac[6];
20569   u8 dmac_set = 0, smac_set = 0;
20570   u16 vlanid = 0;
20571   u32 sid = ~0;
20572   u32 tmp;
20573   int ret;
20574
20575   /* Shut up coverity */
20576   clib_memset (dmac, 0, sizeof (dmac));
20577   clib_memset (smac, 0, sizeof (smac));
20578
20579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20580     {
20581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20582         ;
20583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20584         ;
20585       else if (unformat (i, "vtr_op %d", &vtr_op))
20586         ;
20587 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20588       foreach_pbb_vtr_op
20589 #undef _
20590         else if (unformat (i, "translate_pbb_stag"))
20591         {
20592           if (unformat (i, "%d", &tmp))
20593             {
20594               vtr_op = L2_VTR_TRANSLATE_2_1;
20595               outer_tag = tmp;
20596             }
20597           else
20598             {
20599               errmsg
20600                 ("translate_pbb_stag operation requires outer tag definition");
20601               return -99;
20602             }
20603         }
20604       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20605         dmac_set++;
20606       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20607         smac_set++;
20608       else if (unformat (i, "sid %d", &sid))
20609         ;
20610       else if (unformat (i, "vlanid %d", &tmp))
20611         vlanid = tmp;
20612       else
20613         {
20614           clib_warning ("parse error '%U'", format_unformat_error, i);
20615           return -99;
20616         }
20617     }
20618
20619   if ((sw_if_index == ~0) || (vtr_op == ~0))
20620     {
20621       errmsg ("missing sw_if_index or vtr operation");
20622       return -99;
20623     }
20624   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20625       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20626     {
20627       errmsg
20628         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20629       return -99;
20630     }
20631
20632   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20633   mp->sw_if_index = ntohl (sw_if_index);
20634   mp->vtr_op = ntohl (vtr_op);
20635   mp->outer_tag = ntohs (outer_tag);
20636   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20637   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20638   mp->b_vlanid = ntohs (vlanid);
20639   mp->i_sid = ntohl (sid);
20640
20641   S (mp);
20642   W (ret);
20643   return ret;
20644 }
20645
20646 static int
20647 api_flow_classify_set_interface (vat_main_t * vam)
20648 {
20649   unformat_input_t *i = vam->input;
20650   vl_api_flow_classify_set_interface_t *mp;
20651   u32 sw_if_index;
20652   int sw_if_index_set;
20653   u32 ip4_table_index = ~0;
20654   u32 ip6_table_index = ~0;
20655   u8 is_add = 1;
20656   int ret;
20657
20658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20659     {
20660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20661         sw_if_index_set = 1;
20662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20663         sw_if_index_set = 1;
20664       else if (unformat (i, "del"))
20665         is_add = 0;
20666       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20667         ;
20668       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20669         ;
20670       else
20671         {
20672           clib_warning ("parse error '%U'", format_unformat_error, i);
20673           return -99;
20674         }
20675     }
20676
20677   if (sw_if_index_set == 0)
20678     {
20679       errmsg ("missing interface name or sw_if_index");
20680       return -99;
20681     }
20682
20683   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20684
20685   mp->sw_if_index = ntohl (sw_if_index);
20686   mp->ip4_table_index = ntohl (ip4_table_index);
20687   mp->ip6_table_index = ntohl (ip6_table_index);
20688   mp->is_add = is_add;
20689
20690   S (mp);
20691   W (ret);
20692   return ret;
20693 }
20694
20695 static int
20696 api_flow_classify_dump (vat_main_t * vam)
20697 {
20698   unformat_input_t *i = vam->input;
20699   vl_api_flow_classify_dump_t *mp;
20700   vl_api_control_ping_t *mp_ping;
20701   u8 type = FLOW_CLASSIFY_N_TABLES;
20702   int ret;
20703
20704   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20705     ;
20706   else
20707     {
20708       errmsg ("classify table type must be specified");
20709       return -99;
20710     }
20711
20712   if (!vam->json_output)
20713     {
20714       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20715     }
20716
20717   M (FLOW_CLASSIFY_DUMP, mp);
20718   mp->type = type;
20719   /* send it... */
20720   S (mp);
20721
20722   /* Use a control ping for synchronization */
20723   MPING (CONTROL_PING, mp_ping);
20724   S (mp_ping);
20725
20726   /* Wait for a reply... */
20727   W (ret);
20728   return ret;
20729 }
20730
20731 static int
20732 api_feature_enable_disable (vat_main_t * vam)
20733 {
20734   unformat_input_t *i = vam->input;
20735   vl_api_feature_enable_disable_t *mp;
20736   u8 *arc_name = 0;
20737   u8 *feature_name = 0;
20738   u32 sw_if_index = ~0;
20739   u8 enable = 1;
20740   int ret;
20741
20742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20743     {
20744       if (unformat (i, "arc_name %s", &arc_name))
20745         ;
20746       else if (unformat (i, "feature_name %s", &feature_name))
20747         ;
20748       else
20749         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20750         ;
20751       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20752         ;
20753       else if (unformat (i, "disable"))
20754         enable = 0;
20755       else
20756         break;
20757     }
20758
20759   if (arc_name == 0)
20760     {
20761       errmsg ("missing arc name");
20762       return -99;
20763     }
20764   if (vec_len (arc_name) > 63)
20765     {
20766       errmsg ("arc name too long");
20767     }
20768
20769   if (feature_name == 0)
20770     {
20771       errmsg ("missing feature name");
20772       return -99;
20773     }
20774   if (vec_len (feature_name) > 63)
20775     {
20776       errmsg ("feature name too long");
20777     }
20778
20779   if (sw_if_index == ~0)
20780     {
20781       errmsg ("missing interface name or sw_if_index");
20782       return -99;
20783     }
20784
20785   /* Construct the API message */
20786   M (FEATURE_ENABLE_DISABLE, mp);
20787   mp->sw_if_index = ntohl (sw_if_index);
20788   mp->enable = enable;
20789   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20790   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20791   vec_free (arc_name);
20792   vec_free (feature_name);
20793
20794   S (mp);
20795   W (ret);
20796   return ret;
20797 }
20798
20799 static int
20800 api_sw_interface_tag_add_del (vat_main_t * vam)
20801 {
20802   unformat_input_t *i = vam->input;
20803   vl_api_sw_interface_tag_add_del_t *mp;
20804   u32 sw_if_index = ~0;
20805   u8 *tag = 0;
20806   u8 enable = 1;
20807   int ret;
20808
20809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20810     {
20811       if (unformat (i, "tag %s", &tag))
20812         ;
20813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20814         ;
20815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20816         ;
20817       else if (unformat (i, "del"))
20818         enable = 0;
20819       else
20820         break;
20821     }
20822
20823   if (sw_if_index == ~0)
20824     {
20825       errmsg ("missing interface name or sw_if_index");
20826       return -99;
20827     }
20828
20829   if (enable && (tag == 0))
20830     {
20831       errmsg ("no tag specified");
20832       return -99;
20833     }
20834
20835   /* Construct the API message */
20836   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20837   mp->sw_if_index = ntohl (sw_if_index);
20838   mp->is_add = enable;
20839   if (enable)
20840     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20841   vec_free (tag);
20842
20843   S (mp);
20844   W (ret);
20845   return ret;
20846 }
20847
20848 static void vl_api_l2_xconnect_details_t_handler
20849   (vl_api_l2_xconnect_details_t * mp)
20850 {
20851   vat_main_t *vam = &vat_main;
20852
20853   print (vam->ofp, "%15d%15d",
20854          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20855 }
20856
20857 static void vl_api_l2_xconnect_details_t_handler_json
20858   (vl_api_l2_xconnect_details_t * mp)
20859 {
20860   vat_main_t *vam = &vat_main;
20861   vat_json_node_t *node = NULL;
20862
20863   if (VAT_JSON_ARRAY != vam->json_tree.type)
20864     {
20865       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20866       vat_json_init_array (&vam->json_tree);
20867     }
20868   node = vat_json_array_add (&vam->json_tree);
20869
20870   vat_json_init_object (node);
20871   vat_json_object_add_uint (node, "rx_sw_if_index",
20872                             ntohl (mp->rx_sw_if_index));
20873   vat_json_object_add_uint (node, "tx_sw_if_index",
20874                             ntohl (mp->tx_sw_if_index));
20875 }
20876
20877 static int
20878 api_l2_xconnect_dump (vat_main_t * vam)
20879 {
20880   vl_api_l2_xconnect_dump_t *mp;
20881   vl_api_control_ping_t *mp_ping;
20882   int ret;
20883
20884   if (!vam->json_output)
20885     {
20886       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20887     }
20888
20889   M (L2_XCONNECT_DUMP, mp);
20890
20891   S (mp);
20892
20893   /* Use a control ping for synchronization */
20894   MPING (CONTROL_PING, mp_ping);
20895   S (mp_ping);
20896
20897   W (ret);
20898   return ret;
20899 }
20900
20901 static int
20902 api_hw_interface_set_mtu (vat_main_t * vam)
20903 {
20904   unformat_input_t *i = vam->input;
20905   vl_api_hw_interface_set_mtu_t *mp;
20906   u32 sw_if_index = ~0;
20907   u32 mtu = 0;
20908   int ret;
20909
20910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20911     {
20912       if (unformat (i, "mtu %d", &mtu))
20913         ;
20914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20915         ;
20916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20917         ;
20918       else
20919         break;
20920     }
20921
20922   if (sw_if_index == ~0)
20923     {
20924       errmsg ("missing interface name or sw_if_index");
20925       return -99;
20926     }
20927
20928   if (mtu == 0)
20929     {
20930       errmsg ("no mtu specified");
20931       return -99;
20932     }
20933
20934   /* Construct the API message */
20935   M (HW_INTERFACE_SET_MTU, mp);
20936   mp->sw_if_index = ntohl (sw_if_index);
20937   mp->mtu = ntohs ((u16) mtu);
20938
20939   S (mp);
20940   W (ret);
20941   return ret;
20942 }
20943
20944 static int
20945 api_p2p_ethernet_add (vat_main_t * vam)
20946 {
20947   unformat_input_t *i = vam->input;
20948   vl_api_p2p_ethernet_add_t *mp;
20949   u32 parent_if_index = ~0;
20950   u32 sub_id = ~0;
20951   u8 remote_mac[6];
20952   u8 mac_set = 0;
20953   int ret;
20954
20955   clib_memset (remote_mac, 0, sizeof (remote_mac));
20956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20957     {
20958       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20959         ;
20960       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20961         ;
20962       else
20963         if (unformat
20964             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20965         mac_set++;
20966       else if (unformat (i, "sub_id %d", &sub_id))
20967         ;
20968       else
20969         {
20970           clib_warning ("parse error '%U'", format_unformat_error, i);
20971           return -99;
20972         }
20973     }
20974
20975   if (parent_if_index == ~0)
20976     {
20977       errmsg ("missing interface name or sw_if_index");
20978       return -99;
20979     }
20980   if (mac_set == 0)
20981     {
20982       errmsg ("missing remote mac address");
20983       return -99;
20984     }
20985   if (sub_id == ~0)
20986     {
20987       errmsg ("missing sub-interface id");
20988       return -99;
20989     }
20990
20991   M (P2P_ETHERNET_ADD, mp);
20992   mp->parent_if_index = ntohl (parent_if_index);
20993   mp->subif_id = ntohl (sub_id);
20994   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20995
20996   S (mp);
20997   W (ret);
20998   return ret;
20999 }
21000
21001 static int
21002 api_p2p_ethernet_del (vat_main_t * vam)
21003 {
21004   unformat_input_t *i = vam->input;
21005   vl_api_p2p_ethernet_del_t *mp;
21006   u32 parent_if_index = ~0;
21007   u8 remote_mac[6];
21008   u8 mac_set = 0;
21009   int ret;
21010
21011   clib_memset (remote_mac, 0, sizeof (remote_mac));
21012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21013     {
21014       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21015         ;
21016       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21017         ;
21018       else
21019         if (unformat
21020             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21021         mac_set++;
21022       else
21023         {
21024           clib_warning ("parse error '%U'", format_unformat_error, i);
21025           return -99;
21026         }
21027     }
21028
21029   if (parent_if_index == ~0)
21030     {
21031       errmsg ("missing interface name or sw_if_index");
21032       return -99;
21033     }
21034   if (mac_set == 0)
21035     {
21036       errmsg ("missing remote mac address");
21037       return -99;
21038     }
21039
21040   M (P2P_ETHERNET_DEL, mp);
21041   mp->parent_if_index = ntohl (parent_if_index);
21042   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21043
21044   S (mp);
21045   W (ret);
21046   return ret;
21047 }
21048
21049 static int
21050 api_lldp_config (vat_main_t * vam)
21051 {
21052   unformat_input_t *i = vam->input;
21053   vl_api_lldp_config_t *mp;
21054   int tx_hold = 0;
21055   int tx_interval = 0;
21056   u8 *sys_name = NULL;
21057   int ret;
21058
21059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21060     {
21061       if (unformat (i, "system-name %s", &sys_name))
21062         ;
21063       else if (unformat (i, "tx-hold %d", &tx_hold))
21064         ;
21065       else if (unformat (i, "tx-interval %d", &tx_interval))
21066         ;
21067       else
21068         {
21069           clib_warning ("parse error '%U'", format_unformat_error, i);
21070           return -99;
21071         }
21072     }
21073
21074   vec_add1 (sys_name, 0);
21075
21076   M (LLDP_CONFIG, mp);
21077   mp->tx_hold = htonl (tx_hold);
21078   mp->tx_interval = htonl (tx_interval);
21079   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21080   vec_free (sys_name);
21081
21082   S (mp);
21083   W (ret);
21084   return ret;
21085 }
21086
21087 static int
21088 api_sw_interface_set_lldp (vat_main_t * vam)
21089 {
21090   unformat_input_t *i = vam->input;
21091   vl_api_sw_interface_set_lldp_t *mp;
21092   u32 sw_if_index = ~0;
21093   u32 enable = 1;
21094   u8 *port_desc = NULL, *mgmt_oid = NULL;
21095   ip4_address_t ip4_addr;
21096   ip6_address_t ip6_addr;
21097   int ret;
21098
21099   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21100   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21101
21102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21103     {
21104       if (unformat (i, "disable"))
21105         enable = 0;
21106       else
21107         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21108         ;
21109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21110         ;
21111       else if (unformat (i, "port-desc %s", &port_desc))
21112         ;
21113       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21114         ;
21115       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21116         ;
21117       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21118         ;
21119       else
21120         break;
21121     }
21122
21123   if (sw_if_index == ~0)
21124     {
21125       errmsg ("missing interface name or sw_if_index");
21126       return -99;
21127     }
21128
21129   /* Construct the API message */
21130   vec_add1 (port_desc, 0);
21131   vec_add1 (mgmt_oid, 0);
21132   M (SW_INTERFACE_SET_LLDP, mp);
21133   mp->sw_if_index = ntohl (sw_if_index);
21134   mp->enable = enable;
21135   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21136   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21137   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21138   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21139   vec_free (port_desc);
21140   vec_free (mgmt_oid);
21141
21142   S (mp);
21143   W (ret);
21144   return ret;
21145 }
21146
21147 static int
21148 api_tcp_configure_src_addresses (vat_main_t * vam)
21149 {
21150   vl_api_tcp_configure_src_addresses_t *mp;
21151   unformat_input_t *i = vam->input;
21152   ip4_address_t v4first, v4last;
21153   ip6_address_t v6first, v6last;
21154   u8 range_set = 0;
21155   u32 vrf_id = 0;
21156   int ret;
21157
21158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21159     {
21160       if (unformat (i, "%U - %U",
21161                     unformat_ip4_address, &v4first,
21162                     unformat_ip4_address, &v4last))
21163         {
21164           if (range_set)
21165             {
21166               errmsg ("one range per message (range already set)");
21167               return -99;
21168             }
21169           range_set = 1;
21170         }
21171       else if (unformat (i, "%U - %U",
21172                          unformat_ip6_address, &v6first,
21173                          unformat_ip6_address, &v6last))
21174         {
21175           if (range_set)
21176             {
21177               errmsg ("one range per message (range already set)");
21178               return -99;
21179             }
21180           range_set = 2;
21181         }
21182       else if (unformat (i, "vrf %d", &vrf_id))
21183         ;
21184       else
21185         break;
21186     }
21187
21188   if (range_set == 0)
21189     {
21190       errmsg ("address range not set");
21191       return -99;
21192     }
21193
21194   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21195   mp->vrf_id = ntohl (vrf_id);
21196   /* ipv6? */
21197   if (range_set == 2)
21198     {
21199       mp->is_ipv6 = 1;
21200       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21201       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21202     }
21203   else
21204     {
21205       mp->is_ipv6 = 0;
21206       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21207       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21208     }
21209   S (mp);
21210   W (ret);
21211   return ret;
21212 }
21213
21214 static void vl_api_app_namespace_add_del_reply_t_handler
21215   (vl_api_app_namespace_add_del_reply_t * mp)
21216 {
21217   vat_main_t *vam = &vat_main;
21218   i32 retval = ntohl (mp->retval);
21219   if (vam->async_mode)
21220     {
21221       vam->async_errors += (retval < 0);
21222     }
21223   else
21224     {
21225       vam->retval = retval;
21226       if (retval == 0)
21227         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21228       vam->result_ready = 1;
21229     }
21230 }
21231
21232 static void vl_api_app_namespace_add_del_reply_t_handler_json
21233   (vl_api_app_namespace_add_del_reply_t * mp)
21234 {
21235   vat_main_t *vam = &vat_main;
21236   vat_json_node_t node;
21237
21238   vat_json_init_object (&node);
21239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21240   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21241
21242   vat_json_print (vam->ofp, &node);
21243   vat_json_free (&node);
21244
21245   vam->retval = ntohl (mp->retval);
21246   vam->result_ready = 1;
21247 }
21248
21249 static int
21250 api_app_namespace_add_del (vat_main_t * vam)
21251 {
21252   vl_api_app_namespace_add_del_t *mp;
21253   unformat_input_t *i = vam->input;
21254   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21255   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21256   u64 secret;
21257   int ret;
21258
21259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21260     {
21261       if (unformat (i, "id %_%v%_", &ns_id))
21262         ;
21263       else if (unformat (i, "secret %lu", &secret))
21264         secret_set = 1;
21265       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21266         sw_if_index_set = 1;
21267       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21268         ;
21269       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21270         ;
21271       else
21272         break;
21273     }
21274   if (!ns_id || !secret_set || !sw_if_index_set)
21275     {
21276       errmsg ("namespace id, secret and sw_if_index must be set");
21277       return -99;
21278     }
21279   if (vec_len (ns_id) > 64)
21280     {
21281       errmsg ("namespace id too long");
21282       return -99;
21283     }
21284   M (APP_NAMESPACE_ADD_DEL, mp);
21285
21286   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21287   mp->namespace_id_len = vec_len (ns_id);
21288   mp->secret = clib_host_to_net_u64 (secret);
21289   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21290   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21291   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21292   vec_free (ns_id);
21293   S (mp);
21294   W (ret);
21295   return ret;
21296 }
21297
21298 static int
21299 api_sock_init_shm (vat_main_t * vam)
21300 {
21301 #if VPP_API_TEST_BUILTIN == 0
21302   unformat_input_t *i = vam->input;
21303   vl_api_shm_elem_config_t *config = 0;
21304   u64 size = 64 << 20;
21305   int rv;
21306
21307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21308     {
21309       if (unformat (i, "size %U", unformat_memory_size, &size))
21310         ;
21311       else
21312         break;
21313     }
21314
21315   /*
21316    * Canned custom ring allocator config.
21317    * Should probably parse all of this
21318    */
21319   vec_validate (config, 6);
21320   config[0].type = VL_API_VLIB_RING;
21321   config[0].size = 256;
21322   config[0].count = 32;
21323
21324   config[1].type = VL_API_VLIB_RING;
21325   config[1].size = 1024;
21326   config[1].count = 16;
21327
21328   config[2].type = VL_API_VLIB_RING;
21329   config[2].size = 4096;
21330   config[2].count = 2;
21331
21332   config[3].type = VL_API_CLIENT_RING;
21333   config[3].size = 256;
21334   config[3].count = 32;
21335
21336   config[4].type = VL_API_CLIENT_RING;
21337   config[4].size = 1024;
21338   config[4].count = 16;
21339
21340   config[5].type = VL_API_CLIENT_RING;
21341   config[5].size = 4096;
21342   config[5].count = 2;
21343
21344   config[6].type = VL_API_QUEUE;
21345   config[6].count = 128;
21346   config[6].size = sizeof (uword);
21347
21348   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21349   if (!rv)
21350     vam->client_index_invalid = 1;
21351   return rv;
21352 #else
21353   return -99;
21354 #endif
21355 }
21356
21357 static int
21358 api_dns_enable_disable (vat_main_t * vam)
21359 {
21360   unformat_input_t *line_input = vam->input;
21361   vl_api_dns_enable_disable_t *mp;
21362   u8 enable_disable = 1;
21363   int ret;
21364
21365   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21366     {
21367       if (unformat (line_input, "disable"))
21368         enable_disable = 0;
21369       if (unformat (line_input, "enable"))
21370         enable_disable = 1;
21371       else
21372         break;
21373     }
21374
21375   /* Construct the API message */
21376   M (DNS_ENABLE_DISABLE, mp);
21377   mp->enable = enable_disable;
21378
21379   /* send it... */
21380   S (mp);
21381   /* Wait for the reply */
21382   W (ret);
21383   return ret;
21384 }
21385
21386 static int
21387 api_dns_resolve_name (vat_main_t * vam)
21388 {
21389   unformat_input_t *line_input = vam->input;
21390   vl_api_dns_resolve_name_t *mp;
21391   u8 *name = 0;
21392   int ret;
21393
21394   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21395     {
21396       if (unformat (line_input, "%s", &name))
21397         ;
21398       else
21399         break;
21400     }
21401
21402   if (vec_len (name) > 127)
21403     {
21404       errmsg ("name too long");
21405       return -99;
21406     }
21407
21408   /* Construct the API message */
21409   M (DNS_RESOLVE_NAME, mp);
21410   memcpy (mp->name, name, vec_len (name));
21411   vec_free (name);
21412
21413   /* send it... */
21414   S (mp);
21415   /* Wait for the reply */
21416   W (ret);
21417   return ret;
21418 }
21419
21420 static int
21421 api_dns_resolve_ip (vat_main_t * vam)
21422 {
21423   unformat_input_t *line_input = vam->input;
21424   vl_api_dns_resolve_ip_t *mp;
21425   int is_ip6 = -1;
21426   ip4_address_t addr4;
21427   ip6_address_t addr6;
21428   int ret;
21429
21430   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21431     {
21432       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21433         is_ip6 = 1;
21434       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21435         is_ip6 = 0;
21436       else
21437         break;
21438     }
21439
21440   if (is_ip6 == -1)
21441     {
21442       errmsg ("missing address");
21443       return -99;
21444     }
21445
21446   /* Construct the API message */
21447   M (DNS_RESOLVE_IP, mp);
21448   mp->is_ip6 = is_ip6;
21449   if (is_ip6)
21450     memcpy (mp->address, &addr6, sizeof (addr6));
21451   else
21452     memcpy (mp->address, &addr4, sizeof (addr4));
21453
21454   /* send it... */
21455   S (mp);
21456   /* Wait for the reply */
21457   W (ret);
21458   return ret;
21459 }
21460
21461 static int
21462 api_dns_name_server_add_del (vat_main_t * vam)
21463 {
21464   unformat_input_t *i = vam->input;
21465   vl_api_dns_name_server_add_del_t *mp;
21466   u8 is_add = 1;
21467   ip6_address_t ip6_server;
21468   ip4_address_t ip4_server;
21469   int ip6_set = 0;
21470   int ip4_set = 0;
21471   int ret = 0;
21472
21473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21474     {
21475       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21476         ip6_set = 1;
21477       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21478         ip4_set = 1;
21479       else if (unformat (i, "del"))
21480         is_add = 0;
21481       else
21482         {
21483           clib_warning ("parse error '%U'", format_unformat_error, i);
21484           return -99;
21485         }
21486     }
21487
21488   if (ip4_set && ip6_set)
21489     {
21490       errmsg ("Only one server address allowed per message");
21491       return -99;
21492     }
21493   if ((ip4_set + ip6_set) == 0)
21494     {
21495       errmsg ("Server address required");
21496       return -99;
21497     }
21498
21499   /* Construct the API message */
21500   M (DNS_NAME_SERVER_ADD_DEL, mp);
21501
21502   if (ip6_set)
21503     {
21504       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21505       mp->is_ip6 = 1;
21506     }
21507   else
21508     {
21509       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21510       mp->is_ip6 = 0;
21511     }
21512
21513   mp->is_add = is_add;
21514
21515   /* send it... */
21516   S (mp);
21517
21518   /* Wait for a reply, return good/bad news  */
21519   W (ret);
21520   return ret;
21521 }
21522
21523 static void
21524 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21525 {
21526   vat_main_t *vam = &vat_main;
21527
21528   if (mp->is_ip4)
21529     {
21530       print (vam->ofp,
21531              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21532              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21533              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21534              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21535              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21536              clib_net_to_host_u32 (mp->action_index), mp->tag);
21537     }
21538   else
21539     {
21540       print (vam->ofp,
21541              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21542              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21543              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21544              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21545              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21546              clib_net_to_host_u32 (mp->action_index), mp->tag);
21547     }
21548 }
21549
21550 static void
21551 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21552                                              mp)
21553 {
21554   vat_main_t *vam = &vat_main;
21555   vat_json_node_t *node = NULL;
21556   struct in6_addr ip6;
21557   struct in_addr ip4;
21558
21559   if (VAT_JSON_ARRAY != vam->json_tree.type)
21560     {
21561       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21562       vat_json_init_array (&vam->json_tree);
21563     }
21564   node = vat_json_array_add (&vam->json_tree);
21565   vat_json_init_object (node);
21566
21567   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21568   vat_json_object_add_uint (node, "appns_index",
21569                             clib_net_to_host_u32 (mp->appns_index));
21570   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21571   vat_json_object_add_uint (node, "scope", mp->scope);
21572   vat_json_object_add_uint (node, "action_index",
21573                             clib_net_to_host_u32 (mp->action_index));
21574   vat_json_object_add_uint (node, "lcl_port",
21575                             clib_net_to_host_u16 (mp->lcl_port));
21576   vat_json_object_add_uint (node, "rmt_port",
21577                             clib_net_to_host_u16 (mp->rmt_port));
21578   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21579   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21580   vat_json_object_add_string_copy (node, "tag", mp->tag);
21581   if (mp->is_ip4)
21582     {
21583       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21584       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21585       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21586       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21587     }
21588   else
21589     {
21590       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21591       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21592       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21593       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21594     }
21595 }
21596
21597 static int
21598 api_session_rule_add_del (vat_main_t * vam)
21599 {
21600   vl_api_session_rule_add_del_t *mp;
21601   unformat_input_t *i = vam->input;
21602   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21603   u32 appns_index = 0, scope = 0;
21604   ip4_address_t lcl_ip4, rmt_ip4;
21605   ip6_address_t lcl_ip6, rmt_ip6;
21606   u8 is_ip4 = 1, conn_set = 0;
21607   u8 is_add = 1, *tag = 0;
21608   int ret;
21609
21610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21611     {
21612       if (unformat (i, "del"))
21613         is_add = 0;
21614       else if (unformat (i, "add"))
21615         ;
21616       else if (unformat (i, "proto tcp"))
21617         proto = 0;
21618       else if (unformat (i, "proto udp"))
21619         proto = 1;
21620       else if (unformat (i, "appns %d", &appns_index))
21621         ;
21622       else if (unformat (i, "scope %d", &scope))
21623         ;
21624       else if (unformat (i, "tag %_%v%_", &tag))
21625         ;
21626       else
21627         if (unformat
21628             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21629              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21630              &rmt_port))
21631         {
21632           is_ip4 = 1;
21633           conn_set = 1;
21634         }
21635       else
21636         if (unformat
21637             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21638              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21639              &rmt_port))
21640         {
21641           is_ip4 = 0;
21642           conn_set = 1;
21643         }
21644       else if (unformat (i, "action %d", &action))
21645         ;
21646       else
21647         break;
21648     }
21649   if (proto == ~0 || !conn_set || action == ~0)
21650     {
21651       errmsg ("transport proto, connection and action must be set");
21652       return -99;
21653     }
21654
21655   if (scope > 3)
21656     {
21657       errmsg ("scope should be 0-3");
21658       return -99;
21659     }
21660
21661   M (SESSION_RULE_ADD_DEL, mp);
21662
21663   mp->is_ip4 = is_ip4;
21664   mp->transport_proto = proto;
21665   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21666   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21667   mp->lcl_plen = lcl_plen;
21668   mp->rmt_plen = rmt_plen;
21669   mp->action_index = clib_host_to_net_u32 (action);
21670   mp->appns_index = clib_host_to_net_u32 (appns_index);
21671   mp->scope = scope;
21672   mp->is_add = is_add;
21673   if (is_ip4)
21674     {
21675       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21676       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21677     }
21678   else
21679     {
21680       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21681       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21682     }
21683   if (tag)
21684     {
21685       clib_memcpy (mp->tag, tag, vec_len (tag));
21686       vec_free (tag);
21687     }
21688
21689   S (mp);
21690   W (ret);
21691   return ret;
21692 }
21693
21694 static int
21695 api_session_rules_dump (vat_main_t * vam)
21696 {
21697   vl_api_session_rules_dump_t *mp;
21698   vl_api_control_ping_t *mp_ping;
21699   int ret;
21700
21701   if (!vam->json_output)
21702     {
21703       print (vam->ofp, "%=20s", "Session Rules");
21704     }
21705
21706   M (SESSION_RULES_DUMP, mp);
21707   /* send it... */
21708   S (mp);
21709
21710   /* Use a control ping for synchronization */
21711   MPING (CONTROL_PING, mp_ping);
21712   S (mp_ping);
21713
21714   /* Wait for a reply... */
21715   W (ret);
21716   return ret;
21717 }
21718
21719 static int
21720 api_ip_container_proxy_add_del (vat_main_t * vam)
21721 {
21722   vl_api_ip_container_proxy_add_del_t *mp;
21723   unformat_input_t *i = vam->input;
21724   u32 sw_if_index = ~0;
21725   vl_api_prefix_t pfx = { };
21726   u8 is_add = 1;
21727   int ret;
21728
21729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21730     {
21731       if (unformat (i, "del"))
21732         is_add = 0;
21733       else if (unformat (i, "add"))
21734         ;
21735       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21736         ;
21737       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21738         ;
21739       else
21740         break;
21741     }
21742   if (sw_if_index == ~0 || pfx.address_length == 0)
21743     {
21744       errmsg ("address and sw_if_index must be set");
21745       return -99;
21746     }
21747
21748   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21749
21750   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21751   mp->is_add = is_add;
21752   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21753
21754   S (mp);
21755   W (ret);
21756   return ret;
21757 }
21758
21759 static int
21760 api_qos_record_enable_disable (vat_main_t * vam)
21761 {
21762   unformat_input_t *i = vam->input;
21763   vl_api_qos_record_enable_disable_t *mp;
21764   u32 sw_if_index, qs = 0xff;
21765   u8 sw_if_index_set = 0;
21766   u8 enable = 1;
21767   int ret;
21768
21769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21770     {
21771       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21772         sw_if_index_set = 1;
21773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21774         sw_if_index_set = 1;
21775       else if (unformat (i, "%U", unformat_qos_source, &qs))
21776         ;
21777       else if (unformat (i, "disable"))
21778         enable = 0;
21779       else
21780         {
21781           clib_warning ("parse error '%U'", format_unformat_error, i);
21782           return -99;
21783         }
21784     }
21785
21786   if (sw_if_index_set == 0)
21787     {
21788       errmsg ("missing interface name or sw_if_index");
21789       return -99;
21790     }
21791   if (qs == 0xff)
21792     {
21793       errmsg ("input location must be specified");
21794       return -99;
21795     }
21796
21797   M (QOS_RECORD_ENABLE_DISABLE, mp);
21798
21799   mp->sw_if_index = ntohl (sw_if_index);
21800   mp->input_source = qs;
21801   mp->enable = enable;
21802
21803   S (mp);
21804   W (ret);
21805   return ret;
21806 }
21807
21808
21809 static int
21810 q_or_quit (vat_main_t * vam)
21811 {
21812 #if VPP_API_TEST_BUILTIN == 0
21813   longjmp (vam->jump_buf, 1);
21814 #endif
21815   return 0;                     /* not so much */
21816 }
21817
21818 static int
21819 q (vat_main_t * vam)
21820 {
21821   return q_or_quit (vam);
21822 }
21823
21824 static int
21825 quit (vat_main_t * vam)
21826 {
21827   return q_or_quit (vam);
21828 }
21829
21830 static int
21831 comment (vat_main_t * vam)
21832 {
21833   return 0;
21834 }
21835
21836 static int
21837 statseg (vat_main_t * vam)
21838 {
21839   ssvm_private_t *ssvmp = &vam->stat_segment;
21840   ssvm_shared_header_t *shared_header = ssvmp->sh;
21841   vlib_counter_t **counters;
21842   u64 thread0_index1_packets;
21843   u64 thread0_index1_bytes;
21844   f64 vector_rate, input_rate;
21845   uword *p;
21846
21847   uword *counter_vector_by_name;
21848   if (vam->stat_segment_lockp == 0)
21849     {
21850       errmsg ("Stat segment not mapped...");
21851       return -99;
21852     }
21853
21854   /* look up "/if/rx for sw_if_index 1 as a test */
21855
21856   clib_spinlock_lock (vam->stat_segment_lockp);
21857
21858   counter_vector_by_name = (uword *) shared_header->opaque[1];
21859
21860   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21861   if (p == 0)
21862     {
21863       clib_spinlock_unlock (vam->stat_segment_lockp);
21864       errmsg ("/if/tx not found?");
21865       return -99;
21866     }
21867
21868   /* Fish per-thread vector of combined counters from shared memory */
21869   counters = (vlib_counter_t **) p[0];
21870
21871   if (vec_len (counters[0]) < 2)
21872     {
21873       clib_spinlock_unlock (vam->stat_segment_lockp);
21874       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21875       return -99;
21876     }
21877
21878   /* Read thread 0 sw_if_index 1 counter */
21879   thread0_index1_packets = counters[0][1].packets;
21880   thread0_index1_bytes = counters[0][1].bytes;
21881
21882   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21883   if (p == 0)
21884     {
21885       clib_spinlock_unlock (vam->stat_segment_lockp);
21886       errmsg ("vector_rate not found?");
21887       return -99;
21888     }
21889
21890   vector_rate = *(f64 *) (p[0]);
21891   p = hash_get_mem (counter_vector_by_name, "input_rate");
21892   if (p == 0)
21893     {
21894       clib_spinlock_unlock (vam->stat_segment_lockp);
21895       errmsg ("input_rate not found?");
21896       return -99;
21897     }
21898   input_rate = *(f64 *) (p[0]);
21899
21900   clib_spinlock_unlock (vam->stat_segment_lockp);
21901
21902   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21903          vector_rate, input_rate);
21904   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21905          thread0_index1_packets, thread0_index1_bytes);
21906
21907   return 0;
21908 }
21909
21910 static int
21911 cmd_cmp (void *a1, void *a2)
21912 {
21913   u8 **c1 = a1;
21914   u8 **c2 = a2;
21915
21916   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21917 }
21918
21919 static int
21920 help (vat_main_t * vam)
21921 {
21922   u8 **cmds = 0;
21923   u8 *name = 0;
21924   hash_pair_t *p;
21925   unformat_input_t *i = vam->input;
21926   int j;
21927
21928   if (unformat (i, "%s", &name))
21929     {
21930       uword *hs;
21931
21932       vec_add1 (name, 0);
21933
21934       hs = hash_get_mem (vam->help_by_name, name);
21935       if (hs)
21936         print (vam->ofp, "usage: %s %s", name, hs[0]);
21937       else
21938         print (vam->ofp, "No such msg / command '%s'", name);
21939       vec_free (name);
21940       return 0;
21941     }
21942
21943   print (vam->ofp, "Help is available for the following:");
21944
21945     /* *INDENT-OFF* */
21946     hash_foreach_pair (p, vam->function_by_name,
21947     ({
21948       vec_add1 (cmds, (u8 *)(p->key));
21949     }));
21950     /* *INDENT-ON* */
21951
21952   vec_sort_with_function (cmds, cmd_cmp);
21953
21954   for (j = 0; j < vec_len (cmds); j++)
21955     print (vam->ofp, "%s", cmds[j]);
21956
21957   vec_free (cmds);
21958   return 0;
21959 }
21960
21961 static int
21962 set (vat_main_t * vam)
21963 {
21964   u8 *name = 0, *value = 0;
21965   unformat_input_t *i = vam->input;
21966
21967   if (unformat (i, "%s", &name))
21968     {
21969       /* The input buffer is a vector, not a string. */
21970       value = vec_dup (i->buffer);
21971       vec_delete (value, i->index, 0);
21972       /* Almost certainly has a trailing newline */
21973       if (value[vec_len (value) - 1] == '\n')
21974         value[vec_len (value) - 1] = 0;
21975       /* Make sure it's a proper string, one way or the other */
21976       vec_add1 (value, 0);
21977       (void) clib_macro_set_value (&vam->macro_main,
21978                                    (char *) name, (char *) value);
21979     }
21980   else
21981     errmsg ("usage: set <name> <value>");
21982
21983   vec_free (name);
21984   vec_free (value);
21985   return 0;
21986 }
21987
21988 static int
21989 unset (vat_main_t * vam)
21990 {
21991   u8 *name = 0;
21992
21993   if (unformat (vam->input, "%s", &name))
21994     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21995       errmsg ("unset: %s wasn't set", name);
21996   vec_free (name);
21997   return 0;
21998 }
21999
22000 typedef struct
22001 {
22002   u8 *name;
22003   u8 *value;
22004 } macro_sort_t;
22005
22006
22007 static int
22008 macro_sort_cmp (void *a1, void *a2)
22009 {
22010   macro_sort_t *s1 = a1;
22011   macro_sort_t *s2 = a2;
22012
22013   return strcmp ((char *) (s1->name), (char *) (s2->name));
22014 }
22015
22016 static int
22017 dump_macro_table (vat_main_t * vam)
22018 {
22019   macro_sort_t *sort_me = 0, *sm;
22020   int i;
22021   hash_pair_t *p;
22022
22023     /* *INDENT-OFF* */
22024     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22025     ({
22026       vec_add2 (sort_me, sm, 1);
22027       sm->name = (u8 *)(p->key);
22028       sm->value = (u8 *) (p->value[0]);
22029     }));
22030     /* *INDENT-ON* */
22031
22032   vec_sort_with_function (sort_me, macro_sort_cmp);
22033
22034   if (vec_len (sort_me))
22035     print (vam->ofp, "%-15s%s", "Name", "Value");
22036   else
22037     print (vam->ofp, "The macro table is empty...");
22038
22039   for (i = 0; i < vec_len (sort_me); i++)
22040     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22041   return 0;
22042 }
22043
22044 static int
22045 dump_node_table (vat_main_t * vam)
22046 {
22047   int i, j;
22048   vlib_node_t *node, *next_node;
22049
22050   if (vec_len (vam->graph_nodes) == 0)
22051     {
22052       print (vam->ofp, "Node table empty, issue get_node_graph...");
22053       return 0;
22054     }
22055
22056   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22057     {
22058       node = vam->graph_nodes[0][i];
22059       print (vam->ofp, "[%d] %s", i, node->name);
22060       for (j = 0; j < vec_len (node->next_nodes); j++)
22061         {
22062           if (node->next_nodes[j] != ~0)
22063             {
22064               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22065               print (vam->ofp, "  [%d] %s", j, next_node->name);
22066             }
22067         }
22068     }
22069   return 0;
22070 }
22071
22072 static int
22073 value_sort_cmp (void *a1, void *a2)
22074 {
22075   name_sort_t *n1 = a1;
22076   name_sort_t *n2 = a2;
22077
22078   if (n1->value < n2->value)
22079     return -1;
22080   if (n1->value > n2->value)
22081     return 1;
22082   return 0;
22083 }
22084
22085
22086 static int
22087 dump_msg_api_table (vat_main_t * vam)
22088 {
22089   api_main_t *am = &api_main;
22090   name_sort_t *nses = 0, *ns;
22091   hash_pair_t *hp;
22092   int i;
22093
22094   /* *INDENT-OFF* */
22095   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22096   ({
22097     vec_add2 (nses, ns, 1);
22098     ns->name = (u8 *)(hp->key);
22099     ns->value = (u32) hp->value[0];
22100   }));
22101   /* *INDENT-ON* */
22102
22103   vec_sort_with_function (nses, value_sort_cmp);
22104
22105   for (i = 0; i < vec_len (nses); i++)
22106     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22107   vec_free (nses);
22108   return 0;
22109 }
22110
22111 static int
22112 get_msg_id (vat_main_t * vam)
22113 {
22114   u8 *name_and_crc;
22115   u32 message_index;
22116
22117   if (unformat (vam->input, "%s", &name_and_crc))
22118     {
22119       message_index = vl_msg_api_get_msg_index (name_and_crc);
22120       if (message_index == ~0)
22121         {
22122           print (vam->ofp, " '%s' not found", name_and_crc);
22123           return 0;
22124         }
22125       print (vam->ofp, " '%s' has message index %d",
22126              name_and_crc, message_index);
22127       return 0;
22128     }
22129   errmsg ("name_and_crc required...");
22130   return 0;
22131 }
22132
22133 static int
22134 search_node_table (vat_main_t * vam)
22135 {
22136   unformat_input_t *line_input = vam->input;
22137   u8 *node_to_find;
22138   int j;
22139   vlib_node_t *node, *next_node;
22140   uword *p;
22141
22142   if (vam->graph_node_index_by_name == 0)
22143     {
22144       print (vam->ofp, "Node table empty, issue get_node_graph...");
22145       return 0;
22146     }
22147
22148   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22149     {
22150       if (unformat (line_input, "%s", &node_to_find))
22151         {
22152           vec_add1 (node_to_find, 0);
22153           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22154           if (p == 0)
22155             {
22156               print (vam->ofp, "%s not found...", node_to_find);
22157               goto out;
22158             }
22159           node = vam->graph_nodes[0][p[0]];
22160           print (vam->ofp, "[%d] %s", p[0], node->name);
22161           for (j = 0; j < vec_len (node->next_nodes); j++)
22162             {
22163               if (node->next_nodes[j] != ~0)
22164                 {
22165                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22166                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22167                 }
22168             }
22169         }
22170
22171       else
22172         {
22173           clib_warning ("parse error '%U'", format_unformat_error,
22174                         line_input);
22175           return -99;
22176         }
22177
22178     out:
22179       vec_free (node_to_find);
22180
22181     }
22182
22183   return 0;
22184 }
22185
22186
22187 static int
22188 script (vat_main_t * vam)
22189 {
22190 #if (VPP_API_TEST_BUILTIN==0)
22191   u8 *s = 0;
22192   char *save_current_file;
22193   unformat_input_t save_input;
22194   jmp_buf save_jump_buf;
22195   u32 save_line_number;
22196
22197   FILE *new_fp, *save_ifp;
22198
22199   if (unformat (vam->input, "%s", &s))
22200     {
22201       new_fp = fopen ((char *) s, "r");
22202       if (new_fp == 0)
22203         {
22204           errmsg ("Couldn't open script file %s", s);
22205           vec_free (s);
22206           return -99;
22207         }
22208     }
22209   else
22210     {
22211       errmsg ("Missing script name");
22212       return -99;
22213     }
22214
22215   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22216   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22217   save_ifp = vam->ifp;
22218   save_line_number = vam->input_line_number;
22219   save_current_file = (char *) vam->current_file;
22220
22221   vam->input_line_number = 0;
22222   vam->ifp = new_fp;
22223   vam->current_file = s;
22224   do_one_file (vam);
22225
22226   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22227   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22228   vam->ifp = save_ifp;
22229   vam->input_line_number = save_line_number;
22230   vam->current_file = (u8 *) save_current_file;
22231   vec_free (s);
22232
22233   return 0;
22234 #else
22235   clib_warning ("use the exec command...");
22236   return -99;
22237 #endif
22238 }
22239
22240 static int
22241 echo (vat_main_t * vam)
22242 {
22243   print (vam->ofp, "%v", vam->input->buffer);
22244   return 0;
22245 }
22246
22247 /* List of API message constructors, CLI names map to api_xxx */
22248 #define foreach_vpe_api_msg                                             \
22249 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22250 _(sw_interface_dump,"")                                                 \
22251 _(sw_interface_set_flags,                                               \
22252   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22253 _(sw_interface_add_del_address,                                         \
22254   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22255 _(sw_interface_set_rx_mode,                                             \
22256   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22257 _(sw_interface_set_rx_placement,                                        \
22258   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22259 _(sw_interface_rx_placement_dump,                                       \
22260   "[<intfc> | sw_if_index <id>]")                                         \
22261 _(sw_interface_set_table,                                               \
22262   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22263 _(sw_interface_set_mpls_enable,                                         \
22264   "<intfc> | sw_if_index [disable | dis]")                              \
22265 _(sw_interface_set_vpath,                                               \
22266   "<intfc> | sw_if_index <id> enable | disable")                        \
22267 _(sw_interface_set_vxlan_bypass,                                        \
22268   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22269 _(sw_interface_set_geneve_bypass,                                       \
22270   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22271 _(sw_interface_set_l2_xconnect,                                         \
22272   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22273   "enable | disable")                                                   \
22274 _(sw_interface_set_l2_bridge,                                           \
22275   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22276   "[shg <split-horizon-group>] [bvi]\n"                                 \
22277   "enable | disable")                                                   \
22278 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22279 _(bridge_domain_add_del,                                                \
22280   "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") \
22281 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22282 _(l2fib_add_del,                                                        \
22283   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22284 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22285 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22286 _(l2_flags,                                                             \
22287   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22288 _(bridge_flags,                                                         \
22289   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22290 _(tap_create_v2,                                                        \
22291   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22292 _(tap_delete_v2,                                                        \
22293   "<vpp-if-name> | sw_if_index <id>")                                   \
22294 _(sw_interface_tap_v2_dump, "")                                         \
22295 _(virtio_pci_create,                                                    \
22296   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22297 _(virtio_pci_delete,                                                    \
22298   "<vpp-if-name> | sw_if_index <id>")                                   \
22299 _(sw_interface_virtio_pci_dump, "")                                     \
22300 _(bond_create,                                                          \
22301   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22302   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22303   "[id <if-id>]")                                                       \
22304 _(bond_delete,                                                          \
22305   "<vpp-if-name> | sw_if_index <id>")                                   \
22306 _(bond_enslave,                                                         \
22307   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22308 _(bond_detach_slave,                                                    \
22309   "sw_if_index <n>")                                                    \
22310 _(sw_interface_bond_dump, "")                                           \
22311 _(sw_interface_slave_dump,                                              \
22312   "<vpp-if-name> | sw_if_index <id>")                                   \
22313 _(ip_table_add_del,                                                     \
22314   "table <n> [ipv6] [add | del]\n")                                     \
22315 _(ip_add_del_route,                                                     \
22316   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22317   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22318   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22319   "[multipath] [count <n>] [del]")                                      \
22320 _(ip_mroute_add_del,                                                    \
22321   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22322   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22323 _(mpls_table_add_del,                                                   \
22324   "table <n> [add | del]\n")                                            \
22325 _(mpls_route_add_del,                                                   \
22326   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22327   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22328   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22329   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22330   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22331   "[count <n>] [del]")                                                  \
22332 _(mpls_ip_bind_unbind,                                                  \
22333   "<label> <addr/len>")                                                 \
22334 _(mpls_tunnel_add_del,                                                  \
22335   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22336   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22337   "[l2-only]  [out-label <n>]")                                         \
22338 _(sr_mpls_policy_add,                                                   \
22339   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22340 _(sr_mpls_policy_del,                                                   \
22341   "bsid <id>")                                                          \
22342 _(bier_table_add_del,                                                   \
22343   "<label> <sub-domain> <set> <bsl> [del]")                             \
22344 _(bier_route_add_del,                                                   \
22345   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22346   "[<intfc> | sw_if_index <id>]"                                        \
22347   "[weight <n>] [del] [multipath]")                                     \
22348 _(proxy_arp_add_del,                                                    \
22349   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22350 _(proxy_arp_intfc_enable_disable,                                       \
22351   "<intfc> | sw_if_index <id> enable | disable")                        \
22352 _(sw_interface_set_unnumbered,                                          \
22353   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22354 _(ip_neighbor_add_del,                                                  \
22355   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22356   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22357 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22358 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22359   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22360   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22361   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22362 _(reset_fib, "vrf <n> [ipv6]")                                          \
22363 _(dhcp_proxy_config,                                                    \
22364   "svr <v46-address> src <v46-address>\n"                               \
22365    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22366 _(dhcp_proxy_set_vss,                                                   \
22367   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22368 _(dhcp_proxy_dump, "ip6")                                               \
22369 _(dhcp_client_config,                                                   \
22370   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22371 _(set_ip_flow_hash,                                                     \
22372   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22373 _(sw_interface_ip6_enable_disable,                                      \
22374   "<intfc> | sw_if_index <id> enable | disable")                        \
22375 _(ip6nd_proxy_add_del,                                                  \
22376   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22377 _(ip6nd_proxy_dump, "")                                                 \
22378 _(sw_interface_ip6nd_ra_prefix,                                         \
22379   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22380   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22381   "[nolink] [isno]")                                                    \
22382 _(sw_interface_ip6nd_ra_config,                                         \
22383   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22384   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22385   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22386 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22387 _(l2_patch_add_del,                                                     \
22388   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22389   "enable | disable")                                                   \
22390 _(sr_localsid_add_del,                                                  \
22391   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22392   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22393 _(classify_add_del_table,                                               \
22394   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22395   " [del] [del-chain] mask <mask-value>\n"                              \
22396   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22397   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22398 _(classify_add_del_session,                                             \
22399   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22400   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22401   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22402   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22403 _(classify_set_interface_ip_table,                                      \
22404   "<intfc> | sw_if_index <nn> table <nn>")                              \
22405 _(classify_set_interface_l2_tables,                                     \
22406   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22407   "  [other-table <nn>]")                                               \
22408 _(get_node_index, "node <node-name")                                    \
22409 _(add_node_next, "node <node-name> next <next-node-name>")              \
22410 _(l2tpv3_create_tunnel,                                                 \
22411   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22412   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22413   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22414 _(l2tpv3_set_tunnel_cookies,                                            \
22415   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22416   "[new_remote_cookie <nn>]\n")                                         \
22417 _(l2tpv3_interface_enable_disable,                                      \
22418   "<intfc> | sw_if_index <nn> enable | disable")                        \
22419 _(l2tpv3_set_lookup_key,                                                \
22420   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22421 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22422 _(vxlan_offload_rx,                                                     \
22423   "hw { <interface name> | hw_if_index <nn>} "                          \
22424   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22425 _(vxlan_add_del_tunnel,                                                 \
22426   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22427   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22428   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22429 _(geneve_add_del_tunnel,                                                \
22430   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22431   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22432   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22433 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22434 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22435 _(gre_tunnel_add_del,                                                   \
22436   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22437   "[teb | erspan <session-id>] [del]")                                  \
22438 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22439 _(l2_fib_clear_table, "")                                               \
22440 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22441 _(l2_interface_vlan_tag_rewrite,                                        \
22442   "<intfc> | sw_if_index <nn> \n"                                       \
22443   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22444   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22445 _(create_vhost_user_if,                                                 \
22446         "socket <filename> [server] [renumber <dev_instance>] "         \
22447         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22448         "[mac <mac_address>]")                                          \
22449 _(modify_vhost_user_if,                                                 \
22450         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22451         "[server] [renumber <dev_instance>]")                           \
22452 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22453 _(sw_interface_vhost_user_dump, "")                                     \
22454 _(show_version, "")                                                     \
22455 _(show_threads, "")                                                     \
22456 _(vxlan_gpe_add_del_tunnel,                                             \
22457   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22458   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22459   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22460   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22461 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22462 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22463 _(interface_name_renumber,                                              \
22464   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22465 _(input_acl_set_interface,                                              \
22466   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22467   "  [l2-table <nn>] [del]")                                            \
22468 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22469 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22470   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22471 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22472 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22473 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22474 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22475 _(ip_dump, "ipv4 | ipv6")                                               \
22476 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22477 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22478   "  spid_id <n> ")                                                     \
22479 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22480   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22481   "  integ_alg <alg> integ_key <hex>")                                  \
22482 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22483   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22484   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22485   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22486 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22487 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22488   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22489   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22490   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22491   "  [instance <n>]")     \
22492 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22493 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22494   "  <alg> <hex>\n")                                                    \
22495 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22496 _(delete_loopback,"sw_if_index <nn>")                                   \
22497 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22498 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22499 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22500 _(want_interface_events,  "enable|disable")                             \
22501 _(get_first_msg_id, "client <name>")                                    \
22502 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22503 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22504   "fib-id <nn> [ip4][ip6][default]")                                    \
22505 _(get_node_graph, " ")                                                  \
22506 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22507 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22508 _(ioam_disable, "")                                                     \
22509 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22510                             " sw_if_index <sw_if_index> p <priority> "  \
22511                             "w <weight>] [del]")                        \
22512 _(one_add_del_locator, "locator-set <locator_name> "                    \
22513                         "iface <intf> | sw_if_index <sw_if_index> "     \
22514                         "p <priority> w <weight> [del]")                \
22515 _(one_add_del_local_eid,"vni <vni> eid "                                \
22516                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22517                          "locator-set <locator_name> [del]"             \
22518                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22519 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22520 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22521 _(one_enable_disable, "enable|disable")                                 \
22522 _(one_map_register_enable_disable, "enable|disable")                    \
22523 _(one_map_register_fallback_threshold, "<value>")                       \
22524 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22525 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22526                                "[seid <seid>] "                         \
22527                                "rloc <locator> p <prio> "               \
22528                                "w <weight> [rloc <loc> ... ] "          \
22529                                "action <action> [del-all]")             \
22530 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22531                           "<local-eid>")                                \
22532 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22533 _(one_use_petr, "ip-address> | disable")                                \
22534 _(one_map_request_mode, "src-dst|dst-only")                             \
22535 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22536 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22537 _(one_locator_set_dump, "[local | remote]")                             \
22538 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22539 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22540                        "[local] | [remote]")                            \
22541 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22542 _(one_ndp_bd_get, "")                                                   \
22543 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22544 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22545 _(one_l2_arp_bd_get, "")                                                \
22546 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22547 _(one_stats_enable_disable, "enable|disable")                           \
22548 _(show_one_stats_enable_disable, "")                                    \
22549 _(one_eid_table_vni_dump, "")                                           \
22550 _(one_eid_table_map_dump, "l2|l3")                                      \
22551 _(one_map_resolver_dump, "")                                            \
22552 _(one_map_server_dump, "")                                              \
22553 _(one_adjacencies_get, "vni <vni>")                                     \
22554 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22555 _(show_one_rloc_probe_state, "")                                        \
22556 _(show_one_map_register_state, "")                                      \
22557 _(show_one_status, "")                                                  \
22558 _(one_stats_dump, "")                                                   \
22559 _(one_stats_flush, "")                                                  \
22560 _(one_get_map_request_itr_rlocs, "")                                    \
22561 _(one_map_register_set_ttl, "<ttl>")                                    \
22562 _(one_set_transport_protocol, "udp|api")                                \
22563 _(one_get_transport_protocol, "")                                       \
22564 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22565 _(one_show_xtr_mode, "")                                                \
22566 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22567 _(one_show_pitr_mode, "")                                               \
22568 _(one_enable_disable_petr_mode, "enable|disable")                       \
22569 _(one_show_petr_mode, "")                                               \
22570 _(show_one_nsh_mapping, "")                                             \
22571 _(show_one_pitr, "")                                                    \
22572 _(show_one_use_petr, "")                                                \
22573 _(show_one_map_request_mode, "")                                        \
22574 _(show_one_map_register_ttl, "")                                        \
22575 _(show_one_map_register_fallback_threshold, "")                         \
22576 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22577                             " sw_if_index <sw_if_index> p <priority> "  \
22578                             "w <weight>] [del]")                        \
22579 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22580                         "iface <intf> | sw_if_index <sw_if_index> "     \
22581                         "p <priority> w <weight> [del]")                \
22582 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22583                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22584                          "locator-set <locator_name> [del]"             \
22585                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22586 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22587 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22588 _(lisp_enable_disable, "enable|disable")                                \
22589 _(lisp_map_register_enable_disable, "enable|disable")                   \
22590 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22591 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22592                                "[seid <seid>] "                         \
22593                                "rloc <locator> p <prio> "               \
22594                                "w <weight> [rloc <loc> ... ] "          \
22595                                "action <action> [del-all]")             \
22596 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22597                           "<local-eid>")                                \
22598 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22599 _(lisp_use_petr, "<ip-address> | disable")                              \
22600 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22601 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22602 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22603 _(lisp_locator_set_dump, "[local | remote]")                            \
22604 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22605 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22606                        "[local] | [remote]")                            \
22607 _(lisp_eid_table_vni_dump, "")                                          \
22608 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22609 _(lisp_map_resolver_dump, "")                                           \
22610 _(lisp_map_server_dump, "")                                             \
22611 _(lisp_adjacencies_get, "vni <vni>")                                    \
22612 _(gpe_fwd_entry_vnis_get, "")                                           \
22613 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22614 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22615                                 "[table <table-id>]")                   \
22616 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22617 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22618 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22619 _(gpe_get_encap_mode, "")                                               \
22620 _(lisp_gpe_add_del_iface, "up|down")                                    \
22621 _(lisp_gpe_enable_disable, "enable|disable")                            \
22622 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22623   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22624 _(show_lisp_rloc_probe_state, "")                                       \
22625 _(show_lisp_map_register_state, "")                                     \
22626 _(show_lisp_status, "")                                                 \
22627 _(lisp_get_map_request_itr_rlocs, "")                                   \
22628 _(show_lisp_pitr, "")                                                   \
22629 _(show_lisp_use_petr, "")                                               \
22630 _(show_lisp_map_request_mode, "")                                       \
22631 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22632 _(af_packet_delete, "name <host interface name>")                       \
22633 _(af_packet_dump, "")                                                   \
22634 _(policer_add_del, "name <policer name> <params> [del]")                \
22635 _(policer_dump, "[name <policer name>]")                                \
22636 _(policer_classify_set_interface,                                       \
22637   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22638   "  [l2-table <nn>] [del]")                                            \
22639 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22640 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22641     "[master|slave]")                                                   \
22642 _(netmap_delete, "name <interface name>")                               \
22643 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22644 _(mpls_fib_dump, "")                                                    \
22645 _(classify_table_ids, "")                                               \
22646 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22647 _(classify_table_info, "table_id <nn>")                                 \
22648 _(classify_session_dump, "table_id <nn>")                               \
22649 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22650     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22651     "[template_interval <nn>] [udp_checksum]")                          \
22652 _(ipfix_exporter_dump, "")                                              \
22653 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22654 _(ipfix_classify_stream_dump, "")                                       \
22655 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22656 _(ipfix_classify_table_dump, "")                                        \
22657 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22658 _(sw_interface_span_dump, "[l2]")                                           \
22659 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22660 _(pg_create_interface, "if_id <nn>")                                    \
22661 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22662 _(pg_enable_disable, "[stream <id>] disable")                           \
22663 _(ip_source_and_port_range_check_add_del,                               \
22664   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22665 _(ip_source_and_port_range_check_interface_add_del,                     \
22666   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22667   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22668 _(ipsec_gre_tunnel_add_del,                                             \
22669   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22670 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22671 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22672 _(l2_interface_pbb_tag_rewrite,                                         \
22673   "<intfc> | sw_if_index <nn> \n"                                       \
22674   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22675   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22676 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22677 _(flow_classify_set_interface,                                          \
22678   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22679 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22680 _(ip_fib_dump, "")                                                      \
22681 _(ip_mfib_dump, "")                                                     \
22682 _(ip6_fib_dump, "")                                                     \
22683 _(ip6_mfib_dump, "")                                                    \
22684 _(feature_enable_disable, "arc_name <arc_name> "                        \
22685   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22686 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22687 "[disable]")                                                            \
22688 _(l2_xconnect_dump, "")                                                 \
22689 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22690 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22691 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22692 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22693 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22694 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22695 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22696   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22697 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22698 _(sock_init_shm, "size <nnn>")                                          \
22699 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22700 _(dns_enable_disable, "[enable][disable]")                              \
22701 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22702 _(dns_resolve_name, "<hostname>")                                       \
22703 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22704 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22705 _(dns_resolve_name, "<hostname>")                                       \
22706 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22707   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22708 _(session_rules_dump, "")                                               \
22709 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22710 _(output_acl_set_interface,                                             \
22711   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22712   "  [l2-table <nn>] [del]")                                            \
22713 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22714
22715 /* List of command functions, CLI names map directly to functions */
22716 #define foreach_cli_function                                    \
22717 _(comment, "usage: comment <ignore-rest-of-line>")              \
22718 _(dump_interface_table, "usage: dump_interface_table")          \
22719 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22720 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22721 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22722 _(dump_macro_table, "usage: dump_macro_table ")                 \
22723 _(dump_node_table, "usage: dump_node_table")                    \
22724 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22725 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22726 _(echo, "usage: echo <message>")                                \
22727 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22728 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22729 _(help, "usage: help")                                          \
22730 _(q, "usage: quit")                                             \
22731 _(quit, "usage: quit")                                          \
22732 _(search_node_table, "usage: search_node_table <name>...")      \
22733 _(set, "usage: set <variable-name> <value>")                    \
22734 _(script, "usage: script <file-name>")                          \
22735 _(statseg, "usage: statseg");                                   \
22736 _(unset, "usage: unset <variable-name>")
22737
22738 #define _(N,n)                                  \
22739     static void vl_api_##n##_t_handler_uni      \
22740     (vl_api_##n##_t * mp)                       \
22741     {                                           \
22742         vat_main_t * vam = &vat_main;           \
22743         if (vam->json_output) {                 \
22744             vl_api_##n##_t_handler_json(mp);    \
22745         } else {                                \
22746             vl_api_##n##_t_handler(mp);         \
22747         }                                       \
22748     }
22749 foreach_vpe_api_reply_msg;
22750 #if VPP_API_TEST_BUILTIN == 0
22751 foreach_standalone_reply_msg;
22752 #endif
22753 #undef _
22754
22755 void
22756 vat_api_hookup (vat_main_t * vam)
22757 {
22758 #define _(N,n)                                                  \
22759     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22760                            vl_api_##n##_t_handler_uni,          \
22761                            vl_noop_handler,                     \
22762                            vl_api_##n##_t_endian,               \
22763                            vl_api_##n##_t_print,                \
22764                            sizeof(vl_api_##n##_t), 1);
22765   foreach_vpe_api_reply_msg;
22766 #if VPP_API_TEST_BUILTIN == 0
22767   foreach_standalone_reply_msg;
22768 #endif
22769 #undef _
22770
22771 #if (VPP_API_TEST_BUILTIN==0)
22772   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22773
22774   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22775
22776   vam->function_by_name = hash_create_string (0, sizeof (uword));
22777
22778   vam->help_by_name = hash_create_string (0, sizeof (uword));
22779 #endif
22780
22781   /* API messages we can send */
22782 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22783   foreach_vpe_api_msg;
22784 #undef _
22785
22786   /* Help strings */
22787 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22788   foreach_vpe_api_msg;
22789 #undef _
22790
22791   /* CLI functions */
22792 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22793   foreach_cli_function;
22794 #undef _
22795
22796   /* Help strings */
22797 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22798   foreach_cli_function;
22799 #undef _
22800 }
22801
22802 #if VPP_API_TEST_BUILTIN
22803 static clib_error_t *
22804 vat_api_hookup_shim (vlib_main_t * vm)
22805 {
22806   vat_api_hookup (&vat_main);
22807   return 0;
22808 }
22809
22810 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22811 #endif
22812
22813 /*
22814  * fd.io coding-style-patch-verification: ON
22815  *
22816  * Local Variables:
22817  * eval: (c-set-style "gnu")
22818  * End:
22819  */