Fix VPP-1487 DHCP client does not support option 6-domain server
[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 (s, "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 }
2717
2718 static void vl_api_dhcp_compl_event_t_handler_json
2719   (vl_api_dhcp_compl_event_t * mp)
2720 {
2721   /* JSON output not supported */
2722 }
2723
2724 static void vl_api_get_first_msg_id_reply_t_handler
2725   (vl_api_get_first_msg_id_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   i32 retval = ntohl (mp->retval);
2729
2730   if (vam->async_mode)
2731     {
2732       vam->async_errors += (retval < 0);
2733     }
2734   else
2735     {
2736       vam->retval = retval;
2737       vam->result_ready = 1;
2738     }
2739   if (retval >= 0)
2740     {
2741       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2742     }
2743 }
2744
2745 static void vl_api_get_first_msg_id_reply_t_handler_json
2746   (vl_api_get_first_msg_id_reply_t * mp)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   vat_json_node_t node;
2750
2751   vat_json_init_object (&node);
2752   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2753   vat_json_object_add_uint (&node, "first_msg_id",
2754                             (uint) ntohs (mp->first_msg_id));
2755
2756   vat_json_print (vam->ofp, &node);
2757   vat_json_free (&node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static void vl_api_get_node_graph_reply_t_handler
2764   (vl_api_get_node_graph_reply_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   api_main_t *am = &api_main;
2768   i32 retval = ntohl (mp->retval);
2769   u8 *pvt_copy, *reply;
2770   void *oldheap;
2771   vlib_node_t *node;
2772   int i;
2773
2774   if (vam->async_mode)
2775     {
2776       vam->async_errors += (retval < 0);
2777     }
2778   else
2779     {
2780       vam->retval = retval;
2781       vam->result_ready = 1;
2782     }
2783
2784   /* "Should never happen..." */
2785   if (retval != 0)
2786     return;
2787
2788   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2789   pvt_copy = vec_dup (reply);
2790
2791   /* Toss the shared-memory original... */
2792   pthread_mutex_lock (&am->vlib_rp->mutex);
2793   oldheap = svm_push_data_heap (am->vlib_rp);
2794
2795   vec_free (reply);
2796
2797   svm_pop_heap (oldheap);
2798   pthread_mutex_unlock (&am->vlib_rp->mutex);
2799
2800   if (vam->graph_nodes)
2801     {
2802       hash_free (vam->graph_node_index_by_name);
2803
2804       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2805         {
2806           node = vam->graph_nodes[0][i];
2807           vec_free (node->name);
2808           vec_free (node->next_nodes);
2809           vec_free (node);
2810         }
2811       vec_free (vam->graph_nodes[0]);
2812       vec_free (vam->graph_nodes);
2813     }
2814
2815   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2816   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2817   vec_free (pvt_copy);
2818
2819   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2820     {
2821       node = vam->graph_nodes[0][i];
2822       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2823     }
2824 }
2825
2826 static void vl_api_get_node_graph_reply_t_handler_json
2827   (vl_api_get_node_graph_reply_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   api_main_t *am = &api_main;
2831   void *oldheap;
2832   vat_json_node_t node;
2833   u8 *reply;
2834
2835   /* $$$$ make this real? */
2836   vat_json_init_object (&node);
2837   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2838   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2839
2840   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2841
2842   /* Toss the shared-memory original... */
2843   pthread_mutex_lock (&am->vlib_rp->mutex);
2844   oldheap = svm_push_data_heap (am->vlib_rp);
2845
2846   vec_free (reply);
2847
2848   svm_pop_heap (oldheap);
2849   pthread_mutex_unlock (&am->vlib_rp->mutex);
2850
2851   vat_json_print (vam->ofp, &node);
2852   vat_json_free (&node);
2853
2854   vam->retval = ntohl (mp->retval);
2855   vam->result_ready = 1;
2856 }
2857
2858 static void
2859 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2860 {
2861   vat_main_t *vam = &vat_main;
2862   u8 *s = 0;
2863
2864   if (mp->local)
2865     {
2866       s = format (s, "%=16d%=16d%=16d",
2867                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2868     }
2869   else
2870     {
2871       s = format (s, "%=16U%=16d%=16d",
2872                   mp->is_ipv6 ? format_ip6_address :
2873                   format_ip4_address,
2874                   mp->ip_address, mp->priority, mp->weight);
2875     }
2876
2877   print (vam->ofp, "%v", s);
2878   vec_free (s);
2879 }
2880
2881 static void
2882 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2883 {
2884   vat_main_t *vam = &vat_main;
2885   vat_json_node_t *node = NULL;
2886   struct in6_addr ip6;
2887   struct in_addr ip4;
2888
2889   if (VAT_JSON_ARRAY != vam->json_tree.type)
2890     {
2891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2892       vat_json_init_array (&vam->json_tree);
2893     }
2894   node = vat_json_array_add (&vam->json_tree);
2895   vat_json_init_object (node);
2896
2897   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2898   vat_json_object_add_uint (node, "priority", mp->priority);
2899   vat_json_object_add_uint (node, "weight", mp->weight);
2900
2901   if (mp->local)
2902     vat_json_object_add_uint (node, "sw_if_index",
2903                               clib_net_to_host_u32 (mp->sw_if_index));
2904   else
2905     {
2906       if (mp->is_ipv6)
2907         {
2908           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2909           vat_json_object_add_ip6 (node, "address", ip6);
2910         }
2911       else
2912         {
2913           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2914           vat_json_object_add_ip4 (node, "address", ip4);
2915         }
2916     }
2917 }
2918
2919 static void
2920 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2921                                           mp)
2922 {
2923   vat_main_t *vam = &vat_main;
2924   u8 *ls_name = 0;
2925
2926   ls_name = format (0, "%s", mp->ls_name);
2927
2928   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2929          ls_name);
2930   vec_free (ls_name);
2931 }
2932
2933 static void
2934   vl_api_one_locator_set_details_t_handler_json
2935   (vl_api_one_locator_set_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t *node = 0;
2939   u8 *ls_name = 0;
2940
2941   ls_name = format (0, "%s", mp->ls_name);
2942   vec_add1 (ls_name, 0);
2943
2944   if (VAT_JSON_ARRAY != vam->json_tree.type)
2945     {
2946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2947       vat_json_init_array (&vam->json_tree);
2948     }
2949   node = vat_json_array_add (&vam->json_tree);
2950
2951   vat_json_init_object (node);
2952   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2953   vat_json_object_add_uint (node, "ls_index",
2954                             clib_net_to_host_u32 (mp->ls_index));
2955   vec_free (ls_name);
2956 }
2957
2958 typedef struct
2959 {
2960   u32 spi;
2961   u8 si;
2962 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2963
2964 uword
2965 unformat_nsh_address (unformat_input_t * input, va_list * args)
2966 {
2967   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2968   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2969 }
2970
2971 u8 *
2972 format_nsh_address_vat (u8 * s, va_list * args)
2973 {
2974   nsh_t *a = va_arg (*args, nsh_t *);
2975   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2976 }
2977
2978 static u8 *
2979 format_lisp_flat_eid (u8 * s, va_list * args)
2980 {
2981   u32 type = va_arg (*args, u32);
2982   u8 *eid = va_arg (*args, u8 *);
2983   u32 eid_len = va_arg (*args, u32);
2984
2985   switch (type)
2986     {
2987     case 0:
2988       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2989     case 1:
2990       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2991     case 2:
2992       return format (s, "%U", format_ethernet_address, eid);
2993     case 3:
2994       return format (s, "%U", format_nsh_address_vat, eid);
2995     }
2996   return 0;
2997 }
2998
2999 static u8 *
3000 format_lisp_eid_vat (u8 * s, va_list * args)
3001 {
3002   u32 type = va_arg (*args, u32);
3003   u8 *eid = va_arg (*args, u8 *);
3004   u32 eid_len = va_arg (*args, u32);
3005   u8 *seid = va_arg (*args, u8 *);
3006   u32 seid_len = va_arg (*args, u32);
3007   u32 is_src_dst = va_arg (*args, u32);
3008
3009   if (is_src_dst)
3010     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3011
3012   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3013
3014   return s;
3015 }
3016
3017 static void
3018 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   u8 *s = 0, *eid = 0;
3022
3023   if (~0 == mp->locator_set_index)
3024     s = format (0, "action: %d", mp->action);
3025   else
3026     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3027
3028   eid = format (0, "%U", format_lisp_eid_vat,
3029                 mp->eid_type,
3030                 mp->eid,
3031                 mp->eid_prefix_len,
3032                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3033   vec_add1 (eid, 0);
3034
3035   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3036          clib_net_to_host_u32 (mp->vni),
3037          eid,
3038          mp->is_local ? "local" : "remote",
3039          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3040          clib_net_to_host_u16 (mp->key_id), mp->key);
3041
3042   vec_free (s);
3043   vec_free (eid);
3044 }
3045
3046 static void
3047 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3048                                              * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   vat_json_node_t *node = 0;
3052   u8 *eid = 0;
3053
3054   if (VAT_JSON_ARRAY != vam->json_tree.type)
3055     {
3056       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3057       vat_json_init_array (&vam->json_tree);
3058     }
3059   node = vat_json_array_add (&vam->json_tree);
3060
3061   vat_json_init_object (node);
3062   if (~0 == mp->locator_set_index)
3063     vat_json_object_add_uint (node, "action", mp->action);
3064   else
3065     vat_json_object_add_uint (node, "locator_set_index",
3066                               clib_net_to_host_u32 (mp->locator_set_index));
3067
3068   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3069   if (mp->eid_type == 3)
3070     {
3071       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3072       vat_json_init_object (nsh_json);
3073       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3074       vat_json_object_add_uint (nsh_json, "spi",
3075                                 clib_net_to_host_u32 (nsh->spi));
3076       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3077     }
3078   else
3079     {
3080       eid = format (0, "%U", format_lisp_eid_vat,
3081                     mp->eid_type,
3082                     mp->eid,
3083                     mp->eid_prefix_len,
3084                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3085       vec_add1 (eid, 0);
3086       vat_json_object_add_string_copy (node, "eid", eid);
3087       vec_free (eid);
3088     }
3089   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3090   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3091   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3092
3093   if (mp->key_id)
3094     {
3095       vat_json_object_add_uint (node, "key_id",
3096                                 clib_net_to_host_u16 (mp->key_id));
3097       vat_json_object_add_string_copy (node, "key", mp->key);
3098     }
3099 }
3100
3101 static void
3102 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   u8 *seid = 0, *deid = 0;
3106   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3107
3108   deid = format (0, "%U", format_lisp_eid_vat,
3109                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3110
3111   seid = format (0, "%U", format_lisp_eid_vat,
3112                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3113
3114   vec_add1 (deid, 0);
3115   vec_add1 (seid, 0);
3116
3117   if (mp->is_ip4)
3118     format_ip_address_fcn = format_ip4_address;
3119   else
3120     format_ip_address_fcn = format_ip6_address;
3121
3122
3123   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3124          clib_net_to_host_u32 (mp->vni),
3125          seid, deid,
3126          format_ip_address_fcn, mp->lloc,
3127          format_ip_address_fcn, mp->rloc,
3128          clib_net_to_host_u32 (mp->pkt_count),
3129          clib_net_to_host_u32 (mp->bytes));
3130
3131   vec_free (deid);
3132   vec_free (seid);
3133 }
3134
3135 static void
3136 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3137 {
3138   struct in6_addr ip6;
3139   struct in_addr ip4;
3140   vat_main_t *vam = &vat_main;
3141   vat_json_node_t *node = 0;
3142   u8 *deid = 0, *seid = 0;
3143
3144   if (VAT_JSON_ARRAY != vam->json_tree.type)
3145     {
3146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3147       vat_json_init_array (&vam->json_tree);
3148     }
3149   node = vat_json_array_add (&vam->json_tree);
3150
3151   vat_json_init_object (node);
3152   deid = format (0, "%U", format_lisp_eid_vat,
3153                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3154
3155   seid = format (0, "%U", format_lisp_eid_vat,
3156                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3157
3158   vec_add1 (deid, 0);
3159   vec_add1 (seid, 0);
3160
3161   vat_json_object_add_string_copy (node, "seid", seid);
3162   vat_json_object_add_string_copy (node, "deid", deid);
3163   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3164
3165   if (mp->is_ip4)
3166     {
3167       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3168       vat_json_object_add_ip4 (node, "lloc", ip4);
3169       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3170       vat_json_object_add_ip4 (node, "rloc", ip4);
3171     }
3172   else
3173     {
3174       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3175       vat_json_object_add_ip6 (node, "lloc", ip6);
3176       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3177       vat_json_object_add_ip6 (node, "rloc", ip6);
3178     }
3179   vat_json_object_add_uint (node, "pkt_count",
3180                             clib_net_to_host_u32 (mp->pkt_count));
3181   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3182
3183   vec_free (deid);
3184   vec_free (seid);
3185 }
3186
3187 static void
3188   vl_api_one_eid_table_map_details_t_handler
3189   (vl_api_one_eid_table_map_details_t * mp)
3190 {
3191   vat_main_t *vam = &vat_main;
3192
3193   u8 *line = format (0, "%=10d%=10d",
3194                      clib_net_to_host_u32 (mp->vni),
3195                      clib_net_to_host_u32 (mp->dp_table));
3196   print (vam->ofp, "%v", line);
3197   vec_free (line);
3198 }
3199
3200 static void
3201   vl_api_one_eid_table_map_details_t_handler_json
3202   (vl_api_one_eid_table_map_details_t * mp)
3203 {
3204   vat_main_t *vam = &vat_main;
3205   vat_json_node_t *node = NULL;
3206
3207   if (VAT_JSON_ARRAY != vam->json_tree.type)
3208     {
3209       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3210       vat_json_init_array (&vam->json_tree);
3211     }
3212   node = vat_json_array_add (&vam->json_tree);
3213   vat_json_init_object (node);
3214   vat_json_object_add_uint (node, "dp_table",
3215                             clib_net_to_host_u32 (mp->dp_table));
3216   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3217 }
3218
3219 static void
3220   vl_api_one_eid_table_vni_details_t_handler
3221   (vl_api_one_eid_table_vni_details_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224
3225   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3226   print (vam->ofp, "%v", line);
3227   vec_free (line);
3228 }
3229
3230 static void
3231   vl_api_one_eid_table_vni_details_t_handler_json
3232   (vl_api_one_eid_table_vni_details_t * mp)
3233 {
3234   vat_main_t *vam = &vat_main;
3235   vat_json_node_t *node = NULL;
3236
3237   if (VAT_JSON_ARRAY != vam->json_tree.type)
3238     {
3239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3240       vat_json_init_array (&vam->json_tree);
3241     }
3242   node = vat_json_array_add (&vam->json_tree);
3243   vat_json_init_object (node);
3244   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3245 }
3246
3247 static void
3248   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3249   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   int retval = clib_net_to_host_u32 (mp->retval);
3253
3254   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3255   print (vam->ofp, "fallback threshold value: %d", mp->value);
3256
3257   vam->retval = retval;
3258   vam->result_ready = 1;
3259 }
3260
3261 static void
3262   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3263   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3264 {
3265   vat_main_t *vam = &vat_main;
3266   vat_json_node_t _node, *node = &_node;
3267   int retval = clib_net_to_host_u32 (mp->retval);
3268
3269   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3270   vat_json_init_object (node);
3271   vat_json_object_add_uint (node, "value", mp->value);
3272
3273   vat_json_print (vam->ofp, node);
3274   vat_json_free (node);
3275
3276   vam->retval = retval;
3277   vam->result_ready = 1;
3278 }
3279
3280 static void
3281   vl_api_show_one_map_register_state_reply_t_handler
3282   (vl_api_show_one_map_register_state_reply_t * mp)
3283 {
3284   vat_main_t *vam = &vat_main;
3285   int retval = clib_net_to_host_u32 (mp->retval);
3286
3287   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3288
3289   vam->retval = retval;
3290   vam->result_ready = 1;
3291 }
3292
3293 static void
3294   vl_api_show_one_map_register_state_reply_t_handler_json
3295   (vl_api_show_one_map_register_state_reply_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   vat_json_node_t _node, *node = &_node;
3299   int retval = clib_net_to_host_u32 (mp->retval);
3300
3301   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3302
3303   vat_json_init_object (node);
3304   vat_json_object_add_string_copy (node, "state", s);
3305
3306   vat_json_print (vam->ofp, node);
3307   vat_json_free (node);
3308
3309   vam->retval = retval;
3310   vam->result_ready = 1;
3311   vec_free (s);
3312 }
3313
3314 static void
3315   vl_api_show_one_rloc_probe_state_reply_t_handler
3316   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3317 {
3318   vat_main_t *vam = &vat_main;
3319   int retval = clib_net_to_host_u32 (mp->retval);
3320
3321   if (retval)
3322     goto end;
3323
3324   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3325 end:
3326   vam->retval = retval;
3327   vam->result_ready = 1;
3328 }
3329
3330 static void
3331   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3332   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3333 {
3334   vat_main_t *vam = &vat_main;
3335   vat_json_node_t _node, *node = &_node;
3336   int retval = clib_net_to_host_u32 (mp->retval);
3337
3338   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3339   vat_json_init_object (node);
3340   vat_json_object_add_string_copy (node, "state", s);
3341
3342   vat_json_print (vam->ofp, node);
3343   vat_json_free (node);
3344
3345   vam->retval = retval;
3346   vam->result_ready = 1;
3347   vec_free (s);
3348 }
3349
3350 static void
3351   vl_api_show_one_stats_enable_disable_reply_t_handler
3352   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3353 {
3354   vat_main_t *vam = &vat_main;
3355   int retval = clib_net_to_host_u32 (mp->retval);
3356
3357   if (retval)
3358     goto end;
3359
3360   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3361 end:
3362   vam->retval = retval;
3363   vam->result_ready = 1;
3364 }
3365
3366 static void
3367   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3368   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3369 {
3370   vat_main_t *vam = &vat_main;
3371   vat_json_node_t _node, *node = &_node;
3372   int retval = clib_net_to_host_u32 (mp->retval);
3373
3374   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3375   vat_json_init_object (node);
3376   vat_json_object_add_string_copy (node, "state", s);
3377
3378   vat_json_print (vam->ofp, node);
3379   vat_json_free (node);
3380
3381   vam->retval = retval;
3382   vam->result_ready = 1;
3383   vec_free (s);
3384 }
3385
3386 static void
3387 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3388 {
3389   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3390   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3391   e->vni = clib_net_to_host_u32 (e->vni);
3392 }
3393
3394 static void
3395   gpe_fwd_entries_get_reply_t_net_to_host
3396   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3397 {
3398   u32 i;
3399
3400   mp->count = clib_net_to_host_u32 (mp->count);
3401   for (i = 0; i < mp->count; i++)
3402     {
3403       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3404     }
3405 }
3406
3407 static u8 *
3408 format_gpe_encap_mode (u8 * s, va_list * args)
3409 {
3410   u32 mode = va_arg (*args, u32);
3411
3412   switch (mode)
3413     {
3414     case 0:
3415       return format (s, "lisp");
3416     case 1:
3417       return format (s, "vxlan");
3418     }
3419   return 0;
3420 }
3421
3422 static void
3423   vl_api_gpe_get_encap_mode_reply_t_handler
3424   (vl_api_gpe_get_encap_mode_reply_t * mp)
3425 {
3426   vat_main_t *vam = &vat_main;
3427
3428   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3429   vam->retval = ntohl (mp->retval);
3430   vam->result_ready = 1;
3431 }
3432
3433 static void
3434   vl_api_gpe_get_encap_mode_reply_t_handler_json
3435   (vl_api_gpe_get_encap_mode_reply_t * mp)
3436 {
3437   vat_main_t *vam = &vat_main;
3438   vat_json_node_t node;
3439
3440   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3441   vec_add1 (encap_mode, 0);
3442
3443   vat_json_init_object (&node);
3444   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3445
3446   vec_free (encap_mode);
3447   vat_json_print (vam->ofp, &node);
3448   vat_json_free (&node);
3449
3450   vam->retval = ntohl (mp->retval);
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_gpe_fwd_entry_path_details_t_handler
3456   (vl_api_gpe_fwd_entry_path_details_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3460
3461   if (mp->lcl_loc.is_ip4)
3462     format_ip_address_fcn = format_ip4_address;
3463   else
3464     format_ip_address_fcn = format_ip6_address;
3465
3466   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3467          format_ip_address_fcn, &mp->lcl_loc,
3468          format_ip_address_fcn, &mp->rmt_loc);
3469 }
3470
3471 static void
3472 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3473 {
3474   struct in6_addr ip6;
3475   struct in_addr ip4;
3476
3477   if (loc->is_ip4)
3478     {
3479       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3480       vat_json_object_add_ip4 (n, "address", ip4);
3481     }
3482   else
3483     {
3484       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3485       vat_json_object_add_ip6 (n, "address", ip6);
3486     }
3487   vat_json_object_add_uint (n, "weight", loc->weight);
3488 }
3489
3490 static void
3491   vl_api_gpe_fwd_entry_path_details_t_handler_json
3492   (vl_api_gpe_fwd_entry_path_details_t * mp)
3493 {
3494   vat_main_t *vam = &vat_main;
3495   vat_json_node_t *node = NULL;
3496   vat_json_node_t *loc_node;
3497
3498   if (VAT_JSON_ARRAY != vam->json_tree.type)
3499     {
3500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3501       vat_json_init_array (&vam->json_tree);
3502     }
3503   node = vat_json_array_add (&vam->json_tree);
3504   vat_json_init_object (node);
3505
3506   loc_node = vat_json_object_add (node, "local_locator");
3507   vat_json_init_object (loc_node);
3508   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3509
3510   loc_node = vat_json_object_add (node, "remote_locator");
3511   vat_json_init_object (loc_node);
3512   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3513 }
3514
3515 static void
3516   vl_api_gpe_fwd_entries_get_reply_t_handler
3517   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3518 {
3519   vat_main_t *vam = &vat_main;
3520   u32 i;
3521   int retval = clib_net_to_host_u32 (mp->retval);
3522   vl_api_gpe_fwd_entry_t *e;
3523
3524   if (retval)
3525     goto end;
3526
3527   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3528
3529   for (i = 0; i < mp->count; i++)
3530     {
3531       e = &mp->entries[i];
3532       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3533              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3534              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3535     }
3536
3537 end:
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540 }
3541
3542 static void
3543   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3544   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3545 {
3546   u8 *s = 0;
3547   vat_main_t *vam = &vat_main;
3548   vat_json_node_t *e = 0, root;
3549   u32 i;
3550   int retval = clib_net_to_host_u32 (mp->retval);
3551   vl_api_gpe_fwd_entry_t *fwd;
3552
3553   if (retval)
3554     goto end;
3555
3556   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3557   vat_json_init_array (&root);
3558
3559   for (i = 0; i < mp->count; i++)
3560     {
3561       e = vat_json_array_add (&root);
3562       fwd = &mp->entries[i];
3563
3564       vat_json_init_object (e);
3565       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3566       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3567       vat_json_object_add_int (e, "vni", fwd->vni);
3568       vat_json_object_add_int (e, "action", fwd->action);
3569
3570       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3571                   fwd->leid_prefix_len);
3572       vec_add1 (s, 0);
3573       vat_json_object_add_string_copy (e, "leid", s);
3574       vec_free (s);
3575
3576       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3577                   fwd->reid_prefix_len);
3578       vec_add1 (s, 0);
3579       vat_json_object_add_string_copy (e, "reid", s);
3580       vec_free (s);
3581     }
3582
3583   vat_json_print (vam->ofp, &root);
3584   vat_json_free (&root);
3585
3586 end:
3587   vam->retval = retval;
3588   vam->result_ready = 1;
3589 }
3590
3591 static void
3592   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3593   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   u32 i, n;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_native_fwd_rpath_t *r;
3599
3600   if (retval)
3601     goto end;
3602
3603   n = clib_net_to_host_u32 (mp->count);
3604
3605   for (i = 0; i < n; i++)
3606     {
3607       r = &mp->entries[i];
3608       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3609              clib_net_to_host_u32 (r->fib_index),
3610              clib_net_to_host_u32 (r->nh_sw_if_index),
3611              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3612     }
3613
3614 end:
3615   vam->retval = retval;
3616   vam->result_ready = 1;
3617 }
3618
3619 static void
3620   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3621   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t root, *e;
3625   u32 i, n;
3626   int retval = clib_net_to_host_u32 (mp->retval);
3627   vl_api_gpe_native_fwd_rpath_t *r;
3628   u8 *s;
3629
3630   if (retval)
3631     goto end;
3632
3633   n = clib_net_to_host_u32 (mp->count);
3634   vat_json_init_array (&root);
3635
3636   for (i = 0; i < n; i++)
3637     {
3638       e = vat_json_array_add (&root);
3639       vat_json_init_object (e);
3640       r = &mp->entries[i];
3641       s =
3642         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3643                 r->nh_addr);
3644       vec_add1 (s, 0);
3645       vat_json_object_add_string_copy (e, "ip4", s);
3646       vec_free (s);
3647
3648       vat_json_object_add_uint (e, "fib_index",
3649                                 clib_net_to_host_u32 (r->fib_index));
3650       vat_json_object_add_uint (e, "nh_sw_if_index",
3651                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3652     }
3653
3654   vat_json_print (vam->ofp, &root);
3655   vat_json_free (&root);
3656
3657 end:
3658   vam->retval = retval;
3659   vam->result_ready = 1;
3660 }
3661
3662 static void
3663   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3664   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3665 {
3666   vat_main_t *vam = &vat_main;
3667   u32 i, n;
3668   int retval = clib_net_to_host_u32 (mp->retval);
3669
3670   if (retval)
3671     goto end;
3672
3673   n = clib_net_to_host_u32 (mp->count);
3674
3675   for (i = 0; i < n; i++)
3676     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3677
3678 end:
3679   vam->retval = retval;
3680   vam->result_ready = 1;
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3685   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t root;
3689   u32 i, n;
3690   int retval = clib_net_to_host_u32 (mp->retval);
3691
3692   if (retval)
3693     goto end;
3694
3695   n = clib_net_to_host_u32 (mp->count);
3696   vat_json_init_array (&root);
3697
3698   for (i = 0; i < n; i++)
3699     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3700
3701   vat_json_print (vam->ofp, &root);
3702   vat_json_free (&root);
3703
3704 end:
3705   vam->retval = retval;
3706   vam->result_ready = 1;
3707 }
3708
3709 static void
3710   vl_api_one_ndp_entries_get_reply_t_handler
3711   (vl_api_one_ndp_entries_get_reply_t * mp)
3712 {
3713   vat_main_t *vam = &vat_main;
3714   u32 i, n;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716
3717   if (retval)
3718     goto end;
3719
3720   n = clib_net_to_host_u32 (mp->count);
3721
3722   for (i = 0; i < n; i++)
3723     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3724            format_ethernet_address, mp->entries[i].mac);
3725
3726 end:
3727   vam->retval = retval;
3728   vam->result_ready = 1;
3729 }
3730
3731 static void
3732   vl_api_one_ndp_entries_get_reply_t_handler_json
3733   (vl_api_one_ndp_entries_get_reply_t * mp)
3734 {
3735   u8 *s = 0;
3736   vat_main_t *vam = &vat_main;
3737   vat_json_node_t *e = 0, root;
3738   u32 i, n;
3739   int retval = clib_net_to_host_u32 (mp->retval);
3740   vl_api_one_ndp_entry_t *arp_entry;
3741
3742   if (retval)
3743     goto end;
3744
3745   n = clib_net_to_host_u32 (mp->count);
3746   vat_json_init_array (&root);
3747
3748   for (i = 0; i < n; i++)
3749     {
3750       e = vat_json_array_add (&root);
3751       arp_entry = &mp->entries[i];
3752
3753       vat_json_init_object (e);
3754       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3755       vec_add1 (s, 0);
3756
3757       vat_json_object_add_string_copy (e, "mac", s);
3758       vec_free (s);
3759
3760       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3761       vec_add1 (s, 0);
3762       vat_json_object_add_string_copy (e, "ip6", s);
3763       vec_free (s);
3764     }
3765
3766   vat_json_print (vam->ofp, &root);
3767   vat_json_free (&root);
3768
3769 end:
3770   vam->retval = retval;
3771   vam->result_ready = 1;
3772 }
3773
3774 static void
3775   vl_api_one_l2_arp_entries_get_reply_t_handler
3776   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3777 {
3778   vat_main_t *vam = &vat_main;
3779   u32 i, n;
3780   int retval = clib_net_to_host_u32 (mp->retval);
3781
3782   if (retval)
3783     goto end;
3784
3785   n = clib_net_to_host_u32 (mp->count);
3786
3787   for (i = 0; i < n; i++)
3788     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3789            format_ethernet_address, mp->entries[i].mac);
3790
3791 end:
3792   vam->retval = retval;
3793   vam->result_ready = 1;
3794 }
3795
3796 static void
3797   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3798   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3799 {
3800   u8 *s = 0;
3801   vat_main_t *vam = &vat_main;
3802   vat_json_node_t *e = 0, root;
3803   u32 i, n;
3804   int retval = clib_net_to_host_u32 (mp->retval);
3805   vl_api_one_l2_arp_entry_t *arp_entry;
3806
3807   if (retval)
3808     goto end;
3809
3810   n = clib_net_to_host_u32 (mp->count);
3811   vat_json_init_array (&root);
3812
3813   for (i = 0; i < n; i++)
3814     {
3815       e = vat_json_array_add (&root);
3816       arp_entry = &mp->entries[i];
3817
3818       vat_json_init_object (e);
3819       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3820       vec_add1 (s, 0);
3821
3822       vat_json_object_add_string_copy (e, "mac", s);
3823       vec_free (s);
3824
3825       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3826       vec_add1 (s, 0);
3827       vat_json_object_add_string_copy (e, "ip4", s);
3828       vec_free (s);
3829     }
3830
3831   vat_json_print (vam->ofp, &root);
3832   vat_json_free (&root);
3833
3834 end:
3835   vam->retval = retval;
3836   vam->result_ready = 1;
3837 }
3838
3839 static void
3840 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3841 {
3842   vat_main_t *vam = &vat_main;
3843   u32 i, n;
3844   int retval = clib_net_to_host_u32 (mp->retval);
3845
3846   if (retval)
3847     goto end;
3848
3849   n = clib_net_to_host_u32 (mp->count);
3850
3851   for (i = 0; i < n; i++)
3852     {
3853       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3854     }
3855
3856 end:
3857   vam->retval = retval;
3858   vam->result_ready = 1;
3859 }
3860
3861 static void
3862   vl_api_one_ndp_bd_get_reply_t_handler_json
3863   (vl_api_one_ndp_bd_get_reply_t * mp)
3864 {
3865   vat_main_t *vam = &vat_main;
3866   vat_json_node_t root;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874   vat_json_init_array (&root);
3875
3876   for (i = 0; i < n; i++)
3877     {
3878       vat_json_array_add_uint (&root,
3879                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3880     }
3881
3882   vat_json_print (vam->ofp, &root);
3883   vat_json_free (&root);
3884
3885 end:
3886   vam->retval = retval;
3887   vam->result_ready = 1;
3888 }
3889
3890 static void
3891   vl_api_one_l2_arp_bd_get_reply_t_handler
3892   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3893 {
3894   vat_main_t *vam = &vat_main;
3895   u32 i, n;
3896   int retval = clib_net_to_host_u32 (mp->retval);
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902
3903   for (i = 0; i < n; i++)
3904     {
3905       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3906     }
3907
3908 end:
3909   vam->retval = retval;
3910   vam->result_ready = 1;
3911 }
3912
3913 static void
3914   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3915   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3916 {
3917   vat_main_t *vam = &vat_main;
3918   vat_json_node_t root;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926   vat_json_init_array (&root);
3927
3928   for (i = 0; i < n; i++)
3929     {
3930       vat_json_array_add_uint (&root,
3931                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3932     }
3933
3934   vat_json_print (vam->ofp, &root);
3935   vat_json_free (&root);
3936
3937 end:
3938   vam->retval = retval;
3939   vam->result_ready = 1;
3940 }
3941
3942 static void
3943   vl_api_one_adjacencies_get_reply_t_handler
3944   (vl_api_one_adjacencies_get_reply_t * mp)
3945 {
3946   vat_main_t *vam = &vat_main;
3947   u32 i, n;
3948   int retval = clib_net_to_host_u32 (mp->retval);
3949   vl_api_one_adjacency_t *a;
3950
3951   if (retval)
3952     goto end;
3953
3954   n = clib_net_to_host_u32 (mp->count);
3955
3956   for (i = 0; i < n; i++)
3957     {
3958       a = &mp->adjacencies[i];
3959       print (vam->ofp, "%U %40U",
3960              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3961              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3962     }
3963
3964 end:
3965   vam->retval = retval;
3966   vam->result_ready = 1;
3967 }
3968
3969 static void
3970   vl_api_one_adjacencies_get_reply_t_handler_json
3971   (vl_api_one_adjacencies_get_reply_t * mp)
3972 {
3973   u8 *s = 0;
3974   vat_main_t *vam = &vat_main;
3975   vat_json_node_t *e = 0, root;
3976   u32 i, n;
3977   int retval = clib_net_to_host_u32 (mp->retval);
3978   vl_api_one_adjacency_t *a;
3979
3980   if (retval)
3981     goto end;
3982
3983   n = clib_net_to_host_u32 (mp->count);
3984   vat_json_init_array (&root);
3985
3986   for (i = 0; i < n; i++)
3987     {
3988       e = vat_json_array_add (&root);
3989       a = &mp->adjacencies[i];
3990
3991       vat_json_init_object (e);
3992       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3993                   a->leid_prefix_len);
3994       vec_add1 (s, 0);
3995       vat_json_object_add_string_copy (e, "leid", s);
3996       vec_free (s);
3997
3998       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3999                   a->reid_prefix_len);
4000       vec_add1 (s, 0);
4001       vat_json_object_add_string_copy (e, "reid", s);
4002       vec_free (s);
4003     }
4004
4005   vat_json_print (vam->ofp, &root);
4006   vat_json_free (&root);
4007
4008 end:
4009   vam->retval = retval;
4010   vam->result_ready = 1;
4011 }
4012
4013 static void
4014 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4015 {
4016   vat_main_t *vam = &vat_main;
4017
4018   print (vam->ofp, "%=20U",
4019          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4020          mp->ip_address);
4021 }
4022
4023 static void
4024   vl_api_one_map_server_details_t_handler_json
4025   (vl_api_one_map_server_details_t * mp)
4026 {
4027   vat_main_t *vam = &vat_main;
4028   vat_json_node_t *node = NULL;
4029   struct in6_addr ip6;
4030   struct in_addr ip4;
4031
4032   if (VAT_JSON_ARRAY != vam->json_tree.type)
4033     {
4034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4035       vat_json_init_array (&vam->json_tree);
4036     }
4037   node = vat_json_array_add (&vam->json_tree);
4038
4039   vat_json_init_object (node);
4040   if (mp->is_ipv6)
4041     {
4042       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4043       vat_json_object_add_ip6 (node, "map-server", ip6);
4044     }
4045   else
4046     {
4047       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4048       vat_json_object_add_ip4 (node, "map-server", ip4);
4049     }
4050 }
4051
4052 static void
4053 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4054                                            * mp)
4055 {
4056   vat_main_t *vam = &vat_main;
4057
4058   print (vam->ofp, "%=20U",
4059          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4060          mp->ip_address);
4061 }
4062
4063 static void
4064   vl_api_one_map_resolver_details_t_handler_json
4065   (vl_api_one_map_resolver_details_t * mp)
4066 {
4067   vat_main_t *vam = &vat_main;
4068   vat_json_node_t *node = NULL;
4069   struct in6_addr ip6;
4070   struct in_addr ip4;
4071
4072   if (VAT_JSON_ARRAY != vam->json_tree.type)
4073     {
4074       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4075       vat_json_init_array (&vam->json_tree);
4076     }
4077   node = vat_json_array_add (&vam->json_tree);
4078
4079   vat_json_init_object (node);
4080   if (mp->is_ipv6)
4081     {
4082       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4083       vat_json_object_add_ip6 (node, "map resolver", ip6);
4084     }
4085   else
4086     {
4087       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4088       vat_json_object_add_ip4 (node, "map resolver", ip4);
4089     }
4090 }
4091
4092 static void
4093 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4094 {
4095   vat_main_t *vam = &vat_main;
4096   i32 retval = ntohl (mp->retval);
4097
4098   if (0 <= retval)
4099     {
4100       print (vam->ofp, "feature: %s\ngpe: %s",
4101              mp->feature_status ? "enabled" : "disabled",
4102              mp->gpe_status ? "enabled" : "disabled");
4103     }
4104
4105   vam->retval = retval;
4106   vam->result_ready = 1;
4107 }
4108
4109 static void
4110   vl_api_show_one_status_reply_t_handler_json
4111   (vl_api_show_one_status_reply_t * mp)
4112 {
4113   vat_main_t *vam = &vat_main;
4114   vat_json_node_t node;
4115   u8 *gpe_status = NULL;
4116   u8 *feature_status = NULL;
4117
4118   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4119   feature_status = format (0, "%s",
4120                            mp->feature_status ? "enabled" : "disabled");
4121   vec_add1 (gpe_status, 0);
4122   vec_add1 (feature_status, 0);
4123
4124   vat_json_init_object (&node);
4125   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4126   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4127
4128   vec_free (gpe_status);
4129   vec_free (feature_status);
4130
4131   vat_json_print (vam->ofp, &node);
4132   vat_json_free (&node);
4133
4134   vam->retval = ntohl (mp->retval);
4135   vam->result_ready = 1;
4136 }
4137
4138 static void
4139   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4140   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4141 {
4142   vat_main_t *vam = &vat_main;
4143   i32 retval = ntohl (mp->retval);
4144
4145   if (retval >= 0)
4146     {
4147       print (vam->ofp, "%=20s", mp->locator_set_name);
4148     }
4149
4150   vam->retval = retval;
4151   vam->result_ready = 1;
4152 }
4153
4154 static void
4155   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4156   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   vat_json_node_t *node = NULL;
4160
4161   if (VAT_JSON_ARRAY != vam->json_tree.type)
4162     {
4163       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4164       vat_json_init_array (&vam->json_tree);
4165     }
4166   node = vat_json_array_add (&vam->json_tree);
4167
4168   vat_json_init_object (node);
4169   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4170
4171   vat_json_print (vam->ofp, node);
4172   vat_json_free (node);
4173
4174   vam->retval = ntohl (mp->retval);
4175   vam->result_ready = 1;
4176 }
4177
4178 static u8 *
4179 format_lisp_map_request_mode (u8 * s, va_list * args)
4180 {
4181   u32 mode = va_arg (*args, u32);
4182
4183   switch (mode)
4184     {
4185     case 0:
4186       return format (0, "dst-only");
4187     case 1:
4188       return format (0, "src-dst");
4189     }
4190   return 0;
4191 }
4192
4193 static void
4194   vl_api_show_one_map_request_mode_reply_t_handler
4195   (vl_api_show_one_map_request_mode_reply_t * mp)
4196 {
4197   vat_main_t *vam = &vat_main;
4198   i32 retval = ntohl (mp->retval);
4199
4200   if (0 <= retval)
4201     {
4202       u32 mode = mp->mode;
4203       print (vam->ofp, "map_request_mode: %U",
4204              format_lisp_map_request_mode, mode);
4205     }
4206
4207   vam->retval = retval;
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_show_one_map_request_mode_reply_t_handler_json
4213   (vl_api_show_one_map_request_mode_reply_t * mp)
4214 {
4215   vat_main_t *vam = &vat_main;
4216   vat_json_node_t node;
4217   u8 *s = 0;
4218   u32 mode;
4219
4220   mode = mp->mode;
4221   s = format (0, "%U", format_lisp_map_request_mode, mode);
4222   vec_add1 (s, 0);
4223
4224   vat_json_init_object (&node);
4225   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4226   vat_json_print (vam->ofp, &node);
4227   vat_json_free (&node);
4228
4229   vec_free (s);
4230   vam->retval = ntohl (mp->retval);
4231   vam->result_ready = 1;
4232 }
4233
4234 static void
4235   vl_api_one_show_xtr_mode_reply_t_handler
4236   (vl_api_one_show_xtr_mode_reply_t * mp)
4237 {
4238   vat_main_t *vam = &vat_main;
4239   i32 retval = ntohl (mp->retval);
4240
4241   if (0 <= retval)
4242     {
4243       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4244     }
4245
4246   vam->retval = retval;
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_show_xtr_mode_reply_t_handler_json
4252   (vl_api_one_show_xtr_mode_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   vat_json_node_t node;
4256   u8 *status = 0;
4257
4258   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4259   vec_add1 (status, 0);
4260
4261   vat_json_init_object (&node);
4262   vat_json_object_add_string_copy (&node, "status", status);
4263
4264   vec_free (status);
4265
4266   vat_json_print (vam->ofp, &node);
4267   vat_json_free (&node);
4268
4269   vam->retval = ntohl (mp->retval);
4270   vam->result_ready = 1;
4271 }
4272
4273 static void
4274   vl_api_one_show_pitr_mode_reply_t_handler
4275   (vl_api_one_show_pitr_mode_reply_t * mp)
4276 {
4277   vat_main_t *vam = &vat_main;
4278   i32 retval = ntohl (mp->retval);
4279
4280   if (0 <= retval)
4281     {
4282       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4283     }
4284
4285   vam->retval = retval;
4286   vam->result_ready = 1;
4287 }
4288
4289 static void
4290   vl_api_one_show_pitr_mode_reply_t_handler_json
4291   (vl_api_one_show_pitr_mode_reply_t * mp)
4292 {
4293   vat_main_t *vam = &vat_main;
4294   vat_json_node_t node;
4295   u8 *status = 0;
4296
4297   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4298   vec_add1 (status, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "status", status);
4302
4303   vec_free (status);
4304
4305   vat_json_print (vam->ofp, &node);
4306   vat_json_free (&node);
4307
4308   vam->retval = ntohl (mp->retval);
4309   vam->result_ready = 1;
4310 }
4311
4312 static void
4313   vl_api_one_show_petr_mode_reply_t_handler
4314   (vl_api_one_show_petr_mode_reply_t * mp)
4315 {
4316   vat_main_t *vam = &vat_main;
4317   i32 retval = ntohl (mp->retval);
4318
4319   if (0 <= retval)
4320     {
4321       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4322     }
4323
4324   vam->retval = retval;
4325   vam->result_ready = 1;
4326 }
4327
4328 static void
4329   vl_api_one_show_petr_mode_reply_t_handler_json
4330   (vl_api_one_show_petr_mode_reply_t * mp)
4331 {
4332   vat_main_t *vam = &vat_main;
4333   vat_json_node_t node;
4334   u8 *status = 0;
4335
4336   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4337   vec_add1 (status, 0);
4338
4339   vat_json_init_object (&node);
4340   vat_json_object_add_string_copy (&node, "status", status);
4341
4342   vec_free (status);
4343
4344   vat_json_print (vam->ofp, &node);
4345   vat_json_free (&node);
4346
4347   vam->retval = ntohl (mp->retval);
4348   vam->result_ready = 1;
4349 }
4350
4351 static void
4352   vl_api_show_one_use_petr_reply_t_handler
4353   (vl_api_show_one_use_petr_reply_t * mp)
4354 {
4355   vat_main_t *vam = &vat_main;
4356   i32 retval = ntohl (mp->retval);
4357
4358   if (0 <= retval)
4359     {
4360       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4361       if (mp->status)
4362         {
4363           print (vam->ofp, "Proxy-ETR address; %U",
4364                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4365                  mp->address);
4366         }
4367     }
4368
4369   vam->retval = retval;
4370   vam->result_ready = 1;
4371 }
4372
4373 static void
4374   vl_api_show_one_use_petr_reply_t_handler_json
4375   (vl_api_show_one_use_petr_reply_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378   vat_json_node_t node;
4379   u8 *status = 0;
4380   struct in_addr ip4;
4381   struct in6_addr ip6;
4382
4383   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4384   vec_add1 (status, 0);
4385
4386   vat_json_init_object (&node);
4387   vat_json_object_add_string_copy (&node, "status", status);
4388   if (mp->status)
4389     {
4390       if (mp->is_ip4)
4391         {
4392           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4393           vat_json_object_add_ip6 (&node, "address", ip6);
4394         }
4395       else
4396         {
4397           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4398           vat_json_object_add_ip4 (&node, "address", ip4);
4399         }
4400     }
4401
4402   vec_free (status);
4403
4404   vat_json_print (vam->ofp, &node);
4405   vat_json_free (&node);
4406
4407   vam->retval = ntohl (mp->retval);
4408   vam->result_ready = 1;
4409 }
4410
4411 static void
4412   vl_api_show_one_nsh_mapping_reply_t_handler
4413   (vl_api_show_one_nsh_mapping_reply_t * mp)
4414 {
4415   vat_main_t *vam = &vat_main;
4416   i32 retval = ntohl (mp->retval);
4417
4418   if (0 <= retval)
4419     {
4420       print (vam->ofp, "%-20s%-16s",
4421              mp->is_set ? "set" : "not-set",
4422              mp->is_set ? (char *) mp->locator_set_name : "");
4423     }
4424
4425   vam->retval = retval;
4426   vam->result_ready = 1;
4427 }
4428
4429 static void
4430   vl_api_show_one_nsh_mapping_reply_t_handler_json
4431   (vl_api_show_one_nsh_mapping_reply_t * mp)
4432 {
4433   vat_main_t *vam = &vat_main;
4434   vat_json_node_t node;
4435   u8 *status = 0;
4436
4437   status = format (0, "%s", mp->is_set ? "yes" : "no");
4438   vec_add1 (status, 0);
4439
4440   vat_json_init_object (&node);
4441   vat_json_object_add_string_copy (&node, "is_set", status);
4442   if (mp->is_set)
4443     {
4444       vat_json_object_add_string_copy (&node, "locator_set",
4445                                        mp->locator_set_name);
4446     }
4447
4448   vec_free (status);
4449
4450   vat_json_print (vam->ofp, &node);
4451   vat_json_free (&node);
4452
4453   vam->retval = ntohl (mp->retval);
4454   vam->result_ready = 1;
4455 }
4456
4457 static void
4458   vl_api_show_one_map_register_ttl_reply_t_handler
4459   (vl_api_show_one_map_register_ttl_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462   i32 retval = ntohl (mp->retval);
4463
4464   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4465
4466   if (0 <= retval)
4467     {
4468       print (vam->ofp, "ttl: %u", mp->ttl);
4469     }
4470
4471   vam->retval = retval;
4472   vam->result_ready = 1;
4473 }
4474
4475 static void
4476   vl_api_show_one_map_register_ttl_reply_t_handler_json
4477   (vl_api_show_one_map_register_ttl_reply_t * mp)
4478 {
4479   vat_main_t *vam = &vat_main;
4480   vat_json_node_t node;
4481
4482   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4483   vat_json_init_object (&node);
4484   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4485
4486   vat_json_print (vam->ofp, &node);
4487   vat_json_free (&node);
4488
4489   vam->retval = ntohl (mp->retval);
4490   vam->result_ready = 1;
4491 }
4492
4493 static void
4494 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4495 {
4496   vat_main_t *vam = &vat_main;
4497   i32 retval = ntohl (mp->retval);
4498
4499   if (0 <= retval)
4500     {
4501       print (vam->ofp, "%-20s%-16s",
4502              mp->status ? "enabled" : "disabled",
4503              mp->status ? (char *) mp->locator_set_name : "");
4504     }
4505
4506   vam->retval = retval;
4507   vam->result_ready = 1;
4508 }
4509
4510 static void
4511 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4512 {
4513   vat_main_t *vam = &vat_main;
4514   vat_json_node_t node;
4515   u8 *status = 0;
4516
4517   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4518   vec_add1 (status, 0);
4519
4520   vat_json_init_object (&node);
4521   vat_json_object_add_string_copy (&node, "status", status);
4522   if (mp->status)
4523     {
4524       vat_json_object_add_string_copy (&node, "locator_set",
4525                                        mp->locator_set_name);
4526     }
4527
4528   vec_free (status);
4529
4530   vat_json_print (vam->ofp, &node);
4531   vat_json_free (&node);
4532
4533   vam->retval = ntohl (mp->retval);
4534   vam->result_ready = 1;
4535 }
4536
4537 static u8 *
4538 format_policer_type (u8 * s, va_list * va)
4539 {
4540   u32 i = va_arg (*va, u32);
4541
4542   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4543     s = format (s, "1r2c");
4544   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4545     s = format (s, "1r3c");
4546   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4547     s = format (s, "2r3c-2698");
4548   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4549     s = format (s, "2r3c-4115");
4550   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4551     s = format (s, "2r3c-mef5cf1");
4552   else
4553     s = format (s, "ILLEGAL");
4554   return s;
4555 }
4556
4557 static u8 *
4558 format_policer_rate_type (u8 * s, va_list * va)
4559 {
4560   u32 i = va_arg (*va, u32);
4561
4562   if (i == SSE2_QOS_RATE_KBPS)
4563     s = format (s, "kbps");
4564   else if (i == SSE2_QOS_RATE_PPS)
4565     s = format (s, "pps");
4566   else
4567     s = format (s, "ILLEGAL");
4568   return s;
4569 }
4570
4571 static u8 *
4572 format_policer_round_type (u8 * s, va_list * va)
4573 {
4574   u32 i = va_arg (*va, u32);
4575
4576   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4577     s = format (s, "closest");
4578   else if (i == SSE2_QOS_ROUND_TO_UP)
4579     s = format (s, "up");
4580   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4581     s = format (s, "down");
4582   else
4583     s = format (s, "ILLEGAL");
4584   return s;
4585 }
4586
4587 static u8 *
4588 format_policer_action_type (u8 * s, va_list * va)
4589 {
4590   u32 i = va_arg (*va, u32);
4591
4592   if (i == SSE2_QOS_ACTION_DROP)
4593     s = format (s, "drop");
4594   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4595     s = format (s, "transmit");
4596   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4597     s = format (s, "mark-and-transmit");
4598   else
4599     s = format (s, "ILLEGAL");
4600   return s;
4601 }
4602
4603 static u8 *
4604 format_dscp (u8 * s, va_list * va)
4605 {
4606   u32 i = va_arg (*va, u32);
4607   char *t = 0;
4608
4609   switch (i)
4610     {
4611 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4612       foreach_vnet_dscp
4613 #undef _
4614     default:
4615       return format (s, "ILLEGAL");
4616     }
4617   s = format (s, "%s", t);
4618   return s;
4619 }
4620
4621 static void
4622 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4623 {
4624   vat_main_t *vam = &vat_main;
4625   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4626
4627   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4628     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4629   else
4630     conform_dscp_str = format (0, "");
4631
4632   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4633     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4634   else
4635     exceed_dscp_str = format (0, "");
4636
4637   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4638     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4639   else
4640     violate_dscp_str = format (0, "");
4641
4642   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4643          "rate type %U, round type %U, %s rate, %s color-aware, "
4644          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4645          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4646          "conform action %U%s, exceed action %U%s, violate action %U%s",
4647          mp->name,
4648          format_policer_type, mp->type,
4649          ntohl (mp->cir),
4650          ntohl (mp->eir),
4651          clib_net_to_host_u64 (mp->cb),
4652          clib_net_to_host_u64 (mp->eb),
4653          format_policer_rate_type, mp->rate_type,
4654          format_policer_round_type, mp->round_type,
4655          mp->single_rate ? "single" : "dual",
4656          mp->color_aware ? "is" : "not",
4657          ntohl (mp->cir_tokens_per_period),
4658          ntohl (mp->pir_tokens_per_period),
4659          ntohl (mp->scale),
4660          ntohl (mp->current_limit),
4661          ntohl (mp->current_bucket),
4662          ntohl (mp->extended_limit),
4663          ntohl (mp->extended_bucket),
4664          clib_net_to_host_u64 (mp->last_update_time),
4665          format_policer_action_type, mp->conform_action_type,
4666          conform_dscp_str,
4667          format_policer_action_type, mp->exceed_action_type,
4668          exceed_dscp_str,
4669          format_policer_action_type, mp->violate_action_type,
4670          violate_dscp_str);
4671
4672   vec_free (conform_dscp_str);
4673   vec_free (exceed_dscp_str);
4674   vec_free (violate_dscp_str);
4675 }
4676
4677 static void vl_api_policer_details_t_handler_json
4678   (vl_api_policer_details_t * mp)
4679 {
4680   vat_main_t *vam = &vat_main;
4681   vat_json_node_t *node;
4682   u8 *rate_type_str, *round_type_str, *type_str;
4683   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4684
4685   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4686   round_type_str =
4687     format (0, "%U", format_policer_round_type, mp->round_type);
4688   type_str = format (0, "%U", format_policer_type, mp->type);
4689   conform_action_str = format (0, "%U", format_policer_action_type,
4690                                mp->conform_action_type);
4691   exceed_action_str = format (0, "%U", format_policer_action_type,
4692                               mp->exceed_action_type);
4693   violate_action_str = format (0, "%U", format_policer_action_type,
4694                                mp->violate_action_type);
4695
4696   if (VAT_JSON_ARRAY != vam->json_tree.type)
4697     {
4698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4699       vat_json_init_array (&vam->json_tree);
4700     }
4701   node = vat_json_array_add (&vam->json_tree);
4702
4703   vat_json_init_object (node);
4704   vat_json_object_add_string_copy (node, "name", mp->name);
4705   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4706   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4707   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4708   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4709   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4710   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4711   vat_json_object_add_string_copy (node, "type", type_str);
4712   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4713   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4714   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4715   vat_json_object_add_uint (node, "cir_tokens_per_period",
4716                             ntohl (mp->cir_tokens_per_period));
4717   vat_json_object_add_uint (node, "eir_tokens_per_period",
4718                             ntohl (mp->pir_tokens_per_period));
4719   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4720   vat_json_object_add_uint (node, "current_bucket",
4721                             ntohl (mp->current_bucket));
4722   vat_json_object_add_uint (node, "extended_limit",
4723                             ntohl (mp->extended_limit));
4724   vat_json_object_add_uint (node, "extended_bucket",
4725                             ntohl (mp->extended_bucket));
4726   vat_json_object_add_uint (node, "last_update_time",
4727                             ntohl (mp->last_update_time));
4728   vat_json_object_add_string_copy (node, "conform_action",
4729                                    conform_action_str);
4730   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4731     {
4732       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4733       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4734       vec_free (dscp_str);
4735     }
4736   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4737   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4738     {
4739       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4740       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4741       vec_free (dscp_str);
4742     }
4743   vat_json_object_add_string_copy (node, "violate_action",
4744                                    violate_action_str);
4745   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4746     {
4747       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4748       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4749       vec_free (dscp_str);
4750     }
4751
4752   vec_free (rate_type_str);
4753   vec_free (round_type_str);
4754   vec_free (type_str);
4755   vec_free (conform_action_str);
4756   vec_free (exceed_action_str);
4757   vec_free (violate_action_str);
4758 }
4759
4760 static void
4761 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4762                                            mp)
4763 {
4764   vat_main_t *vam = &vat_main;
4765   int i, count = ntohl (mp->count);
4766
4767   if (count > 0)
4768     print (vam->ofp, "classify table ids (%d) : ", count);
4769   for (i = 0; i < count; i++)
4770     {
4771       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4772       print (vam->ofp, (i < count - 1) ? "," : "");
4773     }
4774   vam->retval = ntohl (mp->retval);
4775   vam->result_ready = 1;
4776 }
4777
4778 static void
4779   vl_api_classify_table_ids_reply_t_handler_json
4780   (vl_api_classify_table_ids_reply_t * mp)
4781 {
4782   vat_main_t *vam = &vat_main;
4783   int i, count = ntohl (mp->count);
4784
4785   if (count > 0)
4786     {
4787       vat_json_node_t node;
4788
4789       vat_json_init_object (&node);
4790       for (i = 0; i < count; i++)
4791         {
4792           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4793         }
4794       vat_json_print (vam->ofp, &node);
4795       vat_json_free (&node);
4796     }
4797   vam->retval = ntohl (mp->retval);
4798   vam->result_ready = 1;
4799 }
4800
4801 static void
4802   vl_api_classify_table_by_interface_reply_t_handler
4803   (vl_api_classify_table_by_interface_reply_t * mp)
4804 {
4805   vat_main_t *vam = &vat_main;
4806   u32 table_id;
4807
4808   table_id = ntohl (mp->l2_table_id);
4809   if (table_id != ~0)
4810     print (vam->ofp, "l2 table id : %d", table_id);
4811   else
4812     print (vam->ofp, "l2 table id : No input ACL tables configured");
4813   table_id = ntohl (mp->ip4_table_id);
4814   if (table_id != ~0)
4815     print (vam->ofp, "ip4 table id : %d", table_id);
4816   else
4817     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4818   table_id = ntohl (mp->ip6_table_id);
4819   if (table_id != ~0)
4820     print (vam->ofp, "ip6 table id : %d", table_id);
4821   else
4822     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4823   vam->retval = ntohl (mp->retval);
4824   vam->result_ready = 1;
4825 }
4826
4827 static void
4828   vl_api_classify_table_by_interface_reply_t_handler_json
4829   (vl_api_classify_table_by_interface_reply_t * mp)
4830 {
4831   vat_main_t *vam = &vat_main;
4832   vat_json_node_t node;
4833
4834   vat_json_init_object (&node);
4835
4836   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4837   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4838   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4839
4840   vat_json_print (vam->ofp, &node);
4841   vat_json_free (&node);
4842
4843   vam->retval = ntohl (mp->retval);
4844   vam->result_ready = 1;
4845 }
4846
4847 static void vl_api_policer_add_del_reply_t_handler
4848   (vl_api_policer_add_del_reply_t * mp)
4849 {
4850   vat_main_t *vam = &vat_main;
4851   i32 retval = ntohl (mp->retval);
4852   if (vam->async_mode)
4853     {
4854       vam->async_errors += (retval < 0);
4855     }
4856   else
4857     {
4858       vam->retval = retval;
4859       vam->result_ready = 1;
4860       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4861         /*
4862          * Note: this is just barely thread-safe, depends on
4863          * the main thread spinning waiting for an answer...
4864          */
4865         errmsg ("policer index %d", ntohl (mp->policer_index));
4866     }
4867 }
4868
4869 static void vl_api_policer_add_del_reply_t_handler_json
4870   (vl_api_policer_add_del_reply_t * mp)
4871 {
4872   vat_main_t *vam = &vat_main;
4873   vat_json_node_t node;
4874
4875   vat_json_init_object (&node);
4876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4877   vat_json_object_add_uint (&node, "policer_index",
4878                             ntohl (mp->policer_index));
4879
4880   vat_json_print (vam->ofp, &node);
4881   vat_json_free (&node);
4882
4883   vam->retval = ntohl (mp->retval);
4884   vam->result_ready = 1;
4885 }
4886
4887 /* Format hex dump. */
4888 u8 *
4889 format_hex_bytes (u8 * s, va_list * va)
4890 {
4891   u8 *bytes = va_arg (*va, u8 *);
4892   int n_bytes = va_arg (*va, int);
4893   uword i;
4894
4895   /* Print short or long form depending on byte count. */
4896   uword short_form = n_bytes <= 32;
4897   u32 indent = format_get_indent (s);
4898
4899   if (n_bytes == 0)
4900     return s;
4901
4902   for (i = 0; i < n_bytes; i++)
4903     {
4904       if (!short_form && (i % 32) == 0)
4905         s = format (s, "%08x: ", i);
4906       s = format (s, "%02x", bytes[i]);
4907       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4908         s = format (s, "\n%U", format_white_space, indent);
4909     }
4910
4911   return s;
4912 }
4913
4914 static void
4915 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4916                                             * mp)
4917 {
4918   vat_main_t *vam = &vat_main;
4919   i32 retval = ntohl (mp->retval);
4920   if (retval == 0)
4921     {
4922       print (vam->ofp, "classify table info :");
4923       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4924              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4925              ntohl (mp->miss_next_index));
4926       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4927              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4928              ntohl (mp->match_n_vectors));
4929       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4930              ntohl (mp->mask_length));
4931     }
4932   vam->retval = retval;
4933   vam->result_ready = 1;
4934 }
4935
4936 static void
4937   vl_api_classify_table_info_reply_t_handler_json
4938   (vl_api_classify_table_info_reply_t * mp)
4939 {
4940   vat_main_t *vam = &vat_main;
4941   vat_json_node_t node;
4942
4943   i32 retval = ntohl (mp->retval);
4944   if (retval == 0)
4945     {
4946       vat_json_init_object (&node);
4947
4948       vat_json_object_add_int (&node, "sessions",
4949                                ntohl (mp->active_sessions));
4950       vat_json_object_add_int (&node, "nexttbl",
4951                                ntohl (mp->next_table_index));
4952       vat_json_object_add_int (&node, "nextnode",
4953                                ntohl (mp->miss_next_index));
4954       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4955       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4956       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4957       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4958                       ntohl (mp->mask_length), 0);
4959       vat_json_object_add_string_copy (&node, "mask", s);
4960
4961       vat_json_print (vam->ofp, &node);
4962       vat_json_free (&node);
4963     }
4964   vam->retval = ntohl (mp->retval);
4965   vam->result_ready = 1;
4966 }
4967
4968 static void
4969 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4970                                            mp)
4971 {
4972   vat_main_t *vam = &vat_main;
4973
4974   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4975          ntohl (mp->hit_next_index), ntohl (mp->advance),
4976          ntohl (mp->opaque_index));
4977   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4978          ntohl (mp->match_length));
4979 }
4980
4981 static void
4982   vl_api_classify_session_details_t_handler_json
4983   (vl_api_classify_session_details_t * mp)
4984 {
4985   vat_main_t *vam = &vat_main;
4986   vat_json_node_t *node = NULL;
4987
4988   if (VAT_JSON_ARRAY != vam->json_tree.type)
4989     {
4990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4991       vat_json_init_array (&vam->json_tree);
4992     }
4993   node = vat_json_array_add (&vam->json_tree);
4994
4995   vat_json_init_object (node);
4996   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4997   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4998   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4999   u8 *s =
5000     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5001             0);
5002   vat_json_object_add_string_copy (node, "match", s);
5003 }
5004
5005 static void vl_api_pg_create_interface_reply_t_handler
5006   (vl_api_pg_create_interface_reply_t * mp)
5007 {
5008   vat_main_t *vam = &vat_main;
5009
5010   vam->retval = ntohl (mp->retval);
5011   vam->result_ready = 1;
5012 }
5013
5014 static void vl_api_pg_create_interface_reply_t_handler_json
5015   (vl_api_pg_create_interface_reply_t * mp)
5016 {
5017   vat_main_t *vam = &vat_main;
5018   vat_json_node_t node;
5019
5020   i32 retval = ntohl (mp->retval);
5021   if (retval == 0)
5022     {
5023       vat_json_init_object (&node);
5024
5025       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5026
5027       vat_json_print (vam->ofp, &node);
5028       vat_json_free (&node);
5029     }
5030   vam->retval = ntohl (mp->retval);
5031   vam->result_ready = 1;
5032 }
5033
5034 static void vl_api_policer_classify_details_t_handler
5035   (vl_api_policer_classify_details_t * mp)
5036 {
5037   vat_main_t *vam = &vat_main;
5038
5039   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5040          ntohl (mp->table_index));
5041 }
5042
5043 static void vl_api_policer_classify_details_t_handler_json
5044   (vl_api_policer_classify_details_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   vat_json_node_t *node;
5048
5049   if (VAT_JSON_ARRAY != vam->json_tree.type)
5050     {
5051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5052       vat_json_init_array (&vam->json_tree);
5053     }
5054   node = vat_json_array_add (&vam->json_tree);
5055
5056   vat_json_init_object (node);
5057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5058   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5059 }
5060
5061 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5062   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5063 {
5064   vat_main_t *vam = &vat_main;
5065   i32 retval = ntohl (mp->retval);
5066   if (vam->async_mode)
5067     {
5068       vam->async_errors += (retval < 0);
5069     }
5070   else
5071     {
5072       vam->retval = retval;
5073       vam->sw_if_index = ntohl (mp->sw_if_index);
5074       vam->result_ready = 1;
5075     }
5076   vam->regenerate_interface_table = 1;
5077 }
5078
5079 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5080   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5081 {
5082   vat_main_t *vam = &vat_main;
5083   vat_json_node_t node;
5084
5085   vat_json_init_object (&node);
5086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5087   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5088
5089   vat_json_print (vam->ofp, &node);
5090   vat_json_free (&node);
5091
5092   vam->retval = ntohl (mp->retval);
5093   vam->result_ready = 1;
5094 }
5095
5096 static void vl_api_flow_classify_details_t_handler
5097   (vl_api_flow_classify_details_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100
5101   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5102          ntohl (mp->table_index));
5103 }
5104
5105 static void vl_api_flow_classify_details_t_handler_json
5106   (vl_api_flow_classify_details_t * mp)
5107 {
5108   vat_main_t *vam = &vat_main;
5109   vat_json_node_t *node;
5110
5111   if (VAT_JSON_ARRAY != vam->json_tree.type)
5112     {
5113       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5114       vat_json_init_array (&vam->json_tree);
5115     }
5116   node = vat_json_array_add (&vam->json_tree);
5117
5118   vat_json_init_object (node);
5119   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5120   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5121 }
5122
5123 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5124 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5125 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5126 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5127 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5128 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5129 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5130 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5131 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5132 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5133
5134 /*
5135  * Generate boilerplate reply handlers, which
5136  * dig the return value out of the xxx_reply_t API message,
5137  * stick it into vam->retval, and set vam->result_ready
5138  *
5139  * Could also do this by pointing N message decode slots at
5140  * a single function, but that could break in subtle ways.
5141  */
5142
5143 #define foreach_standard_reply_retval_handler           \
5144 _(sw_interface_set_flags_reply)                         \
5145 _(sw_interface_add_del_address_reply)                   \
5146 _(sw_interface_set_rx_mode_reply)                       \
5147 _(sw_interface_set_rx_placement_reply)                  \
5148 _(sw_interface_set_table_reply)                         \
5149 _(sw_interface_set_mpls_enable_reply)                   \
5150 _(sw_interface_set_vpath_reply)                         \
5151 _(sw_interface_set_vxlan_bypass_reply)                  \
5152 _(sw_interface_set_geneve_bypass_reply)                 \
5153 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5154 _(sw_interface_set_l2_bridge_reply)                     \
5155 _(bridge_domain_add_del_reply)                          \
5156 _(sw_interface_set_l2_xconnect_reply)                   \
5157 _(l2fib_add_del_reply)                                  \
5158 _(l2fib_flush_int_reply)                                \
5159 _(l2fib_flush_bd_reply)                                 \
5160 _(ip_add_del_route_reply)                               \
5161 _(ip_table_add_del_reply)                               \
5162 _(ip_mroute_add_del_reply)                              \
5163 _(mpls_route_add_del_reply)                             \
5164 _(mpls_table_add_del_reply)                             \
5165 _(mpls_ip_bind_unbind_reply)                            \
5166 _(bier_route_add_del_reply)                             \
5167 _(bier_table_add_del_reply)                             \
5168 _(proxy_arp_add_del_reply)                              \
5169 _(proxy_arp_intfc_enable_disable_reply)                 \
5170 _(sw_interface_set_unnumbered_reply)                    \
5171 _(ip_neighbor_add_del_reply)                            \
5172 _(oam_add_del_reply)                                    \
5173 _(reset_fib_reply)                                      \
5174 _(dhcp_proxy_config_reply)                              \
5175 _(dhcp_proxy_set_vss_reply)                             \
5176 _(dhcp_client_config_reply)                             \
5177 _(set_ip_flow_hash_reply)                               \
5178 _(sw_interface_ip6_enable_disable_reply)                \
5179 _(ip6nd_proxy_add_del_reply)                            \
5180 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5181 _(sw_interface_ip6nd_ra_config_reply)                   \
5182 _(set_arp_neighbor_limit_reply)                         \
5183 _(l2_patch_add_del_reply)                               \
5184 _(sr_mpls_policy_add_reply)                             \
5185 _(sr_mpls_policy_mod_reply)                             \
5186 _(sr_mpls_policy_del_reply)                             \
5187 _(sr_policy_add_reply)                                  \
5188 _(sr_policy_mod_reply)                                  \
5189 _(sr_policy_del_reply)                                  \
5190 _(sr_localsid_add_del_reply)                            \
5191 _(sr_steering_add_del_reply)                            \
5192 _(classify_add_del_session_reply)                       \
5193 _(classify_set_interface_ip_table_reply)                \
5194 _(classify_set_interface_l2_tables_reply)               \
5195 _(l2tpv3_set_tunnel_cookies_reply)                      \
5196 _(l2tpv3_interface_enable_disable_reply)                \
5197 _(l2tpv3_set_lookup_key_reply)                          \
5198 _(l2_fib_clear_table_reply)                             \
5199 _(l2_interface_efp_filter_reply)                        \
5200 _(l2_interface_vlan_tag_rewrite_reply)                  \
5201 _(modify_vhost_user_if_reply)                           \
5202 _(delete_vhost_user_if_reply)                           \
5203 _(ip_probe_neighbor_reply)                              \
5204 _(ip_scan_neighbor_enable_disable_reply)                \
5205 _(want_ip4_arp_events_reply)                            \
5206 _(want_ip6_nd_events_reply)                             \
5207 _(want_l2_macs_events_reply)                            \
5208 _(input_acl_set_interface_reply)                        \
5209 _(ipsec_spd_add_del_reply)                              \
5210 _(ipsec_interface_add_del_spd_reply)                    \
5211 _(ipsec_spd_entry_add_del_reply)                        \
5212 _(ipsec_sad_entry_add_del_reply)                        \
5213 _(ipsec_sa_set_key_reply)                               \
5214 _(ipsec_tunnel_if_add_del_reply)                        \
5215 _(ipsec_tunnel_if_set_key_reply)                        \
5216 _(ipsec_tunnel_if_set_sa_reply)                         \
5217 _(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 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5382 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5383 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5384 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5385 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5386 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5387 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5388 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5389   sw_interface_ip6_enable_disable_reply)                                \
5390 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5391 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5392 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5393   sw_interface_ip6nd_ra_prefix_reply)                                   \
5394 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5395   sw_interface_ip6nd_ra_config_reply)                                   \
5396 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5397 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5398 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5399 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5400 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5401 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5402 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5403 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5404 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5405 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5406 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5407 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5408 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5409 classify_set_interface_ip_table_reply)                                  \
5410 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5411   classify_set_interface_l2_tables_reply)                               \
5412 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5413 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5414 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5415 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5416 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5417   l2tpv3_interface_enable_disable_reply)                                \
5418 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5419 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5420 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5421 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5422 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5423 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5424 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5425 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5426 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5427 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5428 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5429 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5430 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5431 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5432 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5433 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5434 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5435 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5436 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5437 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5438 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5439 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5440 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5441 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5442 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5443 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5444 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5445 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5446 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5447 _(L2_MACS_EVENT, l2_macs_event)                                         \
5448 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5449 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5450 _(IP_DETAILS, ip_details)                                               \
5451 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5452 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5453 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5454 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5455 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5456 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5457 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5458 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5459 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5460 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5461 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5462 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5463 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5464 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5465 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5466 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5467 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5468 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5469 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5470 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5471 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5472 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5473 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5474 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5475 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5476 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5477 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5478 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5479 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5480 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5481 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5482   one_map_register_enable_disable_reply)                                \
5483 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5484 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5485 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5486 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5487   one_map_register_fallback_threshold_reply)                            \
5488 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5489   one_rloc_probe_enable_disable_reply)                                  \
5490 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5491 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5492 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5493 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5494 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5495 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5496 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5497 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5498 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5499 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5500 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5501 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5502 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5503 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5504 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5505 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5506   show_one_stats_enable_disable_reply)                                  \
5507 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5508 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5509 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5510 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5511 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5512 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5513 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5514 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5515   one_enable_disable_pitr_mode_reply)                                   \
5516 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5517   one_enable_disable_petr_mode_reply)                                   \
5518 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5519 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5520 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5521 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5522 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5523 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5524 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5525 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5526 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5527 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5528 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5529 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5530   gpe_add_del_native_fwd_rpath_reply)                                   \
5531 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5532   gpe_fwd_entry_path_details)                                           \
5533 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5534 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5535   one_add_del_map_request_itr_rlocs_reply)                              \
5536 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5537   one_get_map_request_itr_rlocs_reply)                                  \
5538 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5539 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5540 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5541 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5542 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5543 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5544   show_one_map_register_state_reply)                                    \
5545 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5546 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5547   show_one_map_register_fallback_threshold_reply)                       \
5548 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5549 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5550 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5551 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5552 _(POLICER_DETAILS, policer_details)                                     \
5553 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5554 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5555 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5556 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5557 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5558 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5559 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5560 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5561 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5562 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5563 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5564 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5565 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5566 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5567 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5568 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5569 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5570 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5571 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5572 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5573 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5574 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5575 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5576 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5577 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5578  ip_source_and_port_range_check_add_del_reply)                          \
5579 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5580  ip_source_and_port_range_check_interface_add_del_reply)                \
5581 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5582 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5583 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5584 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5585 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5586 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5587 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5588 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5589 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5590 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5591 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5592 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5593 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5594 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5595 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5596 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5597 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5598 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5599 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5600 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5601 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5602 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5603 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5604 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5605 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5606 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5607 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5608 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5609
5610 #define foreach_standalone_reply_msg                                    \
5611 _(SW_INTERFACE_EVENT, sw_interface_event)
5612
5613 typedef struct
5614 {
5615   u8 *name;
5616   u32 value;
5617 } name_sort_t;
5618
5619 #define STR_VTR_OP_CASE(op)     \
5620     case L2_VTR_ ## op:         \
5621         return "" # op;
5622
5623 static const char *
5624 str_vtr_op (u32 vtr_op)
5625 {
5626   switch (vtr_op)
5627     {
5628       STR_VTR_OP_CASE (DISABLED);
5629       STR_VTR_OP_CASE (PUSH_1);
5630       STR_VTR_OP_CASE (PUSH_2);
5631       STR_VTR_OP_CASE (POP_1);
5632       STR_VTR_OP_CASE (POP_2);
5633       STR_VTR_OP_CASE (TRANSLATE_1_1);
5634       STR_VTR_OP_CASE (TRANSLATE_1_2);
5635       STR_VTR_OP_CASE (TRANSLATE_2_1);
5636       STR_VTR_OP_CASE (TRANSLATE_2_2);
5637     }
5638
5639   return "UNKNOWN";
5640 }
5641
5642 static int
5643 dump_sub_interface_table (vat_main_t * vam)
5644 {
5645   const sw_interface_subif_t *sub = NULL;
5646
5647   if (vam->json_output)
5648     {
5649       clib_warning
5650         ("JSON output supported only for VPE API calls and dump_stats_table");
5651       return -99;
5652     }
5653
5654   print (vam->ofp,
5655          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5656          "Interface", "sw_if_index",
5657          "sub id", "dot1ad", "tags", "outer id",
5658          "inner id", "exact", "default", "outer any", "inner any");
5659
5660   vec_foreach (sub, vam->sw_if_subif_table)
5661   {
5662     print (vam->ofp,
5663            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5664            sub->interface_name,
5665            sub->sw_if_index,
5666            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5667            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5668            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5669            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5670     if (sub->vtr_op != L2_VTR_DISABLED)
5671       {
5672         print (vam->ofp,
5673                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5674                "tag1: %d tag2: %d ]",
5675                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5676                sub->vtr_tag1, sub->vtr_tag2);
5677       }
5678   }
5679
5680   return 0;
5681 }
5682
5683 static int
5684 name_sort_cmp (void *a1, void *a2)
5685 {
5686   name_sort_t *n1 = a1;
5687   name_sort_t *n2 = a2;
5688
5689   return strcmp ((char *) n1->name, (char *) n2->name);
5690 }
5691
5692 static int
5693 dump_interface_table (vat_main_t * vam)
5694 {
5695   hash_pair_t *p;
5696   name_sort_t *nses = 0, *ns;
5697
5698   if (vam->json_output)
5699     {
5700       clib_warning
5701         ("JSON output supported only for VPE API calls and dump_stats_table");
5702       return -99;
5703     }
5704
5705   /* *INDENT-OFF* */
5706   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5707   ({
5708     vec_add2 (nses, ns, 1);
5709     ns->name = (u8 *)(p->key);
5710     ns->value = (u32) p->value[0];
5711   }));
5712   /* *INDENT-ON* */
5713
5714   vec_sort_with_function (nses, name_sort_cmp);
5715
5716   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5717   vec_foreach (ns, nses)
5718   {
5719     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5720   }
5721   vec_free (nses);
5722   return 0;
5723 }
5724
5725 static int
5726 dump_ip_table (vat_main_t * vam, int is_ipv6)
5727 {
5728   const ip_details_t *det = NULL;
5729   const ip_address_details_t *address = NULL;
5730   u32 i = ~0;
5731
5732   print (vam->ofp, "%-12s", "sw_if_index");
5733
5734   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5735   {
5736     i++;
5737     if (!det->present)
5738       {
5739         continue;
5740       }
5741     print (vam->ofp, "%-12d", i);
5742     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5743     if (!det->addr)
5744       {
5745         continue;
5746       }
5747     vec_foreach (address, det->addr)
5748     {
5749       print (vam->ofp,
5750              "            %-30U%-13d",
5751              is_ipv6 ? format_ip6_address : format_ip4_address,
5752              address->ip, address->prefix_length);
5753     }
5754   }
5755
5756   return 0;
5757 }
5758
5759 static int
5760 dump_ipv4_table (vat_main_t * vam)
5761 {
5762   if (vam->json_output)
5763     {
5764       clib_warning
5765         ("JSON output supported only for VPE API calls and dump_stats_table");
5766       return -99;
5767     }
5768
5769   return dump_ip_table (vam, 0);
5770 }
5771
5772 static int
5773 dump_ipv6_table (vat_main_t * vam)
5774 {
5775   if (vam->json_output)
5776     {
5777       clib_warning
5778         ("JSON output supported only for VPE API calls and dump_stats_table");
5779       return -99;
5780     }
5781
5782   return dump_ip_table (vam, 1);
5783 }
5784
5785 /*
5786  * Pass CLI buffers directly in the CLI_INBAND API message,
5787  * instead of an additional shared memory area.
5788  */
5789 static int
5790 exec_inband (vat_main_t * vam)
5791 {
5792   vl_api_cli_inband_t *mp;
5793   unformat_input_t *i = vam->input;
5794   int ret;
5795
5796   if (vec_len (i->buffer) == 0)
5797     return -1;
5798
5799   if (vam->exec_mode == 0 && unformat (i, "mode"))
5800     {
5801       vam->exec_mode = 1;
5802       return 0;
5803     }
5804   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5805     {
5806       vam->exec_mode = 0;
5807       return 0;
5808     }
5809
5810   /*
5811    * In order for the CLI command to work, it
5812    * must be a vector ending in \n, not a C-string ending
5813    * in \n\0.
5814    */
5815   u32 len = vec_len (vam->input->buffer);
5816   M2 (CLI_INBAND, mp, len);
5817   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5818
5819   S (mp);
5820   W (ret);
5821   /* json responses may or may not include a useful reply... */
5822   if (vec_len (vam->cmd_reply))
5823     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5824   return ret;
5825 }
5826
5827 int
5828 exec (vat_main_t * vam)
5829 {
5830   return exec_inband (vam);
5831 }
5832
5833 static int
5834 api_create_loopback (vat_main_t * vam)
5835 {
5836   unformat_input_t *i = vam->input;
5837   vl_api_create_loopback_t *mp;
5838   vl_api_create_loopback_instance_t *mp_lbi;
5839   u8 mac_address[6];
5840   u8 mac_set = 0;
5841   u8 is_specified = 0;
5842   u32 user_instance = 0;
5843   int ret;
5844
5845   clib_memset (mac_address, 0, sizeof (mac_address));
5846
5847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5848     {
5849       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5850         mac_set = 1;
5851       if (unformat (i, "instance %d", &user_instance))
5852         is_specified = 1;
5853       else
5854         break;
5855     }
5856
5857   if (is_specified)
5858     {
5859       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5860       mp_lbi->is_specified = is_specified;
5861       if (is_specified)
5862         mp_lbi->user_instance = htonl (user_instance);
5863       if (mac_set)
5864         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5865       S (mp_lbi);
5866     }
5867   else
5868     {
5869       /* Construct the API message */
5870       M (CREATE_LOOPBACK, mp);
5871       if (mac_set)
5872         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5873       S (mp);
5874     }
5875
5876   W (ret);
5877   return ret;
5878 }
5879
5880 static int
5881 api_delete_loopback (vat_main_t * vam)
5882 {
5883   unformat_input_t *i = vam->input;
5884   vl_api_delete_loopback_t *mp;
5885   u32 sw_if_index = ~0;
5886   int ret;
5887
5888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5889     {
5890       if (unformat (i, "sw_if_index %d", &sw_if_index))
5891         ;
5892       else
5893         break;
5894     }
5895
5896   if (sw_if_index == ~0)
5897     {
5898       errmsg ("missing sw_if_index");
5899       return -99;
5900     }
5901
5902   /* Construct the API message */
5903   M (DELETE_LOOPBACK, mp);
5904   mp->sw_if_index = ntohl (sw_if_index);
5905
5906   S (mp);
5907   W (ret);
5908   return ret;
5909 }
5910
5911 static int
5912 api_want_interface_events (vat_main_t * vam)
5913 {
5914   unformat_input_t *i = vam->input;
5915   vl_api_want_interface_events_t *mp;
5916   int enable = -1;
5917   int ret;
5918
5919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5920     {
5921       if (unformat (i, "enable"))
5922         enable = 1;
5923       else if (unformat (i, "disable"))
5924         enable = 0;
5925       else
5926         break;
5927     }
5928
5929   if (enable == -1)
5930     {
5931       errmsg ("missing enable|disable");
5932       return -99;
5933     }
5934
5935   M (WANT_INTERFACE_EVENTS, mp);
5936   mp->enable_disable = enable;
5937
5938   vam->interface_event_display = enable;
5939
5940   S (mp);
5941   W (ret);
5942   return ret;
5943 }
5944
5945
5946 /* Note: non-static, called once to set up the initial intfc table */
5947 int
5948 api_sw_interface_dump (vat_main_t * vam)
5949 {
5950   vl_api_sw_interface_dump_t *mp;
5951   vl_api_control_ping_t *mp_ping;
5952   hash_pair_t *p;
5953   name_sort_t *nses = 0, *ns;
5954   sw_interface_subif_t *sub = NULL;
5955   int ret;
5956
5957   /* Toss the old name table */
5958   /* *INDENT-OFF* */
5959   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5960   ({
5961     vec_add2 (nses, ns, 1);
5962     ns->name = (u8 *)(p->key);
5963     ns->value = (u32) p->value[0];
5964   }));
5965   /* *INDENT-ON* */
5966
5967   hash_free (vam->sw_if_index_by_interface_name);
5968
5969   vec_foreach (ns, nses) vec_free (ns->name);
5970
5971   vec_free (nses);
5972
5973   vec_foreach (sub, vam->sw_if_subif_table)
5974   {
5975     vec_free (sub->interface_name);
5976   }
5977   vec_free (vam->sw_if_subif_table);
5978
5979   /* recreate the interface name hash table */
5980   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5981
5982   /*
5983    * Ask for all interface names. Otherwise, the epic catalog of
5984    * name filters becomes ridiculously long, and vat ends up needing
5985    * to be taught about new interface types.
5986    */
5987   M (SW_INTERFACE_DUMP, mp);
5988   S (mp);
5989
5990   /* Use a control ping for synchronization */
5991   MPING (CONTROL_PING, mp_ping);
5992   S (mp_ping);
5993
5994   W (ret);
5995   return ret;
5996 }
5997
5998 static int
5999 api_sw_interface_set_flags (vat_main_t * vam)
6000 {
6001   unformat_input_t *i = vam->input;
6002   vl_api_sw_interface_set_flags_t *mp;
6003   u32 sw_if_index;
6004   u8 sw_if_index_set = 0;
6005   u8 admin_up = 0;
6006   int ret;
6007
6008   /* Parse args required to build the message */
6009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6010     {
6011       if (unformat (i, "admin-up"))
6012         admin_up = 1;
6013       else if (unformat (i, "admin-down"))
6014         admin_up = 0;
6015       else
6016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6017         sw_if_index_set = 1;
6018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6019         sw_if_index_set = 1;
6020       else
6021         break;
6022     }
6023
6024   if (sw_if_index_set == 0)
6025     {
6026       errmsg ("missing interface name or sw_if_index");
6027       return -99;
6028     }
6029
6030   /* Construct the API message */
6031   M (SW_INTERFACE_SET_FLAGS, mp);
6032   mp->sw_if_index = ntohl (sw_if_index);
6033   mp->admin_up_down = admin_up;
6034
6035   /* send it... */
6036   S (mp);
6037
6038   /* Wait for a reply, return the good/bad news... */
6039   W (ret);
6040   return ret;
6041 }
6042
6043 static int
6044 api_sw_interface_set_rx_mode (vat_main_t * vam)
6045 {
6046   unformat_input_t *i = vam->input;
6047   vl_api_sw_interface_set_rx_mode_t *mp;
6048   u32 sw_if_index;
6049   u8 sw_if_index_set = 0;
6050   int ret;
6051   u8 queue_id_valid = 0;
6052   u32 queue_id;
6053   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6054
6055   /* Parse args required to build the message */
6056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6057     {
6058       if (unformat (i, "queue %d", &queue_id))
6059         queue_id_valid = 1;
6060       else if (unformat (i, "polling"))
6061         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6062       else if (unformat (i, "interrupt"))
6063         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6064       else if (unformat (i, "adaptive"))
6065         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6066       else
6067         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6068         sw_if_index_set = 1;
6069       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6070         sw_if_index_set = 1;
6071       else
6072         break;
6073     }
6074
6075   if (sw_if_index_set == 0)
6076     {
6077       errmsg ("missing interface name or sw_if_index");
6078       return -99;
6079     }
6080   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6081     {
6082       errmsg ("missing rx-mode");
6083       return -99;
6084     }
6085
6086   /* Construct the API message */
6087   M (SW_INTERFACE_SET_RX_MODE, mp);
6088   mp->sw_if_index = ntohl (sw_if_index);
6089   mp->mode = mode;
6090   mp->queue_id_valid = queue_id_valid;
6091   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6092
6093   /* send it... */
6094   S (mp);
6095
6096   /* Wait for a reply, return the good/bad news... */
6097   W (ret);
6098   return ret;
6099 }
6100
6101 static int
6102 api_sw_interface_set_rx_placement (vat_main_t * vam)
6103 {
6104   unformat_input_t *i = vam->input;
6105   vl_api_sw_interface_set_rx_placement_t *mp;
6106   u32 sw_if_index;
6107   u8 sw_if_index_set = 0;
6108   int ret;
6109   u8 is_main = 0;
6110   u32 queue_id, thread_index;
6111
6112   /* Parse args required to build the message */
6113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6114     {
6115       if (unformat (i, "queue %d", &queue_id))
6116         ;
6117       else if (unformat (i, "main"))
6118         is_main = 1;
6119       else if (unformat (i, "worker %d", &thread_index))
6120         ;
6121       else
6122         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6123         sw_if_index_set = 1;
6124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6125         sw_if_index_set = 1;
6126       else
6127         break;
6128     }
6129
6130   if (sw_if_index_set == 0)
6131     {
6132       errmsg ("missing interface name or sw_if_index");
6133       return -99;
6134     }
6135
6136   if (is_main)
6137     thread_index = 0;
6138   /* Construct the API message */
6139   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6140   mp->sw_if_index = ntohl (sw_if_index);
6141   mp->worker_id = ntohl (thread_index);
6142   mp->queue_id = ntohl (queue_id);
6143   mp->is_main = is_main;
6144
6145   /* send it... */
6146   S (mp);
6147   /* Wait for a reply, return the good/bad news... */
6148   W (ret);
6149   return ret;
6150 }
6151
6152 static void vl_api_sw_interface_rx_placement_details_t_handler
6153   (vl_api_sw_interface_rx_placement_details_t * mp)
6154 {
6155   vat_main_t *vam = &vat_main;
6156   u32 worker_id = ntohl (mp->worker_id);
6157
6158   print (vam->ofp,
6159          "\n%-11d %-11s %-6d %-5d %-9s",
6160          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6161          worker_id, ntohl (mp->queue_id),
6162          (mp->mode ==
6163           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6164 }
6165
6166 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6167   (vl_api_sw_interface_rx_placement_details_t * mp)
6168 {
6169   vat_main_t *vam = &vat_main;
6170   vat_json_node_t *node = NULL;
6171
6172   if (VAT_JSON_ARRAY != vam->json_tree.type)
6173     {
6174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6175       vat_json_init_array (&vam->json_tree);
6176     }
6177   node = vat_json_array_add (&vam->json_tree);
6178
6179   vat_json_init_object (node);
6180   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6181   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6182   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6183   vat_json_object_add_uint (node, "mode", mp->mode);
6184 }
6185
6186 static int
6187 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6188 {
6189   unformat_input_t *i = vam->input;
6190   vl_api_sw_interface_rx_placement_dump_t *mp;
6191   vl_api_control_ping_t *mp_ping;
6192   int ret;
6193   u32 sw_if_index;
6194   u8 sw_if_index_set = 0;
6195
6196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6197     {
6198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6199         sw_if_index_set++;
6200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6201         sw_if_index_set++;
6202       else
6203         break;
6204     }
6205
6206   print (vam->ofp,
6207          "\n%-11s %-11s %-6s %-5s %-4s",
6208          "sw_if_index", "main/worker", "thread", "queue", "mode");
6209
6210   /* Dump Interface rx placement */
6211   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6212
6213   if (sw_if_index_set)
6214     mp->sw_if_index = htonl (sw_if_index);
6215   else
6216     mp->sw_if_index = ~0;
6217
6218   S (mp);
6219
6220   /* Use a control ping for synchronization */
6221   MPING (CONTROL_PING, mp_ping);
6222   S (mp_ping);
6223
6224   W (ret);
6225   return ret;
6226 }
6227
6228 static int
6229 api_sw_interface_clear_stats (vat_main_t * vam)
6230 {
6231   unformat_input_t *i = vam->input;
6232   vl_api_sw_interface_clear_stats_t *mp;
6233   u32 sw_if_index;
6234   u8 sw_if_index_set = 0;
6235   int ret;
6236
6237   /* Parse args required to build the message */
6238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6239     {
6240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6241         sw_if_index_set = 1;
6242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6243         sw_if_index_set = 1;
6244       else
6245         break;
6246     }
6247
6248   /* Construct the API message */
6249   M (SW_INTERFACE_CLEAR_STATS, mp);
6250
6251   if (sw_if_index_set == 1)
6252     mp->sw_if_index = ntohl (sw_if_index);
6253   else
6254     mp->sw_if_index = ~0;
6255
6256   /* send it... */
6257   S (mp);
6258
6259   /* Wait for a reply, return the good/bad news... */
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static int
6265 api_sw_interface_add_del_address (vat_main_t * vam)
6266 {
6267   unformat_input_t *i = vam->input;
6268   vl_api_sw_interface_add_del_address_t *mp;
6269   u32 sw_if_index;
6270   u8 sw_if_index_set = 0;
6271   u8 is_add = 1, del_all = 0;
6272   u32 address_length = 0;
6273   u8 v4_address_set = 0;
6274   u8 v6_address_set = 0;
6275   ip4_address_t v4address;
6276   ip6_address_t v6address;
6277   int ret;
6278
6279   /* Parse args required to build the message */
6280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6281     {
6282       if (unformat (i, "del-all"))
6283         del_all = 1;
6284       else if (unformat (i, "del"))
6285         is_add = 0;
6286       else
6287         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6288         sw_if_index_set = 1;
6289       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6290         sw_if_index_set = 1;
6291       else if (unformat (i, "%U/%d",
6292                          unformat_ip4_address, &v4address, &address_length))
6293         v4_address_set = 1;
6294       else if (unformat (i, "%U/%d",
6295                          unformat_ip6_address, &v6address, &address_length))
6296         v6_address_set = 1;
6297       else
6298         break;
6299     }
6300
6301   if (sw_if_index_set == 0)
6302     {
6303       errmsg ("missing interface name or sw_if_index");
6304       return -99;
6305     }
6306   if (v4_address_set && v6_address_set)
6307     {
6308       errmsg ("both v4 and v6 addresses set");
6309       return -99;
6310     }
6311   if (!v4_address_set && !v6_address_set && !del_all)
6312     {
6313       errmsg ("no addresses set");
6314       return -99;
6315     }
6316
6317   /* Construct the API message */
6318   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6319
6320   mp->sw_if_index = ntohl (sw_if_index);
6321   mp->is_add = is_add;
6322   mp->del_all = del_all;
6323   if (v6_address_set)
6324     {
6325       mp->is_ipv6 = 1;
6326       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6327     }
6328   else
6329     {
6330       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6331     }
6332   mp->address_length = address_length;
6333
6334   /* send it... */
6335   S (mp);
6336
6337   /* Wait for a reply, return good/bad news  */
6338   W (ret);
6339   return ret;
6340 }
6341
6342 static int
6343 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6344 {
6345   unformat_input_t *i = vam->input;
6346   vl_api_sw_interface_set_mpls_enable_t *mp;
6347   u32 sw_if_index;
6348   u8 sw_if_index_set = 0;
6349   u8 enable = 1;
6350   int ret;
6351
6352   /* Parse args required to build the message */
6353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6354     {
6355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6356         sw_if_index_set = 1;
6357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6358         sw_if_index_set = 1;
6359       else if (unformat (i, "disable"))
6360         enable = 0;
6361       else if (unformat (i, "dis"))
6362         enable = 0;
6363       else
6364         break;
6365     }
6366
6367   if (sw_if_index_set == 0)
6368     {
6369       errmsg ("missing interface name or sw_if_index");
6370       return -99;
6371     }
6372
6373   /* Construct the API message */
6374   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6375
6376   mp->sw_if_index = ntohl (sw_if_index);
6377   mp->enable = enable;
6378
6379   /* send it... */
6380   S (mp);
6381
6382   /* Wait for a reply... */
6383   W (ret);
6384   return ret;
6385 }
6386
6387 static int
6388 api_sw_interface_set_table (vat_main_t * vam)
6389 {
6390   unformat_input_t *i = vam->input;
6391   vl_api_sw_interface_set_table_t *mp;
6392   u32 sw_if_index, vrf_id = 0;
6393   u8 sw_if_index_set = 0;
6394   u8 is_ipv6 = 0;
6395   int ret;
6396
6397   /* Parse args required to build the message */
6398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6399     {
6400       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6401         sw_if_index_set = 1;
6402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6403         sw_if_index_set = 1;
6404       else if (unformat (i, "vrf %d", &vrf_id))
6405         ;
6406       else if (unformat (i, "ipv6"))
6407         is_ipv6 = 1;
6408       else
6409         break;
6410     }
6411
6412   if (sw_if_index_set == 0)
6413     {
6414       errmsg ("missing interface name or sw_if_index");
6415       return -99;
6416     }
6417
6418   /* Construct the API message */
6419   M (SW_INTERFACE_SET_TABLE, mp);
6420
6421   mp->sw_if_index = ntohl (sw_if_index);
6422   mp->is_ipv6 = is_ipv6;
6423   mp->vrf_id = ntohl (vrf_id);
6424
6425   /* send it... */
6426   S (mp);
6427
6428   /* Wait for a reply... */
6429   W (ret);
6430   return ret;
6431 }
6432
6433 static void vl_api_sw_interface_get_table_reply_t_handler
6434   (vl_api_sw_interface_get_table_reply_t * mp)
6435 {
6436   vat_main_t *vam = &vat_main;
6437
6438   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6439
6440   vam->retval = ntohl (mp->retval);
6441   vam->result_ready = 1;
6442
6443 }
6444
6445 static void vl_api_sw_interface_get_table_reply_t_handler_json
6446   (vl_api_sw_interface_get_table_reply_t * mp)
6447 {
6448   vat_main_t *vam = &vat_main;
6449   vat_json_node_t node;
6450
6451   vat_json_init_object (&node);
6452   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6453   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6454
6455   vat_json_print (vam->ofp, &node);
6456   vat_json_free (&node);
6457
6458   vam->retval = ntohl (mp->retval);
6459   vam->result_ready = 1;
6460 }
6461
6462 static int
6463 api_sw_interface_get_table (vat_main_t * vam)
6464 {
6465   unformat_input_t *i = vam->input;
6466   vl_api_sw_interface_get_table_t *mp;
6467   u32 sw_if_index;
6468   u8 sw_if_index_set = 0;
6469   u8 is_ipv6 = 0;
6470   int ret;
6471
6472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6473     {
6474       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6475         sw_if_index_set = 1;
6476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6477         sw_if_index_set = 1;
6478       else if (unformat (i, "ipv6"))
6479         is_ipv6 = 1;
6480       else
6481         break;
6482     }
6483
6484   if (sw_if_index_set == 0)
6485     {
6486       errmsg ("missing interface name or sw_if_index");
6487       return -99;
6488     }
6489
6490   M (SW_INTERFACE_GET_TABLE, mp);
6491   mp->sw_if_index = htonl (sw_if_index);
6492   mp->is_ipv6 = is_ipv6;
6493
6494   S (mp);
6495   W (ret);
6496   return ret;
6497 }
6498
6499 static int
6500 api_sw_interface_set_vpath (vat_main_t * vam)
6501 {
6502   unformat_input_t *i = vam->input;
6503   vl_api_sw_interface_set_vpath_t *mp;
6504   u32 sw_if_index = 0;
6505   u8 sw_if_index_set = 0;
6506   u8 is_enable = 0;
6507   int ret;
6508
6509   /* Parse args required to build the message */
6510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6511     {
6512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6513         sw_if_index_set = 1;
6514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6515         sw_if_index_set = 1;
6516       else if (unformat (i, "enable"))
6517         is_enable = 1;
6518       else if (unformat (i, "disable"))
6519         is_enable = 0;
6520       else
6521         break;
6522     }
6523
6524   if (sw_if_index_set == 0)
6525     {
6526       errmsg ("missing interface name or sw_if_index");
6527       return -99;
6528     }
6529
6530   /* Construct the API message */
6531   M (SW_INTERFACE_SET_VPATH, mp);
6532
6533   mp->sw_if_index = ntohl (sw_if_index);
6534   mp->enable = is_enable;
6535
6536   /* send it... */
6537   S (mp);
6538
6539   /* Wait for a reply... */
6540   W (ret);
6541   return ret;
6542 }
6543
6544 static int
6545 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6546 {
6547   unformat_input_t *i = vam->input;
6548   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6549   u32 sw_if_index = 0;
6550   u8 sw_if_index_set = 0;
6551   u8 is_enable = 1;
6552   u8 is_ipv6 = 0;
6553   int ret;
6554
6555   /* Parse args required to build the message */
6556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6557     {
6558       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "enable"))
6563         is_enable = 1;
6564       else if (unformat (i, "disable"))
6565         is_enable = 0;
6566       else if (unformat (i, "ip4"))
6567         is_ipv6 = 0;
6568       else if (unformat (i, "ip6"))
6569         is_ipv6 = 1;
6570       else
6571         break;
6572     }
6573
6574   if (sw_if_index_set == 0)
6575     {
6576       errmsg ("missing interface name or sw_if_index");
6577       return -99;
6578     }
6579
6580   /* Construct the API message */
6581   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6582
6583   mp->sw_if_index = ntohl (sw_if_index);
6584   mp->enable = is_enable;
6585   mp->is_ipv6 = is_ipv6;
6586
6587   /* send it... */
6588   S (mp);
6589
6590   /* Wait for a reply... */
6591   W (ret);
6592   return ret;
6593 }
6594
6595 static int
6596 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6597 {
6598   unformat_input_t *i = vam->input;
6599   vl_api_sw_interface_set_geneve_bypass_t *mp;
6600   u32 sw_if_index = 0;
6601   u8 sw_if_index_set = 0;
6602   u8 is_enable = 1;
6603   u8 is_ipv6 = 0;
6604   int ret;
6605
6606   /* Parse args required to build the message */
6607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6608     {
6609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6610         sw_if_index_set = 1;
6611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6612         sw_if_index_set = 1;
6613       else if (unformat (i, "enable"))
6614         is_enable = 1;
6615       else if (unformat (i, "disable"))
6616         is_enable = 0;
6617       else if (unformat (i, "ip4"))
6618         is_ipv6 = 0;
6619       else if (unformat (i, "ip6"))
6620         is_ipv6 = 1;
6621       else
6622         break;
6623     }
6624
6625   if (sw_if_index_set == 0)
6626     {
6627       errmsg ("missing interface name or sw_if_index");
6628       return -99;
6629     }
6630
6631   /* Construct the API message */
6632   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6633
6634   mp->sw_if_index = ntohl (sw_if_index);
6635   mp->enable = is_enable;
6636   mp->is_ipv6 = is_ipv6;
6637
6638   /* send it... */
6639   S (mp);
6640
6641   /* Wait for a reply... */
6642   W (ret);
6643   return ret;
6644 }
6645
6646 static int
6647 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6648 {
6649   unformat_input_t *i = vam->input;
6650   vl_api_sw_interface_set_l2_xconnect_t *mp;
6651   u32 rx_sw_if_index;
6652   u8 rx_sw_if_index_set = 0;
6653   u32 tx_sw_if_index;
6654   u8 tx_sw_if_index_set = 0;
6655   u8 enable = 1;
6656   int ret;
6657
6658   /* Parse args required to build the message */
6659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6660     {
6661       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6662         rx_sw_if_index_set = 1;
6663       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6664         tx_sw_if_index_set = 1;
6665       else if (unformat (i, "rx"))
6666         {
6667           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6668             {
6669               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6670                             &rx_sw_if_index))
6671                 rx_sw_if_index_set = 1;
6672             }
6673           else
6674             break;
6675         }
6676       else if (unformat (i, "tx"))
6677         {
6678           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6679             {
6680               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6681                             &tx_sw_if_index))
6682                 tx_sw_if_index_set = 1;
6683             }
6684           else
6685             break;
6686         }
6687       else if (unformat (i, "enable"))
6688         enable = 1;
6689       else if (unformat (i, "disable"))
6690         enable = 0;
6691       else
6692         break;
6693     }
6694
6695   if (rx_sw_if_index_set == 0)
6696     {
6697       errmsg ("missing rx interface name or rx_sw_if_index");
6698       return -99;
6699     }
6700
6701   if (enable && (tx_sw_if_index_set == 0))
6702     {
6703       errmsg ("missing tx interface name or tx_sw_if_index");
6704       return -99;
6705     }
6706
6707   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6708
6709   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6710   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6711   mp->enable = enable;
6712
6713   S (mp);
6714   W (ret);
6715   return ret;
6716 }
6717
6718 static int
6719 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6720 {
6721   unformat_input_t *i = vam->input;
6722   vl_api_sw_interface_set_l2_bridge_t *mp;
6723   vl_api_l2_port_type_t port_type;
6724   u32 rx_sw_if_index;
6725   u8 rx_sw_if_index_set = 0;
6726   u32 bd_id;
6727   u8 bd_id_set = 0;
6728   u32 shg = 0;
6729   u8 enable = 1;
6730   int ret;
6731
6732   port_type = L2_API_PORT_TYPE_NORMAL;
6733
6734   /* Parse args required to build the message */
6735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6736     {
6737       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6738         rx_sw_if_index_set = 1;
6739       else if (unformat (i, "bd_id %d", &bd_id))
6740         bd_id_set = 1;
6741       else
6742         if (unformat
6743             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6744         rx_sw_if_index_set = 1;
6745       else if (unformat (i, "shg %d", &shg))
6746         ;
6747       else if (unformat (i, "bvi"))
6748         port_type = L2_API_PORT_TYPE_BVI;
6749       else if (unformat (i, "uu-fwd"))
6750         port_type = L2_API_PORT_TYPE_UU_FWD;
6751       else if (unformat (i, "enable"))
6752         enable = 1;
6753       else if (unformat (i, "disable"))
6754         enable = 0;
6755       else
6756         break;
6757     }
6758
6759   if (rx_sw_if_index_set == 0)
6760     {
6761       errmsg ("missing rx interface name or sw_if_index");
6762       return -99;
6763     }
6764
6765   if (enable && (bd_id_set == 0))
6766     {
6767       errmsg ("missing bridge domain");
6768       return -99;
6769     }
6770
6771   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6772
6773   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6774   mp->bd_id = ntohl (bd_id);
6775   mp->shg = (u8) shg;
6776   mp->port_type = ntohl (port_type);
6777   mp->enable = enable;
6778
6779   S (mp);
6780   W (ret);
6781   return ret;
6782 }
6783
6784 static int
6785 api_bridge_domain_dump (vat_main_t * vam)
6786 {
6787   unformat_input_t *i = vam->input;
6788   vl_api_bridge_domain_dump_t *mp;
6789   vl_api_control_ping_t *mp_ping;
6790   u32 bd_id = ~0;
6791   int ret;
6792
6793   /* Parse args required to build the message */
6794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6795     {
6796       if (unformat (i, "bd_id %d", &bd_id))
6797         ;
6798       else
6799         break;
6800     }
6801
6802   M (BRIDGE_DOMAIN_DUMP, mp);
6803   mp->bd_id = ntohl (bd_id);
6804   S (mp);
6805
6806   /* Use a control ping for synchronization */
6807   MPING (CONTROL_PING, mp_ping);
6808   S (mp_ping);
6809
6810   W (ret);
6811   return ret;
6812 }
6813
6814 static int
6815 api_bridge_domain_add_del (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_bridge_domain_add_del_t *mp;
6819   u32 bd_id = ~0;
6820   u8 is_add = 1;
6821   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6822   u8 *bd_tag = NULL;
6823   u32 mac_age = 0;
6824   int ret;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "bd_id %d", &bd_id))
6830         ;
6831       else if (unformat (i, "flood %d", &flood))
6832         ;
6833       else if (unformat (i, "uu-flood %d", &uu_flood))
6834         ;
6835       else if (unformat (i, "forward %d", &forward))
6836         ;
6837       else if (unformat (i, "learn %d", &learn))
6838         ;
6839       else if (unformat (i, "arp-term %d", &arp_term))
6840         ;
6841       else if (unformat (i, "mac-age %d", &mac_age))
6842         ;
6843       else if (unformat (i, "bd-tag %s", &bd_tag))
6844         ;
6845       else if (unformat (i, "del"))
6846         {
6847           is_add = 0;
6848           flood = uu_flood = forward = learn = 0;
6849         }
6850       else
6851         break;
6852     }
6853
6854   if (bd_id == ~0)
6855     {
6856       errmsg ("missing bridge domain");
6857       ret = -99;
6858       goto done;
6859     }
6860
6861   if (mac_age > 255)
6862     {
6863       errmsg ("mac age must be less than 256 ");
6864       ret = -99;
6865       goto done;
6866     }
6867
6868   if ((bd_tag) && (vec_len (bd_tag) > 63))
6869     {
6870       errmsg ("bd-tag cannot be longer than 63");
6871       ret = -99;
6872       goto done;
6873     }
6874
6875   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6876
6877   mp->bd_id = ntohl (bd_id);
6878   mp->flood = flood;
6879   mp->uu_flood = uu_flood;
6880   mp->forward = forward;
6881   mp->learn = learn;
6882   mp->arp_term = arp_term;
6883   mp->is_add = is_add;
6884   mp->mac_age = (u8) mac_age;
6885   if (bd_tag)
6886     {
6887       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6888       mp->bd_tag[vec_len (bd_tag)] = 0;
6889     }
6890   S (mp);
6891   W (ret);
6892
6893 done:
6894   vec_free (bd_tag);
6895   return ret;
6896 }
6897
6898 static int
6899 api_l2fib_flush_bd (vat_main_t * vam)
6900 {
6901   unformat_input_t *i = vam->input;
6902   vl_api_l2fib_flush_bd_t *mp;
6903   u32 bd_id = ~0;
6904   int ret;
6905
6906   /* Parse args required to build the message */
6907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6908     {
6909       if (unformat (i, "bd_id %d", &bd_id));
6910       else
6911         break;
6912     }
6913
6914   if (bd_id == ~0)
6915     {
6916       errmsg ("missing bridge domain");
6917       return -99;
6918     }
6919
6920   M (L2FIB_FLUSH_BD, mp);
6921
6922   mp->bd_id = htonl (bd_id);
6923
6924   S (mp);
6925   W (ret);
6926   return ret;
6927 }
6928
6929 static int
6930 api_l2fib_flush_int (vat_main_t * vam)
6931 {
6932   unformat_input_t *i = vam->input;
6933   vl_api_l2fib_flush_int_t *mp;
6934   u32 sw_if_index = ~0;
6935   int ret;
6936
6937   /* Parse args required to build the message */
6938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939     {
6940       if (unformat (i, "sw_if_index %d", &sw_if_index));
6941       else
6942         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6943       else
6944         break;
6945     }
6946
6947   if (sw_if_index == ~0)
6948     {
6949       errmsg ("missing interface name or sw_if_index");
6950       return -99;
6951     }
6952
6953   M (L2FIB_FLUSH_INT, mp);
6954
6955   mp->sw_if_index = ntohl (sw_if_index);
6956
6957   S (mp);
6958   W (ret);
6959   return ret;
6960 }
6961
6962 static int
6963 api_l2fib_add_del (vat_main_t * vam)
6964 {
6965   unformat_input_t *i = vam->input;
6966   vl_api_l2fib_add_del_t *mp;
6967   f64 timeout;
6968   u8 mac[6] = { 0 };
6969   u8 mac_set = 0;
6970   u32 bd_id;
6971   u8 bd_id_set = 0;
6972   u32 sw_if_index = 0;
6973   u8 sw_if_index_set = 0;
6974   u8 is_add = 1;
6975   u8 static_mac = 0;
6976   u8 filter_mac = 0;
6977   u8 bvi_mac = 0;
6978   int count = 1;
6979   f64 before = 0;
6980   int j;
6981
6982   /* Parse args required to build the message */
6983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6984     {
6985       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6986         mac_set = 1;
6987       else if (unformat (i, "bd_id %d", &bd_id))
6988         bd_id_set = 1;
6989       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6990         sw_if_index_set = 1;
6991       else if (unformat (i, "sw_if"))
6992         {
6993           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6994             {
6995               if (unformat
6996                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6997                 sw_if_index_set = 1;
6998             }
6999           else
7000             break;
7001         }
7002       else if (unformat (i, "static"))
7003         static_mac = 1;
7004       else if (unformat (i, "filter"))
7005         {
7006           filter_mac = 1;
7007           static_mac = 1;
7008         }
7009       else if (unformat (i, "bvi"))
7010         {
7011           bvi_mac = 1;
7012           static_mac = 1;
7013         }
7014       else if (unformat (i, "del"))
7015         is_add = 0;
7016       else if (unformat (i, "count %d", &count))
7017         ;
7018       else
7019         break;
7020     }
7021
7022   if (mac_set == 0)
7023     {
7024       errmsg ("missing mac address");
7025       return -99;
7026     }
7027
7028   if (bd_id_set == 0)
7029     {
7030       errmsg ("missing bridge domain");
7031       return -99;
7032     }
7033
7034   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7035     {
7036       errmsg ("missing interface name or sw_if_index");
7037       return -99;
7038     }
7039
7040   if (count > 1)
7041     {
7042       /* Turn on async mode */
7043       vam->async_mode = 1;
7044       vam->async_errors = 0;
7045       before = vat_time_now (vam);
7046     }
7047
7048   for (j = 0; j < count; j++)
7049     {
7050       M (L2FIB_ADD_DEL, mp);
7051
7052       clib_memcpy (mp->mac, mac, 6);
7053       mp->bd_id = ntohl (bd_id);
7054       mp->is_add = is_add;
7055       mp->sw_if_index = ntohl (sw_if_index);
7056
7057       if (is_add)
7058         {
7059           mp->static_mac = static_mac;
7060           mp->filter_mac = filter_mac;
7061           mp->bvi_mac = bvi_mac;
7062         }
7063       increment_mac_address (mac);
7064       /* send it... */
7065       S (mp);
7066     }
7067
7068   if (count > 1)
7069     {
7070       vl_api_control_ping_t *mp_ping;
7071       f64 after;
7072
7073       /* Shut off async mode */
7074       vam->async_mode = 0;
7075
7076       MPING (CONTROL_PING, mp_ping);
7077       S (mp_ping);
7078
7079       timeout = vat_time_now (vam) + 1.0;
7080       while (vat_time_now (vam) < timeout)
7081         if (vam->result_ready == 1)
7082           goto out;
7083       vam->retval = -99;
7084
7085     out:
7086       if (vam->retval == -99)
7087         errmsg ("timeout");
7088
7089       if (vam->async_errors > 0)
7090         {
7091           errmsg ("%d asynchronous errors", vam->async_errors);
7092           vam->retval = -98;
7093         }
7094       vam->async_errors = 0;
7095       after = vat_time_now (vam);
7096
7097       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7098              count, after - before, count / (after - before));
7099     }
7100   else
7101     {
7102       int ret;
7103
7104       /* Wait for a reply... */
7105       W (ret);
7106       return ret;
7107     }
7108   /* Return the good/bad news */
7109   return (vam->retval);
7110 }
7111
7112 static int
7113 api_bridge_domain_set_mac_age (vat_main_t * vam)
7114 {
7115   unformat_input_t *i = vam->input;
7116   vl_api_bridge_domain_set_mac_age_t *mp;
7117   u32 bd_id = ~0;
7118   u32 mac_age = 0;
7119   int ret;
7120
7121   /* Parse args required to build the message */
7122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7123     {
7124       if (unformat (i, "bd_id %d", &bd_id));
7125       else if (unformat (i, "mac-age %d", &mac_age));
7126       else
7127         break;
7128     }
7129
7130   if (bd_id == ~0)
7131     {
7132       errmsg ("missing bridge domain");
7133       return -99;
7134     }
7135
7136   if (mac_age > 255)
7137     {
7138       errmsg ("mac age must be less than 256 ");
7139       return -99;
7140     }
7141
7142   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7143
7144   mp->bd_id = htonl (bd_id);
7145   mp->mac_age = (u8) mac_age;
7146
7147   S (mp);
7148   W (ret);
7149   return ret;
7150 }
7151
7152 static int
7153 api_l2_flags (vat_main_t * vam)
7154 {
7155   unformat_input_t *i = vam->input;
7156   vl_api_l2_flags_t *mp;
7157   u32 sw_if_index;
7158   u32 flags = 0;
7159   u8 sw_if_index_set = 0;
7160   u8 is_set = 0;
7161   int ret;
7162
7163   /* Parse args required to build the message */
7164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7165     {
7166       if (unformat (i, "sw_if_index %d", &sw_if_index))
7167         sw_if_index_set = 1;
7168       else if (unformat (i, "sw_if"))
7169         {
7170           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171             {
7172               if (unformat
7173                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7174                 sw_if_index_set = 1;
7175             }
7176           else
7177             break;
7178         }
7179       else if (unformat (i, "learn"))
7180         flags |= L2_LEARN;
7181       else if (unformat (i, "forward"))
7182         flags |= L2_FWD;
7183       else if (unformat (i, "flood"))
7184         flags |= L2_FLOOD;
7185       else if (unformat (i, "uu-flood"))
7186         flags |= L2_UU_FLOOD;
7187       else if (unformat (i, "arp-term"))
7188         flags |= L2_ARP_TERM;
7189       else if (unformat (i, "off"))
7190         is_set = 0;
7191       else if (unformat (i, "disable"))
7192         is_set = 0;
7193       else
7194         break;
7195     }
7196
7197   if (sw_if_index_set == 0)
7198     {
7199       errmsg ("missing interface name or sw_if_index");
7200       return -99;
7201     }
7202
7203   M (L2_FLAGS, mp);
7204
7205   mp->sw_if_index = ntohl (sw_if_index);
7206   mp->feature_bitmap = ntohl (flags);
7207   mp->is_set = is_set;
7208
7209   S (mp);
7210   W (ret);
7211   return ret;
7212 }
7213
7214 static int
7215 api_bridge_flags (vat_main_t * vam)
7216 {
7217   unformat_input_t *i = vam->input;
7218   vl_api_bridge_flags_t *mp;
7219   u32 bd_id;
7220   u8 bd_id_set = 0;
7221   u8 is_set = 1;
7222   bd_flags_t flags = 0;
7223   int ret;
7224
7225   /* Parse args required to build the message */
7226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7227     {
7228       if (unformat (i, "bd_id %d", &bd_id))
7229         bd_id_set = 1;
7230       else if (unformat (i, "learn"))
7231         flags |= BRIDGE_API_FLAG_LEARN;
7232       else if (unformat (i, "forward"))
7233         flags |= BRIDGE_API_FLAG_FWD;
7234       else if (unformat (i, "flood"))
7235         flags |= BRIDGE_API_FLAG_FLOOD;
7236       else if (unformat (i, "uu-flood"))
7237         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7238       else if (unformat (i, "arp-term"))
7239         flags |= BRIDGE_API_FLAG_ARP_TERM;
7240       else if (unformat (i, "off"))
7241         is_set = 0;
7242       else if (unformat (i, "disable"))
7243         is_set = 0;
7244       else
7245         break;
7246     }
7247
7248   if (bd_id_set == 0)
7249     {
7250       errmsg ("missing bridge domain");
7251       return -99;
7252     }
7253
7254   M (BRIDGE_FLAGS, mp);
7255
7256   mp->bd_id = ntohl (bd_id);
7257   mp->flags = ntohl (flags);
7258   mp->is_set = is_set;
7259
7260   S (mp);
7261   W (ret);
7262   return ret;
7263 }
7264
7265 static int
7266 api_bd_ip_mac_add_del (vat_main_t * vam)
7267 {
7268   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7269   vl_api_mac_address_t mac = { 0 };
7270   unformat_input_t *i = vam->input;
7271   vl_api_bd_ip_mac_add_del_t *mp;
7272   ip46_type_t type;
7273   u32 bd_id;
7274   u8 is_ipv6 = 0;
7275   u8 is_add = 1;
7276   u8 bd_id_set = 0;
7277   u8 ip_set = 0;
7278   u8 mac_set = 0;
7279   u8 macaddr[6];
7280   int ret;
7281
7282
7283   /* Parse args required to build the message */
7284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7285     {
7286       if (unformat (i, "bd_id %d", &bd_id))
7287         {
7288           bd_id_set++;
7289         }
7290       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7291         {
7292           ip_set++;
7293         }
7294       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7295         {
7296           mac_set++;
7297         }
7298       else if (unformat (i, "del"))
7299         is_add = 0;
7300       else
7301         break;
7302     }
7303
7304   if (bd_id_set == 0)
7305     {
7306       errmsg ("missing bridge domain");
7307       return -99;
7308     }
7309   else if (ip_set == 0)
7310     {
7311       errmsg ("missing IP address");
7312       return -99;
7313     }
7314   else if (mac_set == 0)
7315     {
7316       errmsg ("missing MAC address");
7317       return -99;
7318     }
7319
7320   M (BD_IP_MAC_ADD_DEL, mp);
7321
7322   mp->bd_id = ntohl (bd_id);
7323   mp->is_add = is_add;
7324
7325   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7326   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7327
7328   S (mp);
7329   W (ret);
7330   return ret;
7331 }
7332
7333 static int
7334 api_bd_ip_mac_flush (vat_main_t * vam)
7335 {
7336   unformat_input_t *i = vam->input;
7337   vl_api_bd_ip_mac_flush_t *mp;
7338   u32 bd_id;
7339   u8 bd_id_set = 0;
7340   int ret;
7341
7342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7343     {
7344       if (unformat (i, "bd_id %d", &bd_id))
7345         {
7346           bd_id_set++;
7347         }
7348       else
7349         break;
7350     }
7351
7352   if (bd_id_set == 0)
7353     {
7354       errmsg ("missing bridge domain");
7355       return -99;
7356     }
7357
7358   M (BD_IP_MAC_FLUSH, mp);
7359
7360   mp->bd_id = ntohl (bd_id);
7361
7362   S (mp);
7363   W (ret);
7364   return ret;
7365 }
7366
7367 static void vl_api_bd_ip_mac_details_t_handler
7368   (vl_api_bd_ip_mac_details_t * mp)
7369 {
7370   vat_main_t *vam = &vat_main;
7371   u8 *ip = 0;
7372
7373   if (!mp->is_ipv6)
7374     ip =
7375       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7376   else
7377     ip =
7378       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7379
7380   print (vam->ofp,
7381          "\n%-5d %-7s %-20U %-30s",
7382          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7383          format_ethernet_address, mp->mac_address, ip);
7384
7385   vec_free (ip);
7386 }
7387
7388 static void vl_api_bd_ip_mac_details_t_handler_json
7389   (vl_api_bd_ip_mac_details_t * mp)
7390 {
7391   vat_main_t *vam = &vat_main;
7392   vat_json_node_t *node = NULL;
7393
7394   if (VAT_JSON_ARRAY != vam->json_tree.type)
7395     {
7396       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7397       vat_json_init_array (&vam->json_tree);
7398     }
7399   node = vat_json_array_add (&vam->json_tree);
7400
7401   vat_json_init_object (node);
7402   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7403   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7404   vat_json_object_add_string_copy (node, "mac_address",
7405                                    format (0, "%U", format_ethernet_address,
7406                                            &mp->mac_address));
7407   u8 *ip = 0;
7408
7409   if (!mp->is_ipv6)
7410     ip =
7411       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7412   else
7413     ip =
7414       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7415   vat_json_object_add_string_copy (node, "ip_address", ip);
7416   vec_free (ip);
7417 }
7418
7419 static int
7420 api_bd_ip_mac_dump (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_bd_ip_mac_dump_t *mp;
7424   vl_api_control_ping_t *mp_ping;
7425   int ret;
7426   u32 bd_id;
7427   u8 bd_id_set = 0;
7428
7429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7430     {
7431       if (unformat (i, "bd_id %d", &bd_id))
7432         {
7433           bd_id_set++;
7434         }
7435       else
7436         break;
7437     }
7438
7439   print (vam->ofp,
7440          "\n%-5s %-7s %-20s %-30s",
7441          "bd_id", "is_ipv6", "mac_address", "ip_address");
7442
7443   /* Dump Bridge Domain Ip to Mac entries */
7444   M (BD_IP_MAC_DUMP, mp);
7445
7446   if (bd_id_set)
7447     mp->bd_id = htonl (bd_id);
7448   else
7449     mp->bd_id = ~0;
7450
7451   S (mp);
7452
7453   /* Use a control ping for synchronization */
7454   MPING (CONTROL_PING, mp_ping);
7455   S (mp_ping);
7456
7457   W (ret);
7458   return ret;
7459 }
7460
7461 static int
7462 api_tap_create_v2 (vat_main_t * vam)
7463 {
7464   unformat_input_t *i = vam->input;
7465   vl_api_tap_create_v2_t *mp;
7466   u8 mac_address[6];
7467   u8 random_mac = 1;
7468   u32 id = ~0;
7469   u8 *host_if_name = 0;
7470   u8 *host_ns = 0;
7471   u8 host_mac_addr[6];
7472   u8 host_mac_addr_set = 0;
7473   u8 *host_bridge = 0;
7474   ip4_address_t host_ip4_addr;
7475   ip4_address_t host_ip4_gw;
7476   u8 host_ip4_gw_set = 0;
7477   u32 host_ip4_prefix_len = 0;
7478   ip6_address_t host_ip6_addr;
7479   ip6_address_t host_ip6_gw;
7480   u8 host_ip6_gw_set = 0;
7481   u32 host_ip6_prefix_len = 0;
7482   int ret;
7483   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7484
7485   clib_memset (mac_address, 0, sizeof (mac_address));
7486
7487   /* Parse args required to build the message */
7488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7489     {
7490       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7491         {
7492           random_mac = 0;
7493         }
7494       else if (unformat (i, "id %u", &id))
7495         ;
7496       else if (unformat (i, "host-if-name %s", &host_if_name))
7497         ;
7498       else if (unformat (i, "host-ns %s", &host_ns))
7499         ;
7500       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7501                          host_mac_addr))
7502         host_mac_addr_set = 1;
7503       else if (unformat (i, "host-bridge %s", &host_bridge))
7504         ;
7505       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7506                          &host_ip4_addr, &host_ip4_prefix_len))
7507         ;
7508       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7509                          &host_ip6_addr, &host_ip6_prefix_len))
7510         ;
7511       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7512                          &host_ip4_gw))
7513         host_ip4_gw_set = 1;
7514       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7515                          &host_ip6_gw))
7516         host_ip6_gw_set = 1;
7517       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7518         ;
7519       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7520         ;
7521       else
7522         break;
7523     }
7524
7525   if (vec_len (host_if_name) > 63)
7526     {
7527       errmsg ("tap name too long. ");
7528       return -99;
7529     }
7530   if (vec_len (host_ns) > 63)
7531     {
7532       errmsg ("host name space too long. ");
7533       return -99;
7534     }
7535   if (vec_len (host_bridge) > 63)
7536     {
7537       errmsg ("host bridge name too long. ");
7538       return -99;
7539     }
7540   if (host_ip4_prefix_len > 32)
7541     {
7542       errmsg ("host ip4 prefix length not valid. ");
7543       return -99;
7544     }
7545   if (host_ip6_prefix_len > 128)
7546     {
7547       errmsg ("host ip6 prefix length not valid. ");
7548       return -99;
7549     }
7550   if (!is_pow2 (rx_ring_sz))
7551     {
7552       errmsg ("rx ring size must be power of 2. ");
7553       return -99;
7554     }
7555   if (rx_ring_sz > 32768)
7556     {
7557       errmsg ("rx ring size must be 32768 or lower. ");
7558       return -99;
7559     }
7560   if (!is_pow2 (tx_ring_sz))
7561     {
7562       errmsg ("tx ring size must be power of 2. ");
7563       return -99;
7564     }
7565   if (tx_ring_sz > 32768)
7566     {
7567       errmsg ("tx ring size must be 32768 or lower. ");
7568       return -99;
7569     }
7570
7571   /* Construct the API message */
7572   M (TAP_CREATE_V2, mp);
7573
7574   mp->use_random_mac = random_mac;
7575
7576   mp->id = ntohl (id);
7577   mp->host_namespace_set = host_ns != 0;
7578   mp->host_bridge_set = host_bridge != 0;
7579   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7580   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7581   mp->rx_ring_sz = ntohs (rx_ring_sz);
7582   mp->tx_ring_sz = ntohs (tx_ring_sz);
7583
7584   if (random_mac == 0)
7585     clib_memcpy (mp->mac_address, mac_address, 6);
7586   if (host_mac_addr_set)
7587     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7588   if (host_if_name)
7589     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7590   if (host_ns)
7591     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7592   if (host_bridge)
7593     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7594   if (host_ip4_prefix_len)
7595     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7596   if (host_ip6_prefix_len)
7597     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7598   if (host_ip4_gw_set)
7599     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7600   if (host_ip6_gw_set)
7601     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7602
7603   vec_free (host_ns);
7604   vec_free (host_if_name);
7605   vec_free (host_bridge);
7606
7607   /* send it... */
7608   S (mp);
7609
7610   /* Wait for a reply... */
7611   W (ret);
7612   return ret;
7613 }
7614
7615 static int
7616 api_tap_delete_v2 (vat_main_t * vam)
7617 {
7618   unformat_input_t *i = vam->input;
7619   vl_api_tap_delete_v2_t *mp;
7620   u32 sw_if_index = ~0;
7621   u8 sw_if_index_set = 0;
7622   int ret;
7623
7624   /* Parse args required to build the message */
7625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7626     {
7627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7628         sw_if_index_set = 1;
7629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7630         sw_if_index_set = 1;
7631       else
7632         break;
7633     }
7634
7635   if (sw_if_index_set == 0)
7636     {
7637       errmsg ("missing vpp interface name. ");
7638       return -99;
7639     }
7640
7641   /* Construct the API message */
7642   M (TAP_DELETE_V2, mp);
7643
7644   mp->sw_if_index = ntohl (sw_if_index);
7645
7646   /* send it... */
7647   S (mp);
7648
7649   /* Wait for a reply... */
7650   W (ret);
7651   return ret;
7652 }
7653
7654 uword
7655 unformat_pci_addr (unformat_input_t * input, va_list * args)
7656 {
7657   struct pci_addr_t
7658   {
7659     u16 domain;
7660     u8 bus;
7661     u8 slot:5;
7662     u8 function:3;
7663   } *addr;
7664   addr = va_arg (*args, struct pci_addr_t *);
7665   u32 x[4];
7666
7667   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7668     return 0;
7669
7670   addr->domain = x[0];
7671   addr->bus = x[1];
7672   addr->slot = x[2];
7673   addr->function = x[3];
7674
7675   return 1;
7676 }
7677
7678 static int
7679 api_virtio_pci_create (vat_main_t * vam)
7680 {
7681   unformat_input_t *i = vam->input;
7682   vl_api_virtio_pci_create_t *mp;
7683   u8 mac_address[6];
7684   u8 random_mac = 1;
7685   u32 pci_addr = 0;
7686   u64 features = (u64) ~ (0ULL);
7687   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7688   int ret;
7689
7690   clib_memset (mac_address, 0, sizeof (mac_address));
7691
7692   /* Parse args required to build the message */
7693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7694     {
7695       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7696         {
7697           random_mac = 0;
7698         }
7699       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7700         ;
7701       else if (unformat (i, "features 0x%llx", &features))
7702         ;
7703       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7704         ;
7705       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7706         ;
7707       else
7708         break;
7709     }
7710
7711   if (pci_addr == 0)
7712     {
7713       errmsg ("pci address must be non zero. ");
7714       return -99;
7715     }
7716   if (!is_pow2 (rx_ring_sz))
7717     {
7718       errmsg ("rx ring size must be power of 2. ");
7719       return -99;
7720     }
7721   if (rx_ring_sz > 32768)
7722     {
7723       errmsg ("rx ring size must be 32768 or lower. ");
7724       return -99;
7725     }
7726   if (!is_pow2 (tx_ring_sz))
7727     {
7728       errmsg ("tx ring size must be power of 2. ");
7729       return -99;
7730     }
7731   if (tx_ring_sz > 32768)
7732     {
7733       errmsg ("tx ring size must be 32768 or lower. ");
7734       return -99;
7735     }
7736
7737   /* Construct the API message */
7738   M (VIRTIO_PCI_CREATE, mp);
7739
7740   mp->use_random_mac = random_mac;
7741
7742   mp->pci_addr = htonl (pci_addr);
7743   mp->features = clib_host_to_net_u64 (features);
7744
7745   if (random_mac == 0)
7746     clib_memcpy (mp->mac_address, mac_address, 6);
7747
7748   /* send it... */
7749   S (mp);
7750
7751   /* Wait for a reply... */
7752   W (ret);
7753   return ret;
7754 }
7755
7756 static int
7757 api_virtio_pci_delete (vat_main_t * vam)
7758 {
7759   unformat_input_t *i = vam->input;
7760   vl_api_virtio_pci_delete_t *mp;
7761   u32 sw_if_index = ~0;
7762   u8 sw_if_index_set = 0;
7763   int ret;
7764
7765   /* Parse args required to build the message */
7766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7767     {
7768       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7769         sw_if_index_set = 1;
7770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7771         sw_if_index_set = 1;
7772       else
7773         break;
7774     }
7775
7776   if (sw_if_index_set == 0)
7777     {
7778       errmsg ("missing vpp interface name. ");
7779       return -99;
7780     }
7781
7782   /* Construct the API message */
7783   M (VIRTIO_PCI_DELETE, mp);
7784
7785   mp->sw_if_index = htonl (sw_if_index);
7786
7787   /* send it... */
7788   S (mp);
7789
7790   /* Wait for a reply... */
7791   W (ret);
7792   return ret;
7793 }
7794
7795 static int
7796 api_bond_create (vat_main_t * vam)
7797 {
7798   unformat_input_t *i = vam->input;
7799   vl_api_bond_create_t *mp;
7800   u8 mac_address[6];
7801   u8 custom_mac = 0;
7802   int ret;
7803   u8 mode;
7804   u8 lb;
7805   u8 mode_is_set = 0;
7806   u32 id = ~0;
7807
7808   clib_memset (mac_address, 0, sizeof (mac_address));
7809   lb = BOND_LB_L2;
7810
7811   /* Parse args required to build the message */
7812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7813     {
7814       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7815         mode_is_set = 1;
7816       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7817                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7818         ;
7819       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7820                          mac_address))
7821         custom_mac = 1;
7822       else if (unformat (i, "id %u", &id))
7823         ;
7824       else
7825         break;
7826     }
7827
7828   if (mode_is_set == 0)
7829     {
7830       errmsg ("Missing bond mode. ");
7831       return -99;
7832     }
7833
7834   /* Construct the API message */
7835   M (BOND_CREATE, mp);
7836
7837   mp->use_custom_mac = custom_mac;
7838
7839   mp->mode = mode;
7840   mp->lb = lb;
7841   mp->id = htonl (id);
7842
7843   if (custom_mac)
7844     clib_memcpy (mp->mac_address, mac_address, 6);
7845
7846   /* send it... */
7847   S (mp);
7848
7849   /* Wait for a reply... */
7850   W (ret);
7851   return ret;
7852 }
7853
7854 static int
7855 api_bond_delete (vat_main_t * vam)
7856 {
7857   unformat_input_t *i = vam->input;
7858   vl_api_bond_delete_t *mp;
7859   u32 sw_if_index = ~0;
7860   u8 sw_if_index_set = 0;
7861   int ret;
7862
7863   /* Parse args required to build the message */
7864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7865     {
7866       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7867         sw_if_index_set = 1;
7868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7869         sw_if_index_set = 1;
7870       else
7871         break;
7872     }
7873
7874   if (sw_if_index_set == 0)
7875     {
7876       errmsg ("missing vpp interface name. ");
7877       return -99;
7878     }
7879
7880   /* Construct the API message */
7881   M (BOND_DELETE, mp);
7882
7883   mp->sw_if_index = ntohl (sw_if_index);
7884
7885   /* send it... */
7886   S (mp);
7887
7888   /* Wait for a reply... */
7889   W (ret);
7890   return ret;
7891 }
7892
7893 static int
7894 api_bond_enslave (vat_main_t * vam)
7895 {
7896   unformat_input_t *i = vam->input;
7897   vl_api_bond_enslave_t *mp;
7898   u32 bond_sw_if_index;
7899   int ret;
7900   u8 is_passive;
7901   u8 is_long_timeout;
7902   u32 bond_sw_if_index_is_set = 0;
7903   u32 sw_if_index;
7904   u8 sw_if_index_is_set = 0;
7905
7906   /* Parse args required to build the message */
7907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7908     {
7909       if (unformat (i, "sw_if_index %d", &sw_if_index))
7910         sw_if_index_is_set = 1;
7911       else if (unformat (i, "bond %u", &bond_sw_if_index))
7912         bond_sw_if_index_is_set = 1;
7913       else if (unformat (i, "passive %d", &is_passive))
7914         ;
7915       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7916         ;
7917       else
7918         break;
7919     }
7920
7921   if (bond_sw_if_index_is_set == 0)
7922     {
7923       errmsg ("Missing bond sw_if_index. ");
7924       return -99;
7925     }
7926   if (sw_if_index_is_set == 0)
7927     {
7928       errmsg ("Missing slave sw_if_index. ");
7929       return -99;
7930     }
7931
7932   /* Construct the API message */
7933   M (BOND_ENSLAVE, mp);
7934
7935   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7936   mp->sw_if_index = ntohl (sw_if_index);
7937   mp->is_long_timeout = is_long_timeout;
7938   mp->is_passive = is_passive;
7939
7940   /* send it... */
7941   S (mp);
7942
7943   /* Wait for a reply... */
7944   W (ret);
7945   return ret;
7946 }
7947
7948 static int
7949 api_bond_detach_slave (vat_main_t * vam)
7950 {
7951   unformat_input_t *i = vam->input;
7952   vl_api_bond_detach_slave_t *mp;
7953   u32 sw_if_index = ~0;
7954   u8 sw_if_index_set = 0;
7955   int ret;
7956
7957   /* Parse args required to build the message */
7958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7959     {
7960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7961         sw_if_index_set = 1;
7962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7963         sw_if_index_set = 1;
7964       else
7965         break;
7966     }
7967
7968   if (sw_if_index_set == 0)
7969     {
7970       errmsg ("missing vpp interface name. ");
7971       return -99;
7972     }
7973
7974   /* Construct the API message */
7975   M (BOND_DETACH_SLAVE, mp);
7976
7977   mp->sw_if_index = ntohl (sw_if_index);
7978
7979   /* send it... */
7980   S (mp);
7981
7982   /* Wait for a reply... */
7983   W (ret);
7984   return ret;
7985 }
7986
7987 static int
7988 api_ip_table_add_del (vat_main_t * vam)
7989 {
7990   unformat_input_t *i = vam->input;
7991   vl_api_ip_table_add_del_t *mp;
7992   u32 table_id = ~0;
7993   u8 is_ipv6 = 0;
7994   u8 is_add = 1;
7995   int ret = 0;
7996
7997   /* Parse args required to build the message */
7998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7999     {
8000       if (unformat (i, "ipv6"))
8001         is_ipv6 = 1;
8002       else if (unformat (i, "del"))
8003         is_add = 0;
8004       else if (unformat (i, "add"))
8005         is_add = 1;
8006       else if (unformat (i, "table %d", &table_id))
8007         ;
8008       else
8009         {
8010           clib_warning ("parse error '%U'", format_unformat_error, i);
8011           return -99;
8012         }
8013     }
8014
8015   if (~0 == table_id)
8016     {
8017       errmsg ("missing table-ID");
8018       return -99;
8019     }
8020
8021   /* Construct the API message */
8022   M (IP_TABLE_ADD_DEL, mp);
8023
8024   mp->table_id = ntohl (table_id);
8025   mp->is_ipv6 = is_ipv6;
8026   mp->is_add = is_add;
8027
8028   /* send it... */
8029   S (mp);
8030
8031   /* Wait for a reply... */
8032   W (ret);
8033
8034   return ret;
8035 }
8036
8037 static int
8038 api_ip_add_del_route (vat_main_t * vam)
8039 {
8040   unformat_input_t *i = vam->input;
8041   vl_api_ip_add_del_route_t *mp;
8042   u32 sw_if_index = ~0, vrf_id = 0;
8043   u8 is_ipv6 = 0;
8044   u8 is_local = 0, is_drop = 0;
8045   u8 is_unreach = 0, is_prohibit = 0;
8046   u8 is_add = 1;
8047   u32 next_hop_weight = 1;
8048   u8 is_multipath = 0;
8049   u8 address_set = 0;
8050   u8 address_length_set = 0;
8051   u32 next_hop_table_id = 0;
8052   u32 resolve_attempts = 0;
8053   u32 dst_address_length = 0;
8054   u8 next_hop_set = 0;
8055   ip4_address_t v4_dst_address, v4_next_hop_address;
8056   ip6_address_t v6_dst_address, v6_next_hop_address;
8057   int count = 1;
8058   int j;
8059   f64 before = 0;
8060   u32 random_add_del = 0;
8061   u32 *random_vector = 0;
8062   uword *random_hash;
8063   u32 random_seed = 0xdeaddabe;
8064   u32 classify_table_index = ~0;
8065   u8 is_classify = 0;
8066   u8 resolve_host = 0, resolve_attached = 0;
8067   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8068   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8069   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8070
8071   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8072   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8073   /* Parse args required to build the message */
8074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8077         ;
8078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8079         ;
8080       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8081         {
8082           address_set = 1;
8083           is_ipv6 = 0;
8084         }
8085       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8086         {
8087           address_set = 1;
8088           is_ipv6 = 1;
8089         }
8090       else if (unformat (i, "/%d", &dst_address_length))
8091         {
8092           address_length_set = 1;
8093         }
8094
8095       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8096                                          &v4_next_hop_address))
8097         {
8098           next_hop_set = 1;
8099         }
8100       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8101                                          &v6_next_hop_address))
8102         {
8103           next_hop_set = 1;
8104         }
8105       else
8106         if (unformat
8107             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8108         {
8109           next_hop_set = 1;
8110         }
8111       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8112         {
8113           next_hop_set = 1;
8114         }
8115       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8116         ;
8117       else if (unformat (i, "weight %d", &next_hop_weight))
8118         ;
8119       else if (unformat (i, "drop"))
8120         {
8121           is_drop = 1;
8122         }
8123       else if (unformat (i, "null-send-unreach"))
8124         {
8125           is_unreach = 1;
8126         }
8127       else if (unformat (i, "null-send-prohibit"))
8128         {
8129           is_prohibit = 1;
8130         }
8131       else if (unformat (i, "local"))
8132         {
8133           is_local = 1;
8134         }
8135       else if (unformat (i, "classify %d", &classify_table_index))
8136         {
8137           is_classify = 1;
8138         }
8139       else if (unformat (i, "del"))
8140         is_add = 0;
8141       else if (unformat (i, "add"))
8142         is_add = 1;
8143       else if (unformat (i, "resolve-via-host"))
8144         resolve_host = 1;
8145       else if (unformat (i, "resolve-via-attached"))
8146         resolve_attached = 1;
8147       else if (unformat (i, "multipath"))
8148         is_multipath = 1;
8149       else if (unformat (i, "vrf %d", &vrf_id))
8150         ;
8151       else if (unformat (i, "count %d", &count))
8152         ;
8153       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8154         ;
8155       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8156         ;
8157       else if (unformat (i, "out-label %d", &next_hop_out_label))
8158         {
8159           vl_api_fib_mpls_label_t fib_label = {
8160             .label = ntohl (next_hop_out_label),
8161             .ttl = 64,
8162             .exp = 0,
8163           };
8164           vec_add1 (next_hop_out_label_stack, fib_label);
8165         }
8166       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8167         ;
8168       else if (unformat (i, "random"))
8169         random_add_del = 1;
8170       else if (unformat (i, "seed %d", &random_seed))
8171         ;
8172       else
8173         {
8174           clib_warning ("parse error '%U'", format_unformat_error, i);
8175           return -99;
8176         }
8177     }
8178
8179   if (!next_hop_set && !is_drop && !is_local &&
8180       !is_classify && !is_unreach && !is_prohibit &&
8181       MPLS_LABEL_INVALID == next_hop_via_label)
8182     {
8183       errmsg
8184         ("next hop / local / drop / unreach / prohibit / classify not set");
8185       return -99;
8186     }
8187
8188   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8189     {
8190       errmsg ("next hop and next-hop via label set");
8191       return -99;
8192     }
8193   if (address_set == 0)
8194     {
8195       errmsg ("missing addresses");
8196       return -99;
8197     }
8198
8199   if (address_length_set == 0)
8200     {
8201       errmsg ("missing address length");
8202       return -99;
8203     }
8204
8205   /* Generate a pile of unique, random routes */
8206   if (random_add_del)
8207     {
8208       u32 this_random_address;
8209       random_hash = hash_create (count, sizeof (uword));
8210
8211       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8212       for (j = 0; j <= count; j++)
8213         {
8214           do
8215             {
8216               this_random_address = random_u32 (&random_seed);
8217               this_random_address =
8218                 clib_host_to_net_u32 (this_random_address);
8219             }
8220           while (hash_get (random_hash, this_random_address));
8221           vec_add1 (random_vector, this_random_address);
8222           hash_set (random_hash, this_random_address, 1);
8223         }
8224       hash_free (random_hash);
8225       v4_dst_address.as_u32 = random_vector[0];
8226     }
8227
8228   if (count > 1)
8229     {
8230       /* Turn on async mode */
8231       vam->async_mode = 1;
8232       vam->async_errors = 0;
8233       before = vat_time_now (vam);
8234     }
8235
8236   for (j = 0; j < count; j++)
8237     {
8238       /* Construct the API message */
8239       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8240           vec_len (next_hop_out_label_stack));
8241
8242       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8243       mp->table_id = ntohl (vrf_id);
8244
8245       mp->is_add = is_add;
8246       mp->is_drop = is_drop;
8247       mp->is_unreach = is_unreach;
8248       mp->is_prohibit = is_prohibit;
8249       mp->is_ipv6 = is_ipv6;
8250       mp->is_local = is_local;
8251       mp->is_classify = is_classify;
8252       mp->is_multipath = is_multipath;
8253       mp->is_resolve_host = resolve_host;
8254       mp->is_resolve_attached = resolve_attached;
8255       mp->next_hop_weight = next_hop_weight;
8256       mp->next_hop_preference = 0;
8257       mp->dst_address_length = dst_address_length;
8258       mp->next_hop_table_id = ntohl (next_hop_table_id);
8259       mp->classify_table_index = ntohl (classify_table_index);
8260       mp->next_hop_via_label = ntohl (next_hop_via_label);
8261       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8262       if (0 != mp->next_hop_n_out_labels)
8263         {
8264           memcpy (mp->next_hop_out_label_stack,
8265                   next_hop_out_label_stack,
8266                   (vec_len (next_hop_out_label_stack) *
8267                    sizeof (vl_api_fib_mpls_label_t)));
8268           vec_free (next_hop_out_label_stack);
8269         }
8270
8271       if (is_ipv6)
8272         {
8273           clib_memcpy (mp->dst_address, &v6_dst_address,
8274                        sizeof (v6_dst_address));
8275           if (next_hop_set)
8276             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8277                          sizeof (v6_next_hop_address));
8278           increment_v6_address (&v6_dst_address);
8279         }
8280       else
8281         {
8282           clib_memcpy (mp->dst_address, &v4_dst_address,
8283                        sizeof (v4_dst_address));
8284           if (next_hop_set)
8285             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8286                          sizeof (v4_next_hop_address));
8287           if (random_add_del)
8288             v4_dst_address.as_u32 = random_vector[j + 1];
8289           else
8290             increment_v4_address (&v4_dst_address);
8291         }
8292       /* send it... */
8293       S (mp);
8294       /* If we receive SIGTERM, stop now... */
8295       if (vam->do_exit)
8296         break;
8297     }
8298
8299   /* When testing multiple add/del ops, use a control-ping to sync */
8300   if (count > 1)
8301     {
8302       vl_api_control_ping_t *mp_ping;
8303       f64 after;
8304       f64 timeout;
8305
8306       /* Shut off async mode */
8307       vam->async_mode = 0;
8308
8309       MPING (CONTROL_PING, mp_ping);
8310       S (mp_ping);
8311
8312       timeout = vat_time_now (vam) + 1.0;
8313       while (vat_time_now (vam) < timeout)
8314         if (vam->result_ready == 1)
8315           goto out;
8316       vam->retval = -99;
8317
8318     out:
8319       if (vam->retval == -99)
8320         errmsg ("timeout");
8321
8322       if (vam->async_errors > 0)
8323         {
8324           errmsg ("%d asynchronous errors", vam->async_errors);
8325           vam->retval = -98;
8326         }
8327       vam->async_errors = 0;
8328       after = vat_time_now (vam);
8329
8330       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8331       if (j > 0)
8332         count = j;
8333
8334       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8335              count, after - before, count / (after - before));
8336     }
8337   else
8338     {
8339       int ret;
8340
8341       /* Wait for a reply... */
8342       W (ret);
8343       return ret;
8344     }
8345
8346   /* Return the good/bad news */
8347   return (vam->retval);
8348 }
8349
8350 static int
8351 api_ip_mroute_add_del (vat_main_t * vam)
8352 {
8353   unformat_input_t *i = vam->input;
8354   vl_api_ip_mroute_add_del_t *mp;
8355   u32 sw_if_index = ~0, vrf_id = 0;
8356   u8 is_ipv6 = 0;
8357   u8 is_local = 0;
8358   u8 is_add = 1;
8359   u8 address_set = 0;
8360   u32 grp_address_length = 0;
8361   ip4_address_t v4_grp_address, v4_src_address;
8362   ip6_address_t v6_grp_address, v6_src_address;
8363   mfib_itf_flags_t iflags = 0;
8364   mfib_entry_flags_t eflags = 0;
8365   int ret;
8366
8367   /* Parse args required to build the message */
8368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8369     {
8370       if (unformat (i, "sw_if_index %d", &sw_if_index))
8371         ;
8372       else if (unformat (i, "%U %U",
8373                          unformat_ip4_address, &v4_src_address,
8374                          unformat_ip4_address, &v4_grp_address))
8375         {
8376           grp_address_length = 64;
8377           address_set = 1;
8378           is_ipv6 = 0;
8379         }
8380       else if (unformat (i, "%U %U",
8381                          unformat_ip6_address, &v6_src_address,
8382                          unformat_ip6_address, &v6_grp_address))
8383         {
8384           grp_address_length = 256;
8385           address_set = 1;
8386           is_ipv6 = 1;
8387         }
8388       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8389         {
8390           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8391           grp_address_length = 32;
8392           address_set = 1;
8393           is_ipv6 = 0;
8394         }
8395       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8396         {
8397           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8398           grp_address_length = 128;
8399           address_set = 1;
8400           is_ipv6 = 1;
8401         }
8402       else if (unformat (i, "/%d", &grp_address_length))
8403         ;
8404       else if (unformat (i, "local"))
8405         {
8406           is_local = 1;
8407         }
8408       else if (unformat (i, "del"))
8409         is_add = 0;
8410       else if (unformat (i, "add"))
8411         is_add = 1;
8412       else if (unformat (i, "vrf %d", &vrf_id))
8413         ;
8414       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8415         ;
8416       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8417         ;
8418       else
8419         {
8420           clib_warning ("parse error '%U'", format_unformat_error, i);
8421           return -99;
8422         }
8423     }
8424
8425   if (address_set == 0)
8426     {
8427       errmsg ("missing addresses\n");
8428       return -99;
8429     }
8430
8431   /* Construct the API message */
8432   M (IP_MROUTE_ADD_DEL, mp);
8433
8434   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8435   mp->table_id = ntohl (vrf_id);
8436
8437   mp->is_add = is_add;
8438   mp->is_ipv6 = is_ipv6;
8439   mp->is_local = is_local;
8440   mp->itf_flags = ntohl (iflags);
8441   mp->entry_flags = ntohl (eflags);
8442   mp->grp_address_length = grp_address_length;
8443   mp->grp_address_length = ntohs (mp->grp_address_length);
8444
8445   if (is_ipv6)
8446     {
8447       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8448       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8449     }
8450   else
8451     {
8452       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8453       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8454
8455     }
8456
8457   /* send it... */
8458   S (mp);
8459   /* Wait for a reply... */
8460   W (ret);
8461   return ret;
8462 }
8463
8464 static int
8465 api_mpls_table_add_del (vat_main_t * vam)
8466 {
8467   unformat_input_t *i = vam->input;
8468   vl_api_mpls_table_add_del_t *mp;
8469   u32 table_id = ~0;
8470   u8 is_add = 1;
8471   int ret = 0;
8472
8473   /* Parse args required to build the message */
8474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8475     {
8476       if (unformat (i, "table %d", &table_id))
8477         ;
8478       else if (unformat (i, "del"))
8479         is_add = 0;
8480       else if (unformat (i, "add"))
8481         is_add = 1;
8482       else
8483         {
8484           clib_warning ("parse error '%U'", format_unformat_error, i);
8485           return -99;
8486         }
8487     }
8488
8489   if (~0 == table_id)
8490     {
8491       errmsg ("missing table-ID");
8492       return -99;
8493     }
8494
8495   /* Construct the API message */
8496   M (MPLS_TABLE_ADD_DEL, mp);
8497
8498   mp->mt_table_id = ntohl (table_id);
8499   mp->mt_is_add = is_add;
8500
8501   /* send it... */
8502   S (mp);
8503
8504   /* Wait for a reply... */
8505   W (ret);
8506
8507   return ret;
8508 }
8509
8510 static int
8511 api_mpls_route_add_del (vat_main_t * vam)
8512 {
8513   unformat_input_t *i = vam->input;
8514   vl_api_mpls_route_add_del_t *mp;
8515   u32 sw_if_index = ~0, table_id = 0;
8516   u8 is_add = 1;
8517   u32 next_hop_weight = 1;
8518   u8 is_multipath = 0;
8519   u32 next_hop_table_id = 0;
8520   u8 next_hop_set = 0;
8521   ip4_address_t v4_next_hop_address = {
8522     .as_u32 = 0,
8523   };
8524   ip6_address_t v6_next_hop_address = { {0} };
8525   int count = 1;
8526   int j;
8527   f64 before = 0;
8528   u32 classify_table_index = ~0;
8529   u8 is_classify = 0;
8530   u8 resolve_host = 0, resolve_attached = 0;
8531   u8 is_interface_rx = 0;
8532   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8533   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8534   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8535   mpls_label_t local_label = MPLS_LABEL_INVALID;
8536   u8 is_eos = 0;
8537   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8538
8539   /* Parse args required to build the message */
8540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8541     {
8542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8543         ;
8544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8545         ;
8546       else if (unformat (i, "%d", &local_label))
8547         ;
8548       else if (unformat (i, "eos"))
8549         is_eos = 1;
8550       else if (unformat (i, "non-eos"))
8551         is_eos = 0;
8552       else if (unformat (i, "via %U", unformat_ip4_address,
8553                          &v4_next_hop_address))
8554         {
8555           next_hop_set = 1;
8556           next_hop_proto = DPO_PROTO_IP4;
8557         }
8558       else if (unformat (i, "via %U", unformat_ip6_address,
8559                          &v6_next_hop_address))
8560         {
8561           next_hop_set = 1;
8562           next_hop_proto = DPO_PROTO_IP6;
8563         }
8564       else if (unformat (i, "weight %d", &next_hop_weight))
8565         ;
8566       else if (unformat (i, "classify %d", &classify_table_index))
8567         {
8568           is_classify = 1;
8569         }
8570       else if (unformat (i, "del"))
8571         is_add = 0;
8572       else if (unformat (i, "add"))
8573         is_add = 1;
8574       else if (unformat (i, "resolve-via-host"))
8575         resolve_host = 1;
8576       else if (unformat (i, "resolve-via-attached"))
8577         resolve_attached = 1;
8578       else if (unformat (i, "multipath"))
8579         is_multipath = 1;
8580       else if (unformat (i, "count %d", &count))
8581         ;
8582       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8583         {
8584           next_hop_set = 1;
8585           next_hop_proto = DPO_PROTO_IP4;
8586         }
8587       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8588         {
8589           next_hop_set = 1;
8590           next_hop_proto = DPO_PROTO_IP6;
8591         }
8592       else
8593         if (unformat
8594             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8595              &sw_if_index))
8596         {
8597           next_hop_set = 1;
8598           next_hop_proto = DPO_PROTO_ETHERNET;
8599           is_interface_rx = 1;
8600         }
8601       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8602         {
8603           next_hop_set = 1;
8604           next_hop_proto = DPO_PROTO_ETHERNET;
8605           is_interface_rx = 1;
8606         }
8607       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8608         next_hop_set = 1;
8609       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8610         next_hop_set = 1;
8611       else if (unformat (i, "out-label %d", &next_hop_out_label))
8612         {
8613           vl_api_fib_mpls_label_t fib_label = {
8614             .label = ntohl (next_hop_out_label),
8615             .ttl = 64,
8616             .exp = 0,
8617           };
8618           vec_add1 (next_hop_out_label_stack, fib_label);
8619         }
8620       else
8621         {
8622           clib_warning ("parse error '%U'", format_unformat_error, i);
8623           return -99;
8624         }
8625     }
8626
8627   if (!next_hop_set && !is_classify)
8628     {
8629       errmsg ("next hop / classify not set");
8630       return -99;
8631     }
8632
8633   if (MPLS_LABEL_INVALID == local_label)
8634     {
8635       errmsg ("missing label");
8636       return -99;
8637     }
8638
8639   if (count > 1)
8640     {
8641       /* Turn on async mode */
8642       vam->async_mode = 1;
8643       vam->async_errors = 0;
8644       before = vat_time_now (vam);
8645     }
8646
8647   for (j = 0; j < count; j++)
8648     {
8649       /* Construct the API message */
8650       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8651           vec_len (next_hop_out_label_stack));
8652
8653       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8654       mp->mr_table_id = ntohl (table_id);
8655
8656       mp->mr_is_add = is_add;
8657       mp->mr_next_hop_proto = next_hop_proto;
8658       mp->mr_is_classify = is_classify;
8659       mp->mr_is_multipath = is_multipath;
8660       mp->mr_is_resolve_host = resolve_host;
8661       mp->mr_is_resolve_attached = resolve_attached;
8662       mp->mr_is_interface_rx = is_interface_rx;
8663       mp->mr_next_hop_weight = next_hop_weight;
8664       mp->mr_next_hop_preference = 0;
8665       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8666       mp->mr_classify_table_index = ntohl (classify_table_index);
8667       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8668       mp->mr_label = ntohl (local_label);
8669       mp->mr_eos = is_eos;
8670
8671       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8672       if (0 != mp->mr_next_hop_n_out_labels)
8673         {
8674           memcpy (mp->mr_next_hop_out_label_stack,
8675                   next_hop_out_label_stack,
8676                   vec_len (next_hop_out_label_stack) *
8677                   sizeof (vl_api_fib_mpls_label_t));
8678           vec_free (next_hop_out_label_stack);
8679         }
8680
8681       if (next_hop_set)
8682         {
8683           if (DPO_PROTO_IP4 == next_hop_proto)
8684             {
8685               clib_memcpy (mp->mr_next_hop,
8686                            &v4_next_hop_address,
8687                            sizeof (v4_next_hop_address));
8688             }
8689           else if (DPO_PROTO_IP6 == next_hop_proto)
8690
8691             {
8692               clib_memcpy (mp->mr_next_hop,
8693                            &v6_next_hop_address,
8694                            sizeof (v6_next_hop_address));
8695             }
8696         }
8697       local_label++;
8698
8699       /* send it... */
8700       S (mp);
8701       /* If we receive SIGTERM, stop now... */
8702       if (vam->do_exit)
8703         break;
8704     }
8705
8706   /* When testing multiple add/del ops, use a control-ping to sync */
8707   if (count > 1)
8708     {
8709       vl_api_control_ping_t *mp_ping;
8710       f64 after;
8711       f64 timeout;
8712
8713       /* Shut off async mode */
8714       vam->async_mode = 0;
8715
8716       MPING (CONTROL_PING, mp_ping);
8717       S (mp_ping);
8718
8719       timeout = vat_time_now (vam) + 1.0;
8720       while (vat_time_now (vam) < timeout)
8721         if (vam->result_ready == 1)
8722           goto out;
8723       vam->retval = -99;
8724
8725     out:
8726       if (vam->retval == -99)
8727         errmsg ("timeout");
8728
8729       if (vam->async_errors > 0)
8730         {
8731           errmsg ("%d asynchronous errors", vam->async_errors);
8732           vam->retval = -98;
8733         }
8734       vam->async_errors = 0;
8735       after = vat_time_now (vam);
8736
8737       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8738       if (j > 0)
8739         count = j;
8740
8741       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8742              count, after - before, count / (after - before));
8743     }
8744   else
8745     {
8746       int ret;
8747
8748       /* Wait for a reply... */
8749       W (ret);
8750       return ret;
8751     }
8752
8753   /* Return the good/bad news */
8754   return (vam->retval);
8755 }
8756
8757 static int
8758 api_mpls_ip_bind_unbind (vat_main_t * vam)
8759 {
8760   unformat_input_t *i = vam->input;
8761   vl_api_mpls_ip_bind_unbind_t *mp;
8762   u32 ip_table_id = 0;
8763   u8 is_bind = 1;
8764   u8 is_ip4 = 1;
8765   ip4_address_t v4_address;
8766   ip6_address_t v6_address;
8767   u32 address_length;
8768   u8 address_set = 0;
8769   mpls_label_t local_label = MPLS_LABEL_INVALID;
8770   int ret;
8771
8772   /* Parse args required to build the message */
8773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8774     {
8775       if (unformat (i, "%U/%d", unformat_ip4_address,
8776                     &v4_address, &address_length))
8777         {
8778           is_ip4 = 1;
8779           address_set = 1;
8780         }
8781       else if (unformat (i, "%U/%d", unformat_ip6_address,
8782                          &v6_address, &address_length))
8783         {
8784           is_ip4 = 0;
8785           address_set = 1;
8786         }
8787       else if (unformat (i, "%d", &local_label))
8788         ;
8789       else if (unformat (i, "table-id %d", &ip_table_id))
8790         ;
8791       else if (unformat (i, "unbind"))
8792         is_bind = 0;
8793       else if (unformat (i, "bind"))
8794         is_bind = 1;
8795       else
8796         {
8797           clib_warning ("parse error '%U'", format_unformat_error, i);
8798           return -99;
8799         }
8800     }
8801
8802   if (!address_set)
8803     {
8804       errmsg ("IP address not set");
8805       return -99;
8806     }
8807
8808   if (MPLS_LABEL_INVALID == local_label)
8809     {
8810       errmsg ("missing label");
8811       return -99;
8812     }
8813
8814   /* Construct the API message */
8815   M (MPLS_IP_BIND_UNBIND, mp);
8816
8817   mp->mb_is_bind = is_bind;
8818   mp->mb_is_ip4 = is_ip4;
8819   mp->mb_ip_table_id = ntohl (ip_table_id);
8820   mp->mb_mpls_table_id = 0;
8821   mp->mb_label = ntohl (local_label);
8822   mp->mb_address_length = address_length;
8823
8824   if (is_ip4)
8825     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8826   else
8827     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8828
8829   /* send it... */
8830   S (mp);
8831
8832   /* Wait for a reply... */
8833   W (ret);
8834   return ret;
8835 }
8836
8837 static int
8838 api_sr_mpls_policy_add (vat_main_t * vam)
8839 {
8840   unformat_input_t *i = vam->input;
8841   vl_api_sr_mpls_policy_add_t *mp;
8842   u32 bsid = 0;
8843   u32 weight = 1;
8844   u8 type = 0;
8845   u8 n_segments = 0;
8846   u32 sid;
8847   u32 *segments = NULL;
8848   int ret;
8849
8850   /* Parse args required to build the message */
8851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8852     {
8853       if (unformat (i, "bsid %d", &bsid))
8854         ;
8855       else if (unformat (i, "weight %d", &weight))
8856         ;
8857       else if (unformat (i, "spray"))
8858         type = 1;
8859       else if (unformat (i, "next %d", &sid))
8860         {
8861           n_segments += 1;
8862           vec_add1 (segments, htonl (sid));
8863         }
8864       else
8865         {
8866           clib_warning ("parse error '%U'", format_unformat_error, i);
8867           return -99;
8868         }
8869     }
8870
8871   if (bsid == 0)
8872     {
8873       errmsg ("bsid not set");
8874       return -99;
8875     }
8876
8877   if (n_segments == 0)
8878     {
8879       errmsg ("no sid in segment stack");
8880       return -99;
8881     }
8882
8883   /* Construct the API message */
8884   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8885
8886   mp->bsid = htonl (bsid);
8887   mp->weight = htonl (weight);
8888   mp->type = type;
8889   mp->n_segments = n_segments;
8890   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8891   vec_free (segments);
8892
8893   /* send it... */
8894   S (mp);
8895
8896   /* Wait for a reply... */
8897   W (ret);
8898   return ret;
8899 }
8900
8901 static int
8902 api_sr_mpls_policy_del (vat_main_t * vam)
8903 {
8904   unformat_input_t *i = vam->input;
8905   vl_api_sr_mpls_policy_del_t *mp;
8906   u32 bsid = 0;
8907   int ret;
8908
8909   /* Parse args required to build the message */
8910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8911     {
8912       if (unformat (i, "bsid %d", &bsid))
8913         ;
8914       else
8915         {
8916           clib_warning ("parse error '%U'", format_unformat_error, i);
8917           return -99;
8918         }
8919     }
8920
8921   if (bsid == 0)
8922     {
8923       errmsg ("bsid not set");
8924       return -99;
8925     }
8926
8927   /* Construct the API message */
8928   M (SR_MPLS_POLICY_DEL, mp);
8929
8930   mp->bsid = htonl (bsid);
8931
8932   /* send it... */
8933   S (mp);
8934
8935   /* Wait for a reply... */
8936   W (ret);
8937   return ret;
8938 }
8939
8940 static int
8941 api_bier_table_add_del (vat_main_t * vam)
8942 {
8943   unformat_input_t *i = vam->input;
8944   vl_api_bier_table_add_del_t *mp;
8945   u8 is_add = 1;
8946   u32 set = 0, sub_domain = 0, hdr_len = 3;
8947   mpls_label_t local_label = MPLS_LABEL_INVALID;
8948   int ret;
8949
8950   /* Parse args required to build the message */
8951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8952     {
8953       if (unformat (i, "sub-domain %d", &sub_domain))
8954         ;
8955       else if (unformat (i, "set %d", &set))
8956         ;
8957       else if (unformat (i, "label %d", &local_label))
8958         ;
8959       else if (unformat (i, "hdr-len %d", &hdr_len))
8960         ;
8961       else if (unformat (i, "add"))
8962         is_add = 1;
8963       else if (unformat (i, "del"))
8964         is_add = 0;
8965       else
8966         {
8967           clib_warning ("parse error '%U'", format_unformat_error, i);
8968           return -99;
8969         }
8970     }
8971
8972   if (MPLS_LABEL_INVALID == local_label)
8973     {
8974       errmsg ("missing label\n");
8975       return -99;
8976     }
8977
8978   /* Construct the API message */
8979   M (BIER_TABLE_ADD_DEL, mp);
8980
8981   mp->bt_is_add = is_add;
8982   mp->bt_label = ntohl (local_label);
8983   mp->bt_tbl_id.bt_set = set;
8984   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8985   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8986
8987   /* send it... */
8988   S (mp);
8989
8990   /* Wait for a reply... */
8991   W (ret);
8992
8993   return (ret);
8994 }
8995
8996 static int
8997 api_bier_route_add_del (vat_main_t * vam)
8998 {
8999   unformat_input_t *i = vam->input;
9000   vl_api_bier_route_add_del_t *mp;
9001   u8 is_add = 1;
9002   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9003   ip4_address_t v4_next_hop_address;
9004   ip6_address_t v6_next_hop_address;
9005   u8 next_hop_set = 0;
9006   u8 next_hop_proto_is_ip4 = 1;
9007   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9008   int ret;
9009
9010   /* Parse args required to build the message */
9011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9012     {
9013       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9014         {
9015           next_hop_proto_is_ip4 = 1;
9016           next_hop_set = 1;
9017         }
9018       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9019         {
9020           next_hop_proto_is_ip4 = 0;
9021           next_hop_set = 1;
9022         }
9023       if (unformat (i, "sub-domain %d", &sub_domain))
9024         ;
9025       else if (unformat (i, "set %d", &set))
9026         ;
9027       else if (unformat (i, "hdr-len %d", &hdr_len))
9028         ;
9029       else if (unformat (i, "bp %d", &bp))
9030         ;
9031       else if (unformat (i, "add"))
9032         is_add = 1;
9033       else if (unformat (i, "del"))
9034         is_add = 0;
9035       else if (unformat (i, "out-label %d", &next_hop_out_label))
9036         ;
9037       else
9038         {
9039           clib_warning ("parse error '%U'", format_unformat_error, i);
9040           return -99;
9041         }
9042     }
9043
9044   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9045     {
9046       errmsg ("next hop / label set\n");
9047       return -99;
9048     }
9049   if (0 == bp)
9050     {
9051       errmsg ("bit=position not set\n");
9052       return -99;
9053     }
9054
9055   /* Construct the API message */
9056   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9057
9058   mp->br_is_add = is_add;
9059   mp->br_tbl_id.bt_set = set;
9060   mp->br_tbl_id.bt_sub_domain = sub_domain;
9061   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9062   mp->br_bp = ntohs (bp);
9063   mp->br_n_paths = 1;
9064   mp->br_paths[0].n_labels = 1;
9065   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9066   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9067
9068   if (next_hop_proto_is_ip4)
9069     {
9070       clib_memcpy (mp->br_paths[0].next_hop,
9071                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9072     }
9073   else
9074     {
9075       clib_memcpy (mp->br_paths[0].next_hop,
9076                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9077     }
9078
9079   /* send it... */
9080   S (mp);
9081
9082   /* Wait for a reply... */
9083   W (ret);
9084
9085   return (ret);
9086 }
9087
9088 static int
9089 api_proxy_arp_add_del (vat_main_t * vam)
9090 {
9091   unformat_input_t *i = vam->input;
9092   vl_api_proxy_arp_add_del_t *mp;
9093   u32 vrf_id = 0;
9094   u8 is_add = 1;
9095   vl_api_ip4_address_t lo, hi;
9096   u8 range_set = 0;
9097   int ret;
9098
9099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9100     {
9101       if (unformat (i, "vrf %d", &vrf_id))
9102         ;
9103       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9104                          unformat_vl_api_ip4_address, &hi))
9105         range_set = 1;
9106       else if (unformat (i, "del"))
9107         is_add = 0;
9108       else
9109         {
9110           clib_warning ("parse error '%U'", format_unformat_error, i);
9111           return -99;
9112         }
9113     }
9114
9115   if (range_set == 0)
9116     {
9117       errmsg ("address range not set");
9118       return -99;
9119     }
9120
9121   M (PROXY_ARP_ADD_DEL, mp);
9122
9123   mp->proxy.table_id = ntohl (vrf_id);
9124   mp->is_add = is_add;
9125   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9126   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9127
9128   S (mp);
9129   W (ret);
9130   return ret;
9131 }
9132
9133 static int
9134 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9135 {
9136   unformat_input_t *i = vam->input;
9137   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9138   u32 sw_if_index;
9139   u8 enable = 1;
9140   u8 sw_if_index_set = 0;
9141   int ret;
9142
9143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9144     {
9145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9146         sw_if_index_set = 1;
9147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9148         sw_if_index_set = 1;
9149       else if (unformat (i, "enable"))
9150         enable = 1;
9151       else if (unformat (i, "disable"))
9152         enable = 0;
9153       else
9154         {
9155           clib_warning ("parse error '%U'", format_unformat_error, i);
9156           return -99;
9157         }
9158     }
9159
9160   if (sw_if_index_set == 0)
9161     {
9162       errmsg ("missing interface name or sw_if_index");
9163       return -99;
9164     }
9165
9166   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9167
9168   mp->sw_if_index = ntohl (sw_if_index);
9169   mp->enable_disable = enable;
9170
9171   S (mp);
9172   W (ret);
9173   return ret;
9174 }
9175
9176 static int
9177 api_mpls_tunnel_add_del (vat_main_t * vam)
9178 {
9179   unformat_input_t *i = vam->input;
9180   vl_api_mpls_tunnel_add_del_t *mp;
9181
9182   u8 is_add = 1;
9183   u8 l2_only = 0;
9184   u32 sw_if_index = ~0;
9185   u32 next_hop_sw_if_index = ~0;
9186   u32 next_hop_proto_is_ip4 = 1;
9187
9188   u32 next_hop_table_id = 0;
9189   ip4_address_t v4_next_hop_address = {
9190     .as_u32 = 0,
9191   };
9192   ip6_address_t v6_next_hop_address = { {0} };
9193   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9194   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9195   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9196   int ret;
9197
9198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9199     {
9200       if (unformat (i, "add"))
9201         is_add = 1;
9202       else
9203         if (unformat
9204             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9205         is_add = 0;
9206       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9207         is_add = 0;
9208       else if (unformat (i, "via %U",
9209                          unformat_ip4_address, &v4_next_hop_address))
9210         {
9211           next_hop_proto_is_ip4 = 1;
9212         }
9213       else if (unformat (i, "via %U",
9214                          unformat_ip6_address, &v6_next_hop_address))
9215         {
9216           next_hop_proto_is_ip4 = 0;
9217         }
9218       else if (unformat (i, "via-label %d", &next_hop_via_label))
9219         ;
9220       else
9221         if (unformat
9222             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9223         ;
9224       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9225         ;
9226       else if (unformat (i, "l2-only"))
9227         l2_only = 1;
9228       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9229         ;
9230       else if (unformat (i, "out-label %d", &next_hop_out_label))
9231         {
9232           vl_api_fib_mpls_label_t fib_label = {
9233             .label = ntohl (next_hop_out_label),
9234             .ttl = 64,
9235             .exp = 0,
9236           };
9237           vec_add1 (next_hop_out_label_stack, fib_label);
9238         }
9239       else
9240         {
9241           clib_warning ("parse error '%U'", format_unformat_error, i);
9242           return -99;
9243         }
9244     }
9245
9246   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9247       vec_len (next_hop_out_label_stack));
9248
9249   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9250   mp->mt_sw_if_index = ntohl (sw_if_index);
9251   mp->mt_is_add = is_add;
9252   mp->mt_l2_only = l2_only;
9253   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9254   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9255   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9256   mp->mt_next_hop_weight = 1;
9257   mp->mt_next_hop_preference = 0;
9258
9259   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9260
9261   if (0 != mp->mt_next_hop_n_out_labels)
9262     {
9263       clib_memcpy (mp->mt_next_hop_out_label_stack,
9264                    next_hop_out_label_stack,
9265                    (vec_len (next_hop_out_label_stack) *
9266                     sizeof (vl_api_fib_mpls_label_t)));
9267       vec_free (next_hop_out_label_stack);
9268     }
9269
9270   if (next_hop_proto_is_ip4)
9271     {
9272       clib_memcpy (mp->mt_next_hop,
9273                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9274     }
9275   else
9276     {
9277       clib_memcpy (mp->mt_next_hop,
9278                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9279     }
9280
9281   S (mp);
9282   W (ret);
9283   return ret;
9284 }
9285
9286 static int
9287 api_sw_interface_set_unnumbered (vat_main_t * vam)
9288 {
9289   unformat_input_t *i = vam->input;
9290   vl_api_sw_interface_set_unnumbered_t *mp;
9291   u32 sw_if_index;
9292   u32 unnum_sw_index = ~0;
9293   u8 is_add = 1;
9294   u8 sw_if_index_set = 0;
9295   int ret;
9296
9297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9298     {
9299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9300         sw_if_index_set = 1;
9301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9302         sw_if_index_set = 1;
9303       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9304         ;
9305       else if (unformat (i, "del"))
9306         is_add = 0;
9307       else
9308         {
9309           clib_warning ("parse error '%U'", format_unformat_error, i);
9310           return -99;
9311         }
9312     }
9313
9314   if (sw_if_index_set == 0)
9315     {
9316       errmsg ("missing interface name or sw_if_index");
9317       return -99;
9318     }
9319
9320   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9321
9322   mp->sw_if_index = ntohl (sw_if_index);
9323   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9324   mp->is_add = is_add;
9325
9326   S (mp);
9327   W (ret);
9328   return ret;
9329 }
9330
9331 static int
9332 api_ip_neighbor_add_del (vat_main_t * vam)
9333 {
9334   vl_api_mac_address_t mac_address;
9335   unformat_input_t *i = vam->input;
9336   vl_api_ip_neighbor_add_del_t *mp;
9337   vl_api_address_t ip_address;
9338   u32 sw_if_index;
9339   u8 sw_if_index_set = 0;
9340   u8 is_add = 1;
9341   u8 mac_set = 0;
9342   u8 address_set = 0;
9343   int ret;
9344   ip_neighbor_flags_t flags;
9345
9346   flags = IP_NEIGHBOR_FLAG_NONE;
9347   clib_memset (&ip_address, 0, sizeof (ip_address));
9348   clib_memset (&mac_address, 0, sizeof (mac_address));
9349   /* Parse args required to build the message */
9350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9351     {
9352       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9353         {
9354           mac_set = 1;
9355         }
9356       else if (unformat (i, "del"))
9357         is_add = 0;
9358       else
9359         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9360         sw_if_index_set = 1;
9361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9362         sw_if_index_set = 1;
9363       else if (unformat (i, "static"))
9364         flags |= IP_NEIGHBOR_FLAG_STATIC;
9365       else if (unformat (i, "no-fib-entry"))
9366         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9367       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9368         address_set = 1;
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (sw_if_index_set == 0)
9377     {
9378       errmsg ("missing interface name or sw_if_index");
9379       return -99;
9380     }
9381   if (!address_set)
9382     {
9383       errmsg ("no address set");
9384       return -99;
9385     }
9386
9387   /* Construct the API message */
9388   M (IP_NEIGHBOR_ADD_DEL, mp);
9389
9390   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9391   mp->is_add = is_add;
9392   mp->neighbor.flags = htonl (flags);
9393   if (mac_set)
9394     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9395                  sizeof (mac_address));
9396   if (address_set)
9397     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9398
9399   /* send it... */
9400   S (mp);
9401
9402   /* Wait for a reply, return good/bad news  */
9403   W (ret);
9404   return ret;
9405 }
9406
9407 static int
9408 api_create_vlan_subif (vat_main_t * vam)
9409 {
9410   unformat_input_t *i = vam->input;
9411   vl_api_create_vlan_subif_t *mp;
9412   u32 sw_if_index;
9413   u8 sw_if_index_set = 0;
9414   u32 vlan_id;
9415   u8 vlan_id_set = 0;
9416   int ret;
9417
9418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9419     {
9420       if (unformat (i, "sw_if_index %d", &sw_if_index))
9421         sw_if_index_set = 1;
9422       else
9423         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9424         sw_if_index_set = 1;
9425       else if (unformat (i, "vlan %d", &vlan_id))
9426         vlan_id_set = 1;
9427       else
9428         {
9429           clib_warning ("parse error '%U'", format_unformat_error, i);
9430           return -99;
9431         }
9432     }
9433
9434   if (sw_if_index_set == 0)
9435     {
9436       errmsg ("missing interface name or sw_if_index");
9437       return -99;
9438     }
9439
9440   if (vlan_id_set == 0)
9441     {
9442       errmsg ("missing vlan_id");
9443       return -99;
9444     }
9445   M (CREATE_VLAN_SUBIF, mp);
9446
9447   mp->sw_if_index = ntohl (sw_if_index);
9448   mp->vlan_id = ntohl (vlan_id);
9449
9450   S (mp);
9451   W (ret);
9452   return ret;
9453 }
9454
9455 #define foreach_create_subif_bit                \
9456 _(no_tags)                                      \
9457 _(one_tag)                                      \
9458 _(two_tags)                                     \
9459 _(dot1ad)                                       \
9460 _(exact_match)                                  \
9461 _(default_sub)                                  \
9462 _(outer_vlan_id_any)                            \
9463 _(inner_vlan_id_any)
9464
9465 static int
9466 api_create_subif (vat_main_t * vam)
9467 {
9468   unformat_input_t *i = vam->input;
9469   vl_api_create_subif_t *mp;
9470   u32 sw_if_index;
9471   u8 sw_if_index_set = 0;
9472   u32 sub_id;
9473   u8 sub_id_set = 0;
9474   u32 no_tags = 0;
9475   u32 one_tag = 0;
9476   u32 two_tags = 0;
9477   u32 dot1ad = 0;
9478   u32 exact_match = 0;
9479   u32 default_sub = 0;
9480   u32 outer_vlan_id_any = 0;
9481   u32 inner_vlan_id_any = 0;
9482   u32 tmp;
9483   u16 outer_vlan_id = 0;
9484   u16 inner_vlan_id = 0;
9485   int ret;
9486
9487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9488     {
9489       if (unformat (i, "sw_if_index %d", &sw_if_index))
9490         sw_if_index_set = 1;
9491       else
9492         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9493         sw_if_index_set = 1;
9494       else if (unformat (i, "sub_id %d", &sub_id))
9495         sub_id_set = 1;
9496       else if (unformat (i, "outer_vlan_id %d", &tmp))
9497         outer_vlan_id = tmp;
9498       else if (unformat (i, "inner_vlan_id %d", &tmp))
9499         inner_vlan_id = tmp;
9500
9501 #define _(a) else if (unformat (i, #a)) a = 1 ;
9502       foreach_create_subif_bit
9503 #undef _
9504         else
9505         {
9506           clib_warning ("parse error '%U'", format_unformat_error, i);
9507           return -99;
9508         }
9509     }
9510
9511   if (sw_if_index_set == 0)
9512     {
9513       errmsg ("missing interface name or sw_if_index");
9514       return -99;
9515     }
9516
9517   if (sub_id_set == 0)
9518     {
9519       errmsg ("missing sub_id");
9520       return -99;
9521     }
9522   M (CREATE_SUBIF, mp);
9523
9524   mp->sw_if_index = ntohl (sw_if_index);
9525   mp->sub_id = ntohl (sub_id);
9526
9527 #define _(a) mp->a = a;
9528   foreach_create_subif_bit;
9529 #undef _
9530
9531   mp->outer_vlan_id = ntohs (outer_vlan_id);
9532   mp->inner_vlan_id = ntohs (inner_vlan_id);
9533
9534   S (mp);
9535   W (ret);
9536   return ret;
9537 }
9538
9539 static int
9540 api_oam_add_del (vat_main_t * vam)
9541 {
9542   unformat_input_t *i = vam->input;
9543   vl_api_oam_add_del_t *mp;
9544   u32 vrf_id = 0;
9545   u8 is_add = 1;
9546   ip4_address_t src, dst;
9547   u8 src_set = 0;
9548   u8 dst_set = 0;
9549   int ret;
9550
9551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9552     {
9553       if (unformat (i, "vrf %d", &vrf_id))
9554         ;
9555       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9556         src_set = 1;
9557       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9558         dst_set = 1;
9559       else if (unformat (i, "del"))
9560         is_add = 0;
9561       else
9562         {
9563           clib_warning ("parse error '%U'", format_unformat_error, i);
9564           return -99;
9565         }
9566     }
9567
9568   if (src_set == 0)
9569     {
9570       errmsg ("missing src addr");
9571       return -99;
9572     }
9573
9574   if (dst_set == 0)
9575     {
9576       errmsg ("missing dst addr");
9577       return -99;
9578     }
9579
9580   M (OAM_ADD_DEL, mp);
9581
9582   mp->vrf_id = ntohl (vrf_id);
9583   mp->is_add = is_add;
9584   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9585   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9586
9587   S (mp);
9588   W (ret);
9589   return ret;
9590 }
9591
9592 static int
9593 api_reset_fib (vat_main_t * vam)
9594 {
9595   unformat_input_t *i = vam->input;
9596   vl_api_reset_fib_t *mp;
9597   u32 vrf_id = 0;
9598   u8 is_ipv6 = 0;
9599   u8 vrf_id_set = 0;
9600
9601   int ret;
9602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9603     {
9604       if (unformat (i, "vrf %d", &vrf_id))
9605         vrf_id_set = 1;
9606       else if (unformat (i, "ipv6"))
9607         is_ipv6 = 1;
9608       else
9609         {
9610           clib_warning ("parse error '%U'", format_unformat_error, i);
9611           return -99;
9612         }
9613     }
9614
9615   if (vrf_id_set == 0)
9616     {
9617       errmsg ("missing vrf id");
9618       return -99;
9619     }
9620
9621   M (RESET_FIB, mp);
9622
9623   mp->vrf_id = ntohl (vrf_id);
9624   mp->is_ipv6 = is_ipv6;
9625
9626   S (mp);
9627   W (ret);
9628   return ret;
9629 }
9630
9631 static int
9632 api_dhcp_proxy_config (vat_main_t * vam)
9633 {
9634   unformat_input_t *i = vam->input;
9635   vl_api_dhcp_proxy_config_t *mp;
9636   u32 rx_vrf_id = 0;
9637   u32 server_vrf_id = 0;
9638   u8 is_add = 1;
9639   u8 v4_address_set = 0;
9640   u8 v6_address_set = 0;
9641   ip4_address_t v4address;
9642   ip6_address_t v6address;
9643   u8 v4_src_address_set = 0;
9644   u8 v6_src_address_set = 0;
9645   ip4_address_t v4srcaddress;
9646   ip6_address_t v6srcaddress;
9647   int ret;
9648
9649   /* Parse args required to build the message */
9650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9651     {
9652       if (unformat (i, "del"))
9653         is_add = 0;
9654       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9655         ;
9656       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9657         ;
9658       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9659         v4_address_set = 1;
9660       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9661         v6_address_set = 1;
9662       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9663         v4_src_address_set = 1;
9664       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9665         v6_src_address_set = 1;
9666       else
9667         break;
9668     }
9669
9670   if (v4_address_set && v6_address_set)
9671     {
9672       errmsg ("both v4 and v6 server addresses set");
9673       return -99;
9674     }
9675   if (!v4_address_set && !v6_address_set)
9676     {
9677       errmsg ("no server addresses set");
9678       return -99;
9679     }
9680
9681   if (v4_src_address_set && v6_src_address_set)
9682     {
9683       errmsg ("both v4 and v6  src addresses set");
9684       return -99;
9685     }
9686   if (!v4_src_address_set && !v6_src_address_set)
9687     {
9688       errmsg ("no src addresses set");
9689       return -99;
9690     }
9691
9692   if (!(v4_src_address_set && v4_address_set) &&
9693       !(v6_src_address_set && v6_address_set))
9694     {
9695       errmsg ("no matching server and src addresses set");
9696       return -99;
9697     }
9698
9699   /* Construct the API message */
9700   M (DHCP_PROXY_CONFIG, mp);
9701
9702   mp->is_add = is_add;
9703   mp->rx_vrf_id = ntohl (rx_vrf_id);
9704   mp->server_vrf_id = ntohl (server_vrf_id);
9705   if (v6_address_set)
9706     {
9707       mp->is_ipv6 = 1;
9708       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9709       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9710     }
9711   else
9712     {
9713       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9714       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9715     }
9716
9717   /* send it... */
9718   S (mp);
9719
9720   /* Wait for a reply, return good/bad news  */
9721   W (ret);
9722   return ret;
9723 }
9724
9725 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9726 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9727
9728 static void
9729 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9730 {
9731   vat_main_t *vam = &vat_main;
9732   u32 i, count = mp->count;
9733   vl_api_dhcp_server_t *s;
9734
9735   if (mp->is_ipv6)
9736     print (vam->ofp,
9737            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9738            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9739            ntohl (mp->rx_vrf_id),
9740            format_ip6_address, mp->dhcp_src_address,
9741            mp->vss_type, mp->vss_vpn_ascii_id,
9742            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9743   else
9744     print (vam->ofp,
9745            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9746            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9747            ntohl (mp->rx_vrf_id),
9748            format_ip4_address, mp->dhcp_src_address,
9749            mp->vss_type, mp->vss_vpn_ascii_id,
9750            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9751
9752   for (i = 0; i < count; i++)
9753     {
9754       s = &mp->servers[i];
9755
9756       if (mp->is_ipv6)
9757         print (vam->ofp,
9758                " Server Table-ID %d, Server Address %U",
9759                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9760       else
9761         print (vam->ofp,
9762                " Server Table-ID %d, Server Address %U",
9763                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9764     }
9765 }
9766
9767 static void vl_api_dhcp_proxy_details_t_handler_json
9768   (vl_api_dhcp_proxy_details_t * mp)
9769 {
9770   vat_main_t *vam = &vat_main;
9771   vat_json_node_t *node = NULL;
9772   u32 i, count = mp->count;
9773   struct in_addr ip4;
9774   struct in6_addr ip6;
9775   vl_api_dhcp_server_t *s;
9776
9777   if (VAT_JSON_ARRAY != vam->json_tree.type)
9778     {
9779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9780       vat_json_init_array (&vam->json_tree);
9781     }
9782   node = vat_json_array_add (&vam->json_tree);
9783
9784   vat_json_init_object (node);
9785   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9786   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9787                              sizeof (mp->vss_type));
9788   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9789                                    mp->vss_vpn_ascii_id);
9790   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9791   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9792
9793   if (mp->is_ipv6)
9794     {
9795       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9796       vat_json_object_add_ip6 (node, "src_address", ip6);
9797     }
9798   else
9799     {
9800       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9801       vat_json_object_add_ip4 (node, "src_address", ip4);
9802     }
9803
9804   for (i = 0; i < count; i++)
9805     {
9806       s = &mp->servers[i];
9807
9808       vat_json_object_add_uint (node, "server-table-id",
9809                                 ntohl (s->server_vrf_id));
9810
9811       if (mp->is_ipv6)
9812         {
9813           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9814           vat_json_object_add_ip4 (node, "src_address", ip4);
9815         }
9816       else
9817         {
9818           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9819           vat_json_object_add_ip6 (node, "server_address", ip6);
9820         }
9821     }
9822 }
9823
9824 static int
9825 api_dhcp_proxy_dump (vat_main_t * vam)
9826 {
9827   unformat_input_t *i = vam->input;
9828   vl_api_control_ping_t *mp_ping;
9829   vl_api_dhcp_proxy_dump_t *mp;
9830   u8 is_ipv6 = 0;
9831   int ret;
9832
9833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9834     {
9835       if (unformat (i, "ipv6"))
9836         is_ipv6 = 1;
9837       else
9838         {
9839           clib_warning ("parse error '%U'", format_unformat_error, i);
9840           return -99;
9841         }
9842     }
9843
9844   M (DHCP_PROXY_DUMP, mp);
9845
9846   mp->is_ip6 = is_ipv6;
9847   S (mp);
9848
9849   /* Use a control ping for synchronization */
9850   MPING (CONTROL_PING, mp_ping);
9851   S (mp_ping);
9852
9853   W (ret);
9854   return ret;
9855 }
9856
9857 static int
9858 api_dhcp_proxy_set_vss (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_dhcp_proxy_set_vss_t *mp;
9862   u8 is_ipv6 = 0;
9863   u8 is_add = 1;
9864   u32 tbl_id = ~0;
9865   u8 vss_type = VSS_TYPE_DEFAULT;
9866   u8 *vpn_ascii_id = 0;
9867   u32 oui = 0;
9868   u32 fib_id = 0;
9869   int ret;
9870
9871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9872     {
9873       if (unformat (i, "tbl_id %d", &tbl_id))
9874         ;
9875       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9876         vss_type = VSS_TYPE_ASCII;
9877       else if (unformat (i, "fib_id %d", &fib_id))
9878         vss_type = VSS_TYPE_VPN_ID;
9879       else if (unformat (i, "oui %d", &oui))
9880         vss_type = VSS_TYPE_VPN_ID;
9881       else if (unformat (i, "ipv6"))
9882         is_ipv6 = 1;
9883       else if (unformat (i, "del"))
9884         is_add = 0;
9885       else
9886         break;
9887     }
9888
9889   if (tbl_id == ~0)
9890     {
9891       errmsg ("missing tbl_id ");
9892       vec_free (vpn_ascii_id);
9893       return -99;
9894     }
9895
9896   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9897     {
9898       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9899       vec_free (vpn_ascii_id);
9900       return -99;
9901     }
9902
9903   M (DHCP_PROXY_SET_VSS, mp);
9904   mp->tbl_id = ntohl (tbl_id);
9905   mp->vss_type = vss_type;
9906   if (vpn_ascii_id)
9907     {
9908       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9909       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9910     }
9911   mp->vpn_index = ntohl (fib_id);
9912   mp->oui = ntohl (oui);
9913   mp->is_ipv6 = is_ipv6;
9914   mp->is_add = is_add;
9915
9916   S (mp);
9917   W (ret);
9918
9919   vec_free (vpn_ascii_id);
9920   return ret;
9921 }
9922
9923 static int
9924 api_dhcp_client_config (vat_main_t * vam)
9925 {
9926   unformat_input_t *i = vam->input;
9927   vl_api_dhcp_client_config_t *mp;
9928   u32 sw_if_index;
9929   u8 sw_if_index_set = 0;
9930   u8 is_add = 1;
9931   u8 *hostname = 0;
9932   u8 disable_event = 0;
9933   int ret;
9934
9935   /* Parse args required to build the message */
9936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9937     {
9938       if (unformat (i, "del"))
9939         is_add = 0;
9940       else
9941         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9942         sw_if_index_set = 1;
9943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9944         sw_if_index_set = 1;
9945       else if (unformat (i, "hostname %s", &hostname))
9946         ;
9947       else if (unformat (i, "disable_event"))
9948         disable_event = 1;
9949       else
9950         break;
9951     }
9952
9953   if (sw_if_index_set == 0)
9954     {
9955       errmsg ("missing interface name or sw_if_index");
9956       return -99;
9957     }
9958
9959   if (vec_len (hostname) > 63)
9960     {
9961       errmsg ("hostname too long");
9962     }
9963   vec_add1 (hostname, 0);
9964
9965   /* Construct the API message */
9966   M (DHCP_CLIENT_CONFIG, mp);
9967
9968   mp->is_add = is_add;
9969   mp->client.sw_if_index = htonl (sw_if_index);
9970   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9971   vec_free (hostname);
9972   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9973   mp->client.pid = htonl (getpid ());
9974
9975   /* send it... */
9976   S (mp);
9977
9978   /* Wait for a reply, return good/bad news  */
9979   W (ret);
9980   return ret;
9981 }
9982
9983 static int
9984 api_set_ip_flow_hash (vat_main_t * vam)
9985 {
9986   unformat_input_t *i = vam->input;
9987   vl_api_set_ip_flow_hash_t *mp;
9988   u32 vrf_id = 0;
9989   u8 is_ipv6 = 0;
9990   u8 vrf_id_set = 0;
9991   u8 src = 0;
9992   u8 dst = 0;
9993   u8 sport = 0;
9994   u8 dport = 0;
9995   u8 proto = 0;
9996   u8 reverse = 0;
9997   int ret;
9998
9999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10000     {
10001       if (unformat (i, "vrf %d", &vrf_id))
10002         vrf_id_set = 1;
10003       else if (unformat (i, "ipv6"))
10004         is_ipv6 = 1;
10005       else if (unformat (i, "src"))
10006         src = 1;
10007       else if (unformat (i, "dst"))
10008         dst = 1;
10009       else if (unformat (i, "sport"))
10010         sport = 1;
10011       else if (unformat (i, "dport"))
10012         dport = 1;
10013       else if (unformat (i, "proto"))
10014         proto = 1;
10015       else if (unformat (i, "reverse"))
10016         reverse = 1;
10017
10018       else
10019         {
10020           clib_warning ("parse error '%U'", format_unformat_error, i);
10021           return -99;
10022         }
10023     }
10024
10025   if (vrf_id_set == 0)
10026     {
10027       errmsg ("missing vrf id");
10028       return -99;
10029     }
10030
10031   M (SET_IP_FLOW_HASH, mp);
10032   mp->src = src;
10033   mp->dst = dst;
10034   mp->sport = sport;
10035   mp->dport = dport;
10036   mp->proto = proto;
10037   mp->reverse = reverse;
10038   mp->vrf_id = ntohl (vrf_id);
10039   mp->is_ipv6 = is_ipv6;
10040
10041   S (mp);
10042   W (ret);
10043   return ret;
10044 }
10045
10046 static int
10047 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10048 {
10049   unformat_input_t *i = vam->input;
10050   vl_api_sw_interface_ip6_enable_disable_t *mp;
10051   u32 sw_if_index;
10052   u8 sw_if_index_set = 0;
10053   u8 enable = 0;
10054   int ret;
10055
10056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10057     {
10058       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10059         sw_if_index_set = 1;
10060       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10061         sw_if_index_set = 1;
10062       else if (unformat (i, "enable"))
10063         enable = 1;
10064       else if (unformat (i, "disable"))
10065         enable = 0;
10066       else
10067         {
10068           clib_warning ("parse error '%U'", format_unformat_error, i);
10069           return -99;
10070         }
10071     }
10072
10073   if (sw_if_index_set == 0)
10074     {
10075       errmsg ("missing interface name or sw_if_index");
10076       return -99;
10077     }
10078
10079   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10080
10081   mp->sw_if_index = ntohl (sw_if_index);
10082   mp->enable = enable;
10083
10084   S (mp);
10085   W (ret);
10086   return ret;
10087 }
10088
10089 static int
10090 api_ip6nd_proxy_add_del (vat_main_t * vam)
10091 {
10092   unformat_input_t *i = vam->input;
10093   vl_api_ip6nd_proxy_add_del_t *mp;
10094   u32 sw_if_index = ~0;
10095   u8 v6_address_set = 0;
10096   vl_api_ip6_address_t v6address;
10097   u8 is_del = 0;
10098   int ret;
10099
10100   /* Parse args required to build the message */
10101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10102     {
10103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10104         ;
10105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10106         ;
10107       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10108         v6_address_set = 1;
10109       if (unformat (i, "del"))
10110         is_del = 1;
10111       else
10112         {
10113           clib_warning ("parse error '%U'", format_unformat_error, i);
10114           return -99;
10115         }
10116     }
10117
10118   if (sw_if_index == ~0)
10119     {
10120       errmsg ("missing interface name or sw_if_index");
10121       return -99;
10122     }
10123   if (!v6_address_set)
10124     {
10125       errmsg ("no address set");
10126       return -99;
10127     }
10128
10129   /* Construct the API message */
10130   M (IP6ND_PROXY_ADD_DEL, mp);
10131
10132   mp->is_del = is_del;
10133   mp->sw_if_index = ntohl (sw_if_index);
10134   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10135
10136   /* send it... */
10137   S (mp);
10138
10139   /* Wait for a reply, return good/bad news  */
10140   W (ret);
10141   return ret;
10142 }
10143
10144 static int
10145 api_ip6nd_proxy_dump (vat_main_t * vam)
10146 {
10147   vl_api_ip6nd_proxy_dump_t *mp;
10148   vl_api_control_ping_t *mp_ping;
10149   int ret;
10150
10151   M (IP6ND_PROXY_DUMP, mp);
10152
10153   S (mp);
10154
10155   /* Use a control ping for synchronization */
10156   MPING (CONTROL_PING, mp_ping);
10157   S (mp_ping);
10158
10159   W (ret);
10160   return ret;
10161 }
10162
10163 static void vl_api_ip6nd_proxy_details_t_handler
10164   (vl_api_ip6nd_proxy_details_t * mp)
10165 {
10166   vat_main_t *vam = &vat_main;
10167
10168   print (vam->ofp, "host %U sw_if_index %d",
10169          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10170 }
10171
10172 static void vl_api_ip6nd_proxy_details_t_handler_json
10173   (vl_api_ip6nd_proxy_details_t * mp)
10174 {
10175   vat_main_t *vam = &vat_main;
10176   struct in6_addr ip6;
10177   vat_json_node_t *node = NULL;
10178
10179   if (VAT_JSON_ARRAY != vam->json_tree.type)
10180     {
10181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10182       vat_json_init_array (&vam->json_tree);
10183     }
10184   node = vat_json_array_add (&vam->json_tree);
10185
10186   vat_json_init_object (node);
10187   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10188
10189   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10190   vat_json_object_add_ip6 (node, "host", ip6);
10191 }
10192
10193 static int
10194 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10195 {
10196   unformat_input_t *i = vam->input;
10197   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10198   u32 sw_if_index;
10199   u8 sw_if_index_set = 0;
10200   u32 address_length = 0;
10201   u8 v6_address_set = 0;
10202   vl_api_prefix_t pfx;
10203   u8 use_default = 0;
10204   u8 no_advertise = 0;
10205   u8 off_link = 0;
10206   u8 no_autoconfig = 0;
10207   u8 no_onlink = 0;
10208   u8 is_no = 0;
10209   u32 val_lifetime = 0;
10210   u32 pref_lifetime = 0;
10211   int ret;
10212
10213   /* Parse args required to build the message */
10214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10215     {
10216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10217         sw_if_index_set = 1;
10218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10219         sw_if_index_set = 1;
10220       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10221         v6_address_set = 1;
10222       else if (unformat (i, "val_life %d", &val_lifetime))
10223         ;
10224       else if (unformat (i, "pref_life %d", &pref_lifetime))
10225         ;
10226       else if (unformat (i, "def"))
10227         use_default = 1;
10228       else if (unformat (i, "noadv"))
10229         no_advertise = 1;
10230       else if (unformat (i, "offl"))
10231         off_link = 1;
10232       else if (unformat (i, "noauto"))
10233         no_autoconfig = 1;
10234       else if (unformat (i, "nolink"))
10235         no_onlink = 1;
10236       else if (unformat (i, "isno"))
10237         is_no = 1;
10238       else
10239         {
10240           clib_warning ("parse error '%U'", format_unformat_error, i);
10241           return -99;
10242         }
10243     }
10244
10245   if (sw_if_index_set == 0)
10246     {
10247       errmsg ("missing interface name or sw_if_index");
10248       return -99;
10249     }
10250   if (!v6_address_set)
10251     {
10252       errmsg ("no address set");
10253       return -99;
10254     }
10255
10256   /* Construct the API message */
10257   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10258
10259   mp->sw_if_index = ntohl (sw_if_index);
10260   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10261   mp->use_default = use_default;
10262   mp->no_advertise = no_advertise;
10263   mp->off_link = off_link;
10264   mp->no_autoconfig = no_autoconfig;
10265   mp->no_onlink = no_onlink;
10266   mp->is_no = is_no;
10267   mp->val_lifetime = ntohl (val_lifetime);
10268   mp->pref_lifetime = ntohl (pref_lifetime);
10269
10270   /* send it... */
10271   S (mp);
10272
10273   /* Wait for a reply, return good/bad news  */
10274   W (ret);
10275   return ret;
10276 }
10277
10278 static int
10279 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10280 {
10281   unformat_input_t *i = vam->input;
10282   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10283   u32 sw_if_index;
10284   u8 sw_if_index_set = 0;
10285   u8 suppress = 0;
10286   u8 managed = 0;
10287   u8 other = 0;
10288   u8 ll_option = 0;
10289   u8 send_unicast = 0;
10290   u8 cease = 0;
10291   u8 is_no = 0;
10292   u8 default_router = 0;
10293   u32 max_interval = 0;
10294   u32 min_interval = 0;
10295   u32 lifetime = 0;
10296   u32 initial_count = 0;
10297   u32 initial_interval = 0;
10298   int ret;
10299
10300
10301   /* Parse args required to build the message */
10302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10303     {
10304       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10305         sw_if_index_set = 1;
10306       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10307         sw_if_index_set = 1;
10308       else if (unformat (i, "maxint %d", &max_interval))
10309         ;
10310       else if (unformat (i, "minint %d", &min_interval))
10311         ;
10312       else if (unformat (i, "life %d", &lifetime))
10313         ;
10314       else if (unformat (i, "count %d", &initial_count))
10315         ;
10316       else if (unformat (i, "interval %d", &initial_interval))
10317         ;
10318       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10319         suppress = 1;
10320       else if (unformat (i, "managed"))
10321         managed = 1;
10322       else if (unformat (i, "other"))
10323         other = 1;
10324       else if (unformat (i, "ll"))
10325         ll_option = 1;
10326       else if (unformat (i, "send"))
10327         send_unicast = 1;
10328       else if (unformat (i, "cease"))
10329         cease = 1;
10330       else if (unformat (i, "isno"))
10331         is_no = 1;
10332       else if (unformat (i, "def"))
10333         default_router = 1;
10334       else
10335         {
10336           clib_warning ("parse error '%U'", format_unformat_error, i);
10337           return -99;
10338         }
10339     }
10340
10341   if (sw_if_index_set == 0)
10342     {
10343       errmsg ("missing interface name or sw_if_index");
10344       return -99;
10345     }
10346
10347   /* Construct the API message */
10348   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10349
10350   mp->sw_if_index = ntohl (sw_if_index);
10351   mp->max_interval = ntohl (max_interval);
10352   mp->min_interval = ntohl (min_interval);
10353   mp->lifetime = ntohl (lifetime);
10354   mp->initial_count = ntohl (initial_count);
10355   mp->initial_interval = ntohl (initial_interval);
10356   mp->suppress = suppress;
10357   mp->managed = managed;
10358   mp->other = other;
10359   mp->ll_option = ll_option;
10360   mp->send_unicast = send_unicast;
10361   mp->cease = cease;
10362   mp->is_no = is_no;
10363   mp->default_router = default_router;
10364
10365   /* send it... */
10366   S (mp);
10367
10368   /* Wait for a reply, return good/bad news  */
10369   W (ret);
10370   return ret;
10371 }
10372
10373 static int
10374 api_set_arp_neighbor_limit (vat_main_t * vam)
10375 {
10376   unformat_input_t *i = vam->input;
10377   vl_api_set_arp_neighbor_limit_t *mp;
10378   u32 arp_nbr_limit;
10379   u8 limit_set = 0;
10380   u8 is_ipv6 = 0;
10381   int ret;
10382
10383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10384     {
10385       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10386         limit_set = 1;
10387       else if (unformat (i, "ipv6"))
10388         is_ipv6 = 1;
10389       else
10390         {
10391           clib_warning ("parse error '%U'", format_unformat_error, i);
10392           return -99;
10393         }
10394     }
10395
10396   if (limit_set == 0)
10397     {
10398       errmsg ("missing limit value");
10399       return -99;
10400     }
10401
10402   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10403
10404   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10405   mp->is_ipv6 = is_ipv6;
10406
10407   S (mp);
10408   W (ret);
10409   return ret;
10410 }
10411
10412 static int
10413 api_l2_patch_add_del (vat_main_t * vam)
10414 {
10415   unformat_input_t *i = vam->input;
10416   vl_api_l2_patch_add_del_t *mp;
10417   u32 rx_sw_if_index;
10418   u8 rx_sw_if_index_set = 0;
10419   u32 tx_sw_if_index;
10420   u8 tx_sw_if_index_set = 0;
10421   u8 is_add = 1;
10422   int ret;
10423
10424   /* Parse args required to build the message */
10425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10426     {
10427       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10428         rx_sw_if_index_set = 1;
10429       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10430         tx_sw_if_index_set = 1;
10431       else if (unformat (i, "rx"))
10432         {
10433           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10434             {
10435               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10436                             &rx_sw_if_index))
10437                 rx_sw_if_index_set = 1;
10438             }
10439           else
10440             break;
10441         }
10442       else if (unformat (i, "tx"))
10443         {
10444           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10445             {
10446               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10447                             &tx_sw_if_index))
10448                 tx_sw_if_index_set = 1;
10449             }
10450           else
10451             break;
10452         }
10453       else if (unformat (i, "del"))
10454         is_add = 0;
10455       else
10456         break;
10457     }
10458
10459   if (rx_sw_if_index_set == 0)
10460     {
10461       errmsg ("missing rx interface name or rx_sw_if_index");
10462       return -99;
10463     }
10464
10465   if (tx_sw_if_index_set == 0)
10466     {
10467       errmsg ("missing tx interface name or tx_sw_if_index");
10468       return -99;
10469     }
10470
10471   M (L2_PATCH_ADD_DEL, mp);
10472
10473   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10474   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10475   mp->is_add = is_add;
10476
10477   S (mp);
10478   W (ret);
10479   return ret;
10480 }
10481
10482 u8 is_del;
10483 u8 localsid_addr[16];
10484 u8 end_psp;
10485 u8 behavior;
10486 u32 sw_if_index;
10487 u32 vlan_index;
10488 u32 fib_table;
10489 u8 nh_addr[16];
10490
10491 static int
10492 api_sr_localsid_add_del (vat_main_t * vam)
10493 {
10494   unformat_input_t *i = vam->input;
10495   vl_api_sr_localsid_add_del_t *mp;
10496
10497   u8 is_del;
10498   ip6_address_t localsid;
10499   u8 end_psp = 0;
10500   u8 behavior = ~0;
10501   u32 sw_if_index;
10502   u32 fib_table = ~(u32) 0;
10503   ip6_address_t nh_addr6;
10504   ip4_address_t nh_addr4;
10505   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10506   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10507
10508   bool nexthop_set = 0;
10509
10510   int ret;
10511
10512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10513     {
10514       if (unformat (i, "del"))
10515         is_del = 1;
10516       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10517       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10518         nexthop_set = 1;
10519       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10520         nexthop_set = 1;
10521       else if (unformat (i, "behavior %u", &behavior));
10522       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10523       else if (unformat (i, "fib-table %u", &fib_table));
10524       else if (unformat (i, "end.psp %u", &behavior));
10525       else
10526         break;
10527     }
10528
10529   M (SR_LOCALSID_ADD_DEL, mp);
10530
10531   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10532   if (nexthop_set)
10533     {
10534       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10535       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10536     }
10537   mp->behavior = behavior;
10538   mp->sw_if_index = ntohl (sw_if_index);
10539   mp->fib_table = ntohl (fib_table);
10540   mp->end_psp = end_psp;
10541   mp->is_del = is_del;
10542
10543   S (mp);
10544   W (ret);
10545   return ret;
10546 }
10547
10548 static int
10549 api_ioam_enable (vat_main_t * vam)
10550 {
10551   unformat_input_t *input = vam->input;
10552   vl_api_ioam_enable_t *mp;
10553   u32 id = 0;
10554   int has_trace_option = 0;
10555   int has_pot_option = 0;
10556   int has_seqno_option = 0;
10557   int has_analyse_option = 0;
10558   int ret;
10559
10560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10561     {
10562       if (unformat (input, "trace"))
10563         has_trace_option = 1;
10564       else if (unformat (input, "pot"))
10565         has_pot_option = 1;
10566       else if (unformat (input, "seqno"))
10567         has_seqno_option = 1;
10568       else if (unformat (input, "analyse"))
10569         has_analyse_option = 1;
10570       else
10571         break;
10572     }
10573   M (IOAM_ENABLE, mp);
10574   mp->id = htons (id);
10575   mp->seqno = has_seqno_option;
10576   mp->analyse = has_analyse_option;
10577   mp->pot_enable = has_pot_option;
10578   mp->trace_enable = has_trace_option;
10579
10580   S (mp);
10581   W (ret);
10582   return ret;
10583 }
10584
10585
10586 static int
10587 api_ioam_disable (vat_main_t * vam)
10588 {
10589   vl_api_ioam_disable_t *mp;
10590   int ret;
10591
10592   M (IOAM_DISABLE, mp);
10593   S (mp);
10594   W (ret);
10595   return ret;
10596 }
10597
10598 #define foreach_tcp_proto_field                 \
10599 _(src_port)                                     \
10600 _(dst_port)
10601
10602 #define foreach_udp_proto_field                 \
10603 _(src_port)                                     \
10604 _(dst_port)
10605
10606 #define foreach_ip4_proto_field                 \
10607 _(src_address)                                  \
10608 _(dst_address)                                  \
10609 _(tos)                                          \
10610 _(length)                                       \
10611 _(fragment_id)                                  \
10612 _(ttl)                                          \
10613 _(protocol)                                     \
10614 _(checksum)
10615
10616 typedef struct
10617 {
10618   u16 src_port, dst_port;
10619 } tcpudp_header_t;
10620
10621 #if VPP_API_TEST_BUILTIN == 0
10622 uword
10623 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10624 {
10625   u8 **maskp = va_arg (*args, u8 **);
10626   u8 *mask = 0;
10627   u8 found_something = 0;
10628   tcp_header_t *tcp;
10629
10630 #define _(a) u8 a=0;
10631   foreach_tcp_proto_field;
10632 #undef _
10633
10634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10635     {
10636       if (0);
10637 #define _(a) else if (unformat (input, #a)) a=1;
10638       foreach_tcp_proto_field
10639 #undef _
10640         else
10641         break;
10642     }
10643
10644 #define _(a) found_something += a;
10645   foreach_tcp_proto_field;
10646 #undef _
10647
10648   if (found_something == 0)
10649     return 0;
10650
10651   vec_validate (mask, sizeof (*tcp) - 1);
10652
10653   tcp = (tcp_header_t *) mask;
10654
10655 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10656   foreach_tcp_proto_field;
10657 #undef _
10658
10659   *maskp = mask;
10660   return 1;
10661 }
10662
10663 uword
10664 unformat_udp_mask (unformat_input_t * input, va_list * args)
10665 {
10666   u8 **maskp = va_arg (*args, u8 **);
10667   u8 *mask = 0;
10668   u8 found_something = 0;
10669   udp_header_t *udp;
10670
10671 #define _(a) u8 a=0;
10672   foreach_udp_proto_field;
10673 #undef _
10674
10675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10676     {
10677       if (0);
10678 #define _(a) else if (unformat (input, #a)) a=1;
10679       foreach_udp_proto_field
10680 #undef _
10681         else
10682         break;
10683     }
10684
10685 #define _(a) found_something += a;
10686   foreach_udp_proto_field;
10687 #undef _
10688
10689   if (found_something == 0)
10690     return 0;
10691
10692   vec_validate (mask, sizeof (*udp) - 1);
10693
10694   udp = (udp_header_t *) mask;
10695
10696 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10697   foreach_udp_proto_field;
10698 #undef _
10699
10700   *maskp = mask;
10701   return 1;
10702 }
10703
10704 uword
10705 unformat_l4_mask (unformat_input_t * input, va_list * args)
10706 {
10707   u8 **maskp = va_arg (*args, u8 **);
10708   u16 src_port = 0, dst_port = 0;
10709   tcpudp_header_t *tcpudp;
10710
10711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10712     {
10713       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10714         return 1;
10715       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10716         return 1;
10717       else if (unformat (input, "src_port"))
10718         src_port = 0xFFFF;
10719       else if (unformat (input, "dst_port"))
10720         dst_port = 0xFFFF;
10721       else
10722         return 0;
10723     }
10724
10725   if (!src_port && !dst_port)
10726     return 0;
10727
10728   u8 *mask = 0;
10729   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10730
10731   tcpudp = (tcpudp_header_t *) mask;
10732   tcpudp->src_port = src_port;
10733   tcpudp->dst_port = dst_port;
10734
10735   *maskp = mask;
10736
10737   return 1;
10738 }
10739
10740 uword
10741 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10742 {
10743   u8 **maskp = va_arg (*args, u8 **);
10744   u8 *mask = 0;
10745   u8 found_something = 0;
10746   ip4_header_t *ip;
10747
10748 #define _(a) u8 a=0;
10749   foreach_ip4_proto_field;
10750 #undef _
10751   u8 version = 0;
10752   u8 hdr_length = 0;
10753
10754
10755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (input, "version"))
10758         version = 1;
10759       else if (unformat (input, "hdr_length"))
10760         hdr_length = 1;
10761       else if (unformat (input, "src"))
10762         src_address = 1;
10763       else if (unformat (input, "dst"))
10764         dst_address = 1;
10765       else if (unformat (input, "proto"))
10766         protocol = 1;
10767
10768 #define _(a) else if (unformat (input, #a)) a=1;
10769       foreach_ip4_proto_field
10770 #undef _
10771         else
10772         break;
10773     }
10774
10775 #define _(a) found_something += a;
10776   foreach_ip4_proto_field;
10777 #undef _
10778
10779   if (found_something == 0)
10780     return 0;
10781
10782   vec_validate (mask, sizeof (*ip) - 1);
10783
10784   ip = (ip4_header_t *) mask;
10785
10786 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10787   foreach_ip4_proto_field;
10788 #undef _
10789
10790   ip->ip_version_and_header_length = 0;
10791
10792   if (version)
10793     ip->ip_version_and_header_length |= 0xF0;
10794
10795   if (hdr_length)
10796     ip->ip_version_and_header_length |= 0x0F;
10797
10798   *maskp = mask;
10799   return 1;
10800 }
10801
10802 #define foreach_ip6_proto_field                 \
10803 _(src_address)                                  \
10804 _(dst_address)                                  \
10805 _(payload_length)                               \
10806 _(hop_limit)                                    \
10807 _(protocol)
10808
10809 uword
10810 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10811 {
10812   u8 **maskp = va_arg (*args, u8 **);
10813   u8 *mask = 0;
10814   u8 found_something = 0;
10815   ip6_header_t *ip;
10816   u32 ip_version_traffic_class_and_flow_label;
10817
10818 #define _(a) u8 a=0;
10819   foreach_ip6_proto_field;
10820 #undef _
10821   u8 version = 0;
10822   u8 traffic_class = 0;
10823   u8 flow_label = 0;
10824
10825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10826     {
10827       if (unformat (input, "version"))
10828         version = 1;
10829       else if (unformat (input, "traffic-class"))
10830         traffic_class = 1;
10831       else if (unformat (input, "flow-label"))
10832         flow_label = 1;
10833       else if (unformat (input, "src"))
10834         src_address = 1;
10835       else if (unformat (input, "dst"))
10836         dst_address = 1;
10837       else if (unformat (input, "proto"))
10838         protocol = 1;
10839
10840 #define _(a) else if (unformat (input, #a)) a=1;
10841       foreach_ip6_proto_field
10842 #undef _
10843         else
10844         break;
10845     }
10846
10847 #define _(a) found_something += a;
10848   foreach_ip6_proto_field;
10849 #undef _
10850
10851   if (found_something == 0)
10852     return 0;
10853
10854   vec_validate (mask, sizeof (*ip) - 1);
10855
10856   ip = (ip6_header_t *) mask;
10857
10858 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10859   foreach_ip6_proto_field;
10860 #undef _
10861
10862   ip_version_traffic_class_and_flow_label = 0;
10863
10864   if (version)
10865     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10866
10867   if (traffic_class)
10868     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10869
10870   if (flow_label)
10871     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10872
10873   ip->ip_version_traffic_class_and_flow_label =
10874     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10875
10876   *maskp = mask;
10877   return 1;
10878 }
10879
10880 uword
10881 unformat_l3_mask (unformat_input_t * input, va_list * args)
10882 {
10883   u8 **maskp = va_arg (*args, u8 **);
10884
10885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10886     {
10887       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10888         return 1;
10889       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10890         return 1;
10891       else
10892         break;
10893     }
10894   return 0;
10895 }
10896
10897 uword
10898 unformat_l2_mask (unformat_input_t * input, va_list * args)
10899 {
10900   u8 **maskp = va_arg (*args, u8 **);
10901   u8 *mask = 0;
10902   u8 src = 0;
10903   u8 dst = 0;
10904   u8 proto = 0;
10905   u8 tag1 = 0;
10906   u8 tag2 = 0;
10907   u8 ignore_tag1 = 0;
10908   u8 ignore_tag2 = 0;
10909   u8 cos1 = 0;
10910   u8 cos2 = 0;
10911   u8 dot1q = 0;
10912   u8 dot1ad = 0;
10913   int len = 14;
10914
10915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10916     {
10917       if (unformat (input, "src"))
10918         src = 1;
10919       else if (unformat (input, "dst"))
10920         dst = 1;
10921       else if (unformat (input, "proto"))
10922         proto = 1;
10923       else if (unformat (input, "tag1"))
10924         tag1 = 1;
10925       else if (unformat (input, "tag2"))
10926         tag2 = 1;
10927       else if (unformat (input, "ignore-tag1"))
10928         ignore_tag1 = 1;
10929       else if (unformat (input, "ignore-tag2"))
10930         ignore_tag2 = 1;
10931       else if (unformat (input, "cos1"))
10932         cos1 = 1;
10933       else if (unformat (input, "cos2"))
10934         cos2 = 1;
10935       else if (unformat (input, "dot1q"))
10936         dot1q = 1;
10937       else if (unformat (input, "dot1ad"))
10938         dot1ad = 1;
10939       else
10940         break;
10941     }
10942   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10943        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10944     return 0;
10945
10946   if (tag1 || ignore_tag1 || cos1 || dot1q)
10947     len = 18;
10948   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10949     len = 22;
10950
10951   vec_validate (mask, len - 1);
10952
10953   if (dst)
10954     clib_memset (mask, 0xff, 6);
10955
10956   if (src)
10957     clib_memset (mask + 6, 0xff, 6);
10958
10959   if (tag2 || dot1ad)
10960     {
10961       /* inner vlan tag */
10962       if (tag2)
10963         {
10964           mask[19] = 0xff;
10965           mask[18] = 0x0f;
10966         }
10967       if (cos2)
10968         mask[18] |= 0xe0;
10969       if (proto)
10970         mask[21] = mask[20] = 0xff;
10971       if (tag1)
10972         {
10973           mask[15] = 0xff;
10974           mask[14] = 0x0f;
10975         }
10976       if (cos1)
10977         mask[14] |= 0xe0;
10978       *maskp = mask;
10979       return 1;
10980     }
10981   if (tag1 | dot1q)
10982     {
10983       if (tag1)
10984         {
10985           mask[15] = 0xff;
10986           mask[14] = 0x0f;
10987         }
10988       if (cos1)
10989         mask[14] |= 0xe0;
10990       if (proto)
10991         mask[16] = mask[17] = 0xff;
10992
10993       *maskp = mask;
10994       return 1;
10995     }
10996   if (cos2)
10997     mask[18] |= 0xe0;
10998   if (cos1)
10999     mask[14] |= 0xe0;
11000   if (proto)
11001     mask[12] = mask[13] = 0xff;
11002
11003   *maskp = mask;
11004   return 1;
11005 }
11006
11007 uword
11008 unformat_classify_mask (unformat_input_t * input, va_list * args)
11009 {
11010   u8 **maskp = va_arg (*args, u8 **);
11011   u32 *skipp = va_arg (*args, u32 *);
11012   u32 *matchp = va_arg (*args, u32 *);
11013   u32 match;
11014   u8 *mask = 0;
11015   u8 *l2 = 0;
11016   u8 *l3 = 0;
11017   u8 *l4 = 0;
11018   int i;
11019
11020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11021     {
11022       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11023         ;
11024       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11025         ;
11026       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11027         ;
11028       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11029         ;
11030       else
11031         break;
11032     }
11033
11034   if (l4 && !l3)
11035     {
11036       vec_free (mask);
11037       vec_free (l2);
11038       vec_free (l4);
11039       return 0;
11040     }
11041
11042   if (mask || l2 || l3 || l4)
11043     {
11044       if (l2 || l3 || l4)
11045         {
11046           /* "With a free Ethernet header in every package" */
11047           if (l2 == 0)
11048             vec_validate (l2, 13);
11049           mask = l2;
11050           if (vec_len (l3))
11051             {
11052               vec_append (mask, l3);
11053               vec_free (l3);
11054             }
11055           if (vec_len (l4))
11056             {
11057               vec_append (mask, l4);
11058               vec_free (l4);
11059             }
11060         }
11061
11062       /* Scan forward looking for the first significant mask octet */
11063       for (i = 0; i < vec_len (mask); i++)
11064         if (mask[i])
11065           break;
11066
11067       /* compute (skip, match) params */
11068       *skipp = i / sizeof (u32x4);
11069       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11070
11071       /* Pad mask to an even multiple of the vector size */
11072       while (vec_len (mask) % sizeof (u32x4))
11073         vec_add1 (mask, 0);
11074
11075       match = vec_len (mask) / sizeof (u32x4);
11076
11077       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11078         {
11079           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11080           if (*tmp || *(tmp + 1))
11081             break;
11082           match--;
11083         }
11084       if (match == 0)
11085         clib_warning ("BUG: match 0");
11086
11087       _vec_len (mask) = match * sizeof (u32x4);
11088
11089       *matchp = match;
11090       *maskp = mask;
11091
11092       return 1;
11093     }
11094
11095   return 0;
11096 }
11097 #endif /* VPP_API_TEST_BUILTIN */
11098
11099 #define foreach_l2_next                         \
11100 _(drop, DROP)                                   \
11101 _(ethernet, ETHERNET_INPUT)                     \
11102 _(ip4, IP4_INPUT)                               \
11103 _(ip6, IP6_INPUT)
11104
11105 uword
11106 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11107 {
11108   u32 *miss_next_indexp = va_arg (*args, u32 *);
11109   u32 next_index = 0;
11110   u32 tmp;
11111
11112 #define _(n,N) \
11113   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11114   foreach_l2_next;
11115 #undef _
11116
11117   if (unformat (input, "%d", &tmp))
11118     {
11119       next_index = tmp;
11120       goto out;
11121     }
11122
11123   return 0;
11124
11125 out:
11126   *miss_next_indexp = next_index;
11127   return 1;
11128 }
11129
11130 #define foreach_ip_next                         \
11131 _(drop, DROP)                                   \
11132 _(local, LOCAL)                                 \
11133 _(rewrite, REWRITE)
11134
11135 uword
11136 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11137 {
11138   u32 *miss_next_indexp = va_arg (*args, u32 *);
11139   u32 next_index = 0;
11140   u32 tmp;
11141
11142 #define _(n,N) \
11143   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11144   foreach_ip_next;
11145 #undef _
11146
11147   if (unformat (input, "%d", &tmp))
11148     {
11149       next_index = tmp;
11150       goto out;
11151     }
11152
11153   return 0;
11154
11155 out:
11156   *miss_next_indexp = next_index;
11157   return 1;
11158 }
11159
11160 #define foreach_acl_next                        \
11161 _(deny, DENY)
11162
11163 uword
11164 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11165 {
11166   u32 *miss_next_indexp = va_arg (*args, u32 *);
11167   u32 next_index = 0;
11168   u32 tmp;
11169
11170 #define _(n,N) \
11171   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11172   foreach_acl_next;
11173 #undef _
11174
11175   if (unformat (input, "permit"))
11176     {
11177       next_index = ~0;
11178       goto out;
11179     }
11180   else if (unformat (input, "%d", &tmp))
11181     {
11182       next_index = tmp;
11183       goto out;
11184     }
11185
11186   return 0;
11187
11188 out:
11189   *miss_next_indexp = next_index;
11190   return 1;
11191 }
11192
11193 uword
11194 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11195 {
11196   u32 *r = va_arg (*args, u32 *);
11197
11198   if (unformat (input, "conform-color"))
11199     *r = POLICE_CONFORM;
11200   else if (unformat (input, "exceed-color"))
11201     *r = POLICE_EXCEED;
11202   else
11203     return 0;
11204
11205   return 1;
11206 }
11207
11208 static int
11209 api_classify_add_del_table (vat_main_t * vam)
11210 {
11211   unformat_input_t *i = vam->input;
11212   vl_api_classify_add_del_table_t *mp;
11213
11214   u32 nbuckets = 2;
11215   u32 skip = ~0;
11216   u32 match = ~0;
11217   int is_add = 1;
11218   int del_chain = 0;
11219   u32 table_index = ~0;
11220   u32 next_table_index = ~0;
11221   u32 miss_next_index = ~0;
11222   u32 memory_size = 32 << 20;
11223   u8 *mask = 0;
11224   u32 current_data_flag = 0;
11225   int current_data_offset = 0;
11226   int ret;
11227
11228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11229     {
11230       if (unformat (i, "del"))
11231         is_add = 0;
11232       else if (unformat (i, "del-chain"))
11233         {
11234           is_add = 0;
11235           del_chain = 1;
11236         }
11237       else if (unformat (i, "buckets %d", &nbuckets))
11238         ;
11239       else if (unformat (i, "memory_size %d", &memory_size))
11240         ;
11241       else if (unformat (i, "skip %d", &skip))
11242         ;
11243       else if (unformat (i, "match %d", &match))
11244         ;
11245       else if (unformat (i, "table %d", &table_index))
11246         ;
11247       else if (unformat (i, "mask %U", unformat_classify_mask,
11248                          &mask, &skip, &match))
11249         ;
11250       else if (unformat (i, "next-table %d", &next_table_index))
11251         ;
11252       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11253                          &miss_next_index))
11254         ;
11255       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11256                          &miss_next_index))
11257         ;
11258       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11259                          &miss_next_index))
11260         ;
11261       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11262         ;
11263       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11264         ;
11265       else
11266         break;
11267     }
11268
11269   if (is_add && mask == 0)
11270     {
11271       errmsg ("Mask required");
11272       return -99;
11273     }
11274
11275   if (is_add && skip == ~0)
11276     {
11277       errmsg ("skip count required");
11278       return -99;
11279     }
11280
11281   if (is_add && match == ~0)
11282     {
11283       errmsg ("match count required");
11284       return -99;
11285     }
11286
11287   if (!is_add && table_index == ~0)
11288     {
11289       errmsg ("table index required for delete");
11290       return -99;
11291     }
11292
11293   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11294
11295   mp->is_add = is_add;
11296   mp->del_chain = del_chain;
11297   mp->table_index = ntohl (table_index);
11298   mp->nbuckets = ntohl (nbuckets);
11299   mp->memory_size = ntohl (memory_size);
11300   mp->skip_n_vectors = ntohl (skip);
11301   mp->match_n_vectors = ntohl (match);
11302   mp->next_table_index = ntohl (next_table_index);
11303   mp->miss_next_index = ntohl (miss_next_index);
11304   mp->current_data_flag = ntohl (current_data_flag);
11305   mp->current_data_offset = ntohl (current_data_offset);
11306   mp->mask_len = ntohl (vec_len (mask));
11307   clib_memcpy (mp->mask, mask, vec_len (mask));
11308
11309   vec_free (mask);
11310
11311   S (mp);
11312   W (ret);
11313   return ret;
11314 }
11315
11316 #if VPP_API_TEST_BUILTIN == 0
11317 uword
11318 unformat_l4_match (unformat_input_t * input, va_list * args)
11319 {
11320   u8 **matchp = va_arg (*args, u8 **);
11321
11322   u8 *proto_header = 0;
11323   int src_port = 0;
11324   int dst_port = 0;
11325
11326   tcpudp_header_t h;
11327
11328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11329     {
11330       if (unformat (input, "src_port %d", &src_port))
11331         ;
11332       else if (unformat (input, "dst_port %d", &dst_port))
11333         ;
11334       else
11335         return 0;
11336     }
11337
11338   h.src_port = clib_host_to_net_u16 (src_port);
11339   h.dst_port = clib_host_to_net_u16 (dst_port);
11340   vec_validate (proto_header, sizeof (h) - 1);
11341   memcpy (proto_header, &h, sizeof (h));
11342
11343   *matchp = proto_header;
11344
11345   return 1;
11346 }
11347
11348 uword
11349 unformat_ip4_match (unformat_input_t * input, va_list * args)
11350 {
11351   u8 **matchp = va_arg (*args, u8 **);
11352   u8 *match = 0;
11353   ip4_header_t *ip;
11354   int version = 0;
11355   u32 version_val;
11356   int hdr_length = 0;
11357   u32 hdr_length_val;
11358   int src = 0, dst = 0;
11359   ip4_address_t src_val, dst_val;
11360   int proto = 0;
11361   u32 proto_val;
11362   int tos = 0;
11363   u32 tos_val;
11364   int length = 0;
11365   u32 length_val;
11366   int fragment_id = 0;
11367   u32 fragment_id_val;
11368   int ttl = 0;
11369   int ttl_val;
11370   int checksum = 0;
11371   u32 checksum_val;
11372
11373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11374     {
11375       if (unformat (input, "version %d", &version_val))
11376         version = 1;
11377       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11378         hdr_length = 1;
11379       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11380         src = 1;
11381       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11382         dst = 1;
11383       else if (unformat (input, "proto %d", &proto_val))
11384         proto = 1;
11385       else if (unformat (input, "tos %d", &tos_val))
11386         tos = 1;
11387       else if (unformat (input, "length %d", &length_val))
11388         length = 1;
11389       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11390         fragment_id = 1;
11391       else if (unformat (input, "ttl %d", &ttl_val))
11392         ttl = 1;
11393       else if (unformat (input, "checksum %d", &checksum_val))
11394         checksum = 1;
11395       else
11396         break;
11397     }
11398
11399   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11400       + ttl + checksum == 0)
11401     return 0;
11402
11403   /*
11404    * Aligned because we use the real comparison functions
11405    */
11406   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11407
11408   ip = (ip4_header_t *) match;
11409
11410   /* These are realistically matched in practice */
11411   if (src)
11412     ip->src_address.as_u32 = src_val.as_u32;
11413
11414   if (dst)
11415     ip->dst_address.as_u32 = dst_val.as_u32;
11416
11417   if (proto)
11418     ip->protocol = proto_val;
11419
11420
11421   /* These are not, but they're included for completeness */
11422   if (version)
11423     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11424
11425   if (hdr_length)
11426     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11427
11428   if (tos)
11429     ip->tos = tos_val;
11430
11431   if (length)
11432     ip->length = clib_host_to_net_u16 (length_val);
11433
11434   if (ttl)
11435     ip->ttl = ttl_val;
11436
11437   if (checksum)
11438     ip->checksum = clib_host_to_net_u16 (checksum_val);
11439
11440   *matchp = match;
11441   return 1;
11442 }
11443
11444 uword
11445 unformat_ip6_match (unformat_input_t * input, va_list * args)
11446 {
11447   u8 **matchp = va_arg (*args, u8 **);
11448   u8 *match = 0;
11449   ip6_header_t *ip;
11450   int version = 0;
11451   u32 version_val;
11452   u8 traffic_class = 0;
11453   u32 traffic_class_val = 0;
11454   u8 flow_label = 0;
11455   u8 flow_label_val;
11456   int src = 0, dst = 0;
11457   ip6_address_t src_val, dst_val;
11458   int proto = 0;
11459   u32 proto_val;
11460   int payload_length = 0;
11461   u32 payload_length_val;
11462   int hop_limit = 0;
11463   int hop_limit_val;
11464   u32 ip_version_traffic_class_and_flow_label;
11465
11466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11467     {
11468       if (unformat (input, "version %d", &version_val))
11469         version = 1;
11470       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11471         traffic_class = 1;
11472       else if (unformat (input, "flow_label %d", &flow_label_val))
11473         flow_label = 1;
11474       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11475         src = 1;
11476       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11477         dst = 1;
11478       else if (unformat (input, "proto %d", &proto_val))
11479         proto = 1;
11480       else if (unformat (input, "payload_length %d", &payload_length_val))
11481         payload_length = 1;
11482       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11483         hop_limit = 1;
11484       else
11485         break;
11486     }
11487
11488   if (version + traffic_class + flow_label + src + dst + proto +
11489       payload_length + hop_limit == 0)
11490     return 0;
11491
11492   /*
11493    * Aligned because we use the real comparison functions
11494    */
11495   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11496
11497   ip = (ip6_header_t *) match;
11498
11499   if (src)
11500     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11501
11502   if (dst)
11503     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11504
11505   if (proto)
11506     ip->protocol = proto_val;
11507
11508   ip_version_traffic_class_and_flow_label = 0;
11509
11510   if (version)
11511     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11512
11513   if (traffic_class)
11514     ip_version_traffic_class_and_flow_label |=
11515       (traffic_class_val & 0xFF) << 20;
11516
11517   if (flow_label)
11518     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11519
11520   ip->ip_version_traffic_class_and_flow_label =
11521     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11522
11523   if (payload_length)
11524     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11525
11526   if (hop_limit)
11527     ip->hop_limit = hop_limit_val;
11528
11529   *matchp = match;
11530   return 1;
11531 }
11532
11533 uword
11534 unformat_l3_match (unformat_input_t * input, va_list * args)
11535 {
11536   u8 **matchp = va_arg (*args, u8 **);
11537
11538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11539     {
11540       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11541         return 1;
11542       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11543         return 1;
11544       else
11545         break;
11546     }
11547   return 0;
11548 }
11549
11550 uword
11551 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11552 {
11553   u8 *tagp = va_arg (*args, u8 *);
11554   u32 tag;
11555
11556   if (unformat (input, "%d", &tag))
11557     {
11558       tagp[0] = (tag >> 8) & 0x0F;
11559       tagp[1] = tag & 0xFF;
11560       return 1;
11561     }
11562
11563   return 0;
11564 }
11565
11566 uword
11567 unformat_l2_match (unformat_input_t * input, va_list * args)
11568 {
11569   u8 **matchp = va_arg (*args, u8 **);
11570   u8 *match = 0;
11571   u8 src = 0;
11572   u8 src_val[6];
11573   u8 dst = 0;
11574   u8 dst_val[6];
11575   u8 proto = 0;
11576   u16 proto_val;
11577   u8 tag1 = 0;
11578   u8 tag1_val[2];
11579   u8 tag2 = 0;
11580   u8 tag2_val[2];
11581   int len = 14;
11582   u8 ignore_tag1 = 0;
11583   u8 ignore_tag2 = 0;
11584   u8 cos1 = 0;
11585   u8 cos2 = 0;
11586   u32 cos1_val = 0;
11587   u32 cos2_val = 0;
11588
11589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11590     {
11591       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11592         src = 1;
11593       else
11594         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11595         dst = 1;
11596       else if (unformat (input, "proto %U",
11597                          unformat_ethernet_type_host_byte_order, &proto_val))
11598         proto = 1;
11599       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11600         tag1 = 1;
11601       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11602         tag2 = 1;
11603       else if (unformat (input, "ignore-tag1"))
11604         ignore_tag1 = 1;
11605       else if (unformat (input, "ignore-tag2"))
11606         ignore_tag2 = 1;
11607       else if (unformat (input, "cos1 %d", &cos1_val))
11608         cos1 = 1;
11609       else if (unformat (input, "cos2 %d", &cos2_val))
11610         cos2 = 1;
11611       else
11612         break;
11613     }
11614   if ((src + dst + proto + tag1 + tag2 +
11615        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11616     return 0;
11617
11618   if (tag1 || ignore_tag1 || cos1)
11619     len = 18;
11620   if (tag2 || ignore_tag2 || cos2)
11621     len = 22;
11622
11623   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11624
11625   if (dst)
11626     clib_memcpy (match, dst_val, 6);
11627
11628   if (src)
11629     clib_memcpy (match + 6, src_val, 6);
11630
11631   if (tag2)
11632     {
11633       /* inner vlan tag */
11634       match[19] = tag2_val[1];
11635       match[18] = tag2_val[0];
11636       if (cos2)
11637         match[18] |= (cos2_val & 0x7) << 5;
11638       if (proto)
11639         {
11640           match[21] = proto_val & 0xff;
11641           match[20] = proto_val >> 8;
11642         }
11643       if (tag1)
11644         {
11645           match[15] = tag1_val[1];
11646           match[14] = tag1_val[0];
11647         }
11648       if (cos1)
11649         match[14] |= (cos1_val & 0x7) << 5;
11650       *matchp = match;
11651       return 1;
11652     }
11653   if (tag1)
11654     {
11655       match[15] = tag1_val[1];
11656       match[14] = tag1_val[0];
11657       if (proto)
11658         {
11659           match[17] = proto_val & 0xff;
11660           match[16] = proto_val >> 8;
11661         }
11662       if (cos1)
11663         match[14] |= (cos1_val & 0x7) << 5;
11664
11665       *matchp = match;
11666       return 1;
11667     }
11668   if (cos2)
11669     match[18] |= (cos2_val & 0x7) << 5;
11670   if (cos1)
11671     match[14] |= (cos1_val & 0x7) << 5;
11672   if (proto)
11673     {
11674       match[13] = proto_val & 0xff;
11675       match[12] = proto_val >> 8;
11676     }
11677
11678   *matchp = match;
11679   return 1;
11680 }
11681
11682 uword
11683 unformat_qos_source (unformat_input_t * input, va_list * args)
11684 {
11685   int *qs = va_arg (*args, int *);
11686
11687   if (unformat (input, "ip"))
11688     *qs = QOS_SOURCE_IP;
11689   else if (unformat (input, "mpls"))
11690     *qs = QOS_SOURCE_MPLS;
11691   else if (unformat (input, "ext"))
11692     *qs = QOS_SOURCE_EXT;
11693   else if (unformat (input, "vlan"))
11694     *qs = QOS_SOURCE_VLAN;
11695   else
11696     return 0;
11697
11698   return 1;
11699 }
11700 #endif
11701
11702 uword
11703 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11704 {
11705   u8 **matchp = va_arg (*args, u8 **);
11706   u32 skip_n_vectors = va_arg (*args, u32);
11707   u32 match_n_vectors = va_arg (*args, u32);
11708
11709   u8 *match = 0;
11710   u8 *l2 = 0;
11711   u8 *l3 = 0;
11712   u8 *l4 = 0;
11713
11714   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11715     {
11716       if (unformat (input, "hex %U", unformat_hex_string, &match))
11717         ;
11718       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11719         ;
11720       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11721         ;
11722       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11723         ;
11724       else
11725         break;
11726     }
11727
11728   if (l4 && !l3)
11729     {
11730       vec_free (match);
11731       vec_free (l2);
11732       vec_free (l4);
11733       return 0;
11734     }
11735
11736   if (match || l2 || l3 || l4)
11737     {
11738       if (l2 || l3 || l4)
11739         {
11740           /* "Win a free Ethernet header in every packet" */
11741           if (l2 == 0)
11742             vec_validate_aligned (l2, 13, sizeof (u32x4));
11743           match = l2;
11744           if (vec_len (l3))
11745             {
11746               vec_append_aligned (match, l3, sizeof (u32x4));
11747               vec_free (l3);
11748             }
11749           if (vec_len (l4))
11750             {
11751               vec_append_aligned (match, l4, sizeof (u32x4));
11752               vec_free (l4);
11753             }
11754         }
11755
11756       /* Make sure the vector is big enough even if key is all 0's */
11757       vec_validate_aligned
11758         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11759          sizeof (u32x4));
11760
11761       /* Set size, include skipped vectors */
11762       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11763
11764       *matchp = match;
11765
11766       return 1;
11767     }
11768
11769   return 0;
11770 }
11771
11772 static int
11773 api_classify_add_del_session (vat_main_t * vam)
11774 {
11775   unformat_input_t *i = vam->input;
11776   vl_api_classify_add_del_session_t *mp;
11777   int is_add = 1;
11778   u32 table_index = ~0;
11779   u32 hit_next_index = ~0;
11780   u32 opaque_index = ~0;
11781   u8 *match = 0;
11782   i32 advance = 0;
11783   u32 skip_n_vectors = 0;
11784   u32 match_n_vectors = 0;
11785   u32 action = 0;
11786   u32 metadata = 0;
11787   int ret;
11788
11789   /*
11790    * Warning: you have to supply skip_n and match_n
11791    * because the API client cant simply look at the classify
11792    * table object.
11793    */
11794
11795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11796     {
11797       if (unformat (i, "del"))
11798         is_add = 0;
11799       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11800                          &hit_next_index))
11801         ;
11802       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11803                          &hit_next_index))
11804         ;
11805       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11806                          &hit_next_index))
11807         ;
11808       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11809         ;
11810       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11811         ;
11812       else if (unformat (i, "opaque-index %d", &opaque_index))
11813         ;
11814       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11815         ;
11816       else if (unformat (i, "match_n %d", &match_n_vectors))
11817         ;
11818       else if (unformat (i, "match %U", api_unformat_classify_match,
11819                          &match, skip_n_vectors, match_n_vectors))
11820         ;
11821       else if (unformat (i, "advance %d", &advance))
11822         ;
11823       else if (unformat (i, "table-index %d", &table_index))
11824         ;
11825       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11826         action = 1;
11827       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11828         action = 2;
11829       else if (unformat (i, "action %d", &action))
11830         ;
11831       else if (unformat (i, "metadata %d", &metadata))
11832         ;
11833       else
11834         break;
11835     }
11836
11837   if (table_index == ~0)
11838     {
11839       errmsg ("Table index required");
11840       return -99;
11841     }
11842
11843   if (is_add && match == 0)
11844     {
11845       errmsg ("Match value required");
11846       return -99;
11847     }
11848
11849   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11850
11851   mp->is_add = is_add;
11852   mp->table_index = ntohl (table_index);
11853   mp->hit_next_index = ntohl (hit_next_index);
11854   mp->opaque_index = ntohl (opaque_index);
11855   mp->advance = ntohl (advance);
11856   mp->action = action;
11857   mp->metadata = ntohl (metadata);
11858   mp->match_len = ntohl (vec_len (match));
11859   clib_memcpy (mp->match, match, vec_len (match));
11860   vec_free (match);
11861
11862   S (mp);
11863   W (ret);
11864   return ret;
11865 }
11866
11867 static int
11868 api_classify_set_interface_ip_table (vat_main_t * vam)
11869 {
11870   unformat_input_t *i = vam->input;
11871   vl_api_classify_set_interface_ip_table_t *mp;
11872   u32 sw_if_index;
11873   int sw_if_index_set;
11874   u32 table_index = ~0;
11875   u8 is_ipv6 = 0;
11876   int ret;
11877
11878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11879     {
11880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11881         sw_if_index_set = 1;
11882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11883         sw_if_index_set = 1;
11884       else if (unformat (i, "table %d", &table_index))
11885         ;
11886       else
11887         {
11888           clib_warning ("parse error '%U'", format_unformat_error, i);
11889           return -99;
11890         }
11891     }
11892
11893   if (sw_if_index_set == 0)
11894     {
11895       errmsg ("missing interface name or sw_if_index");
11896       return -99;
11897     }
11898
11899
11900   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11901
11902   mp->sw_if_index = ntohl (sw_if_index);
11903   mp->table_index = ntohl (table_index);
11904   mp->is_ipv6 = is_ipv6;
11905
11906   S (mp);
11907   W (ret);
11908   return ret;
11909 }
11910
11911 static int
11912 api_classify_set_interface_l2_tables (vat_main_t * vam)
11913 {
11914   unformat_input_t *i = vam->input;
11915   vl_api_classify_set_interface_l2_tables_t *mp;
11916   u32 sw_if_index;
11917   int sw_if_index_set;
11918   u32 ip4_table_index = ~0;
11919   u32 ip6_table_index = ~0;
11920   u32 other_table_index = ~0;
11921   u32 is_input = 1;
11922   int ret;
11923
11924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11925     {
11926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11927         sw_if_index_set = 1;
11928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11929         sw_if_index_set = 1;
11930       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11931         ;
11932       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11933         ;
11934       else if (unformat (i, "other-table %d", &other_table_index))
11935         ;
11936       else if (unformat (i, "is-input %d", &is_input))
11937         ;
11938       else
11939         {
11940           clib_warning ("parse error '%U'", format_unformat_error, i);
11941           return -99;
11942         }
11943     }
11944
11945   if (sw_if_index_set == 0)
11946     {
11947       errmsg ("missing interface name or sw_if_index");
11948       return -99;
11949     }
11950
11951
11952   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11953
11954   mp->sw_if_index = ntohl (sw_if_index);
11955   mp->ip4_table_index = ntohl (ip4_table_index);
11956   mp->ip6_table_index = ntohl (ip6_table_index);
11957   mp->other_table_index = ntohl (other_table_index);
11958   mp->is_input = (u8) is_input;
11959
11960   S (mp);
11961   W (ret);
11962   return ret;
11963 }
11964
11965 static int
11966 api_set_ipfix_exporter (vat_main_t * vam)
11967 {
11968   unformat_input_t *i = vam->input;
11969   vl_api_set_ipfix_exporter_t *mp;
11970   ip4_address_t collector_address;
11971   u8 collector_address_set = 0;
11972   u32 collector_port = ~0;
11973   ip4_address_t src_address;
11974   u8 src_address_set = 0;
11975   u32 vrf_id = ~0;
11976   u32 path_mtu = ~0;
11977   u32 template_interval = ~0;
11978   u8 udp_checksum = 0;
11979   int ret;
11980
11981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11982     {
11983       if (unformat (i, "collector_address %U", unformat_ip4_address,
11984                     &collector_address))
11985         collector_address_set = 1;
11986       else if (unformat (i, "collector_port %d", &collector_port))
11987         ;
11988       else if (unformat (i, "src_address %U", unformat_ip4_address,
11989                          &src_address))
11990         src_address_set = 1;
11991       else if (unformat (i, "vrf_id %d", &vrf_id))
11992         ;
11993       else if (unformat (i, "path_mtu %d", &path_mtu))
11994         ;
11995       else if (unformat (i, "template_interval %d", &template_interval))
11996         ;
11997       else if (unformat (i, "udp_checksum"))
11998         udp_checksum = 1;
11999       else
12000         break;
12001     }
12002
12003   if (collector_address_set == 0)
12004     {
12005       errmsg ("collector_address required");
12006       return -99;
12007     }
12008
12009   if (src_address_set == 0)
12010     {
12011       errmsg ("src_address required");
12012       return -99;
12013     }
12014
12015   M (SET_IPFIX_EXPORTER, mp);
12016
12017   memcpy (mp->collector_address, collector_address.data,
12018           sizeof (collector_address.data));
12019   mp->collector_port = htons ((u16) collector_port);
12020   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12021   mp->vrf_id = htonl (vrf_id);
12022   mp->path_mtu = htonl (path_mtu);
12023   mp->template_interval = htonl (template_interval);
12024   mp->udp_checksum = udp_checksum;
12025
12026   S (mp);
12027   W (ret);
12028   return ret;
12029 }
12030
12031 static int
12032 api_set_ipfix_classify_stream (vat_main_t * vam)
12033 {
12034   unformat_input_t *i = vam->input;
12035   vl_api_set_ipfix_classify_stream_t *mp;
12036   u32 domain_id = 0;
12037   u32 src_port = UDP_DST_PORT_ipfix;
12038   int ret;
12039
12040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12041     {
12042       if (unformat (i, "domain %d", &domain_id))
12043         ;
12044       else if (unformat (i, "src_port %d", &src_port))
12045         ;
12046       else
12047         {
12048           errmsg ("unknown input `%U'", format_unformat_error, i);
12049           return -99;
12050         }
12051     }
12052
12053   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12054
12055   mp->domain_id = htonl (domain_id);
12056   mp->src_port = htons ((u16) src_port);
12057
12058   S (mp);
12059   W (ret);
12060   return ret;
12061 }
12062
12063 static int
12064 api_ipfix_classify_table_add_del (vat_main_t * vam)
12065 {
12066   unformat_input_t *i = vam->input;
12067   vl_api_ipfix_classify_table_add_del_t *mp;
12068   int is_add = -1;
12069   u32 classify_table_index = ~0;
12070   u8 ip_version = 0;
12071   u8 transport_protocol = 255;
12072   int ret;
12073
12074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12075     {
12076       if (unformat (i, "add"))
12077         is_add = 1;
12078       else if (unformat (i, "del"))
12079         is_add = 0;
12080       else if (unformat (i, "table %d", &classify_table_index))
12081         ;
12082       else if (unformat (i, "ip4"))
12083         ip_version = 4;
12084       else if (unformat (i, "ip6"))
12085         ip_version = 6;
12086       else if (unformat (i, "tcp"))
12087         transport_protocol = 6;
12088       else if (unformat (i, "udp"))
12089         transport_protocol = 17;
12090       else
12091         {
12092           errmsg ("unknown input `%U'", format_unformat_error, i);
12093           return -99;
12094         }
12095     }
12096
12097   if (is_add == -1)
12098     {
12099       errmsg ("expecting: add|del");
12100       return -99;
12101     }
12102   if (classify_table_index == ~0)
12103     {
12104       errmsg ("classifier table not specified");
12105       return -99;
12106     }
12107   if (ip_version == 0)
12108     {
12109       errmsg ("IP version not specified");
12110       return -99;
12111     }
12112
12113   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12114
12115   mp->is_add = is_add;
12116   mp->table_id = htonl (classify_table_index);
12117   mp->ip_version = ip_version;
12118   mp->transport_protocol = transport_protocol;
12119
12120   S (mp);
12121   W (ret);
12122   return ret;
12123 }
12124
12125 static int
12126 api_get_node_index (vat_main_t * vam)
12127 {
12128   unformat_input_t *i = vam->input;
12129   vl_api_get_node_index_t *mp;
12130   u8 *name = 0;
12131   int ret;
12132
12133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12134     {
12135       if (unformat (i, "node %s", &name))
12136         ;
12137       else
12138         break;
12139     }
12140   if (name == 0)
12141     {
12142       errmsg ("node name required");
12143       return -99;
12144     }
12145   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12146     {
12147       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12148       return -99;
12149     }
12150
12151   M (GET_NODE_INDEX, mp);
12152   clib_memcpy (mp->node_name, name, vec_len (name));
12153   vec_free (name);
12154
12155   S (mp);
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_get_next_index (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   vl_api_get_next_index_t *mp;
12165   u8 *node_name = 0, *next_node_name = 0;
12166   int ret;
12167
12168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12169     {
12170       if (unformat (i, "node-name %s", &node_name))
12171         ;
12172       else if (unformat (i, "next-node-name %s", &next_node_name))
12173         break;
12174     }
12175
12176   if (node_name == 0)
12177     {
12178       errmsg ("node name required");
12179       return -99;
12180     }
12181   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12182     {
12183       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12184       return -99;
12185     }
12186
12187   if (next_node_name == 0)
12188     {
12189       errmsg ("next node name required");
12190       return -99;
12191     }
12192   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12193     {
12194       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12195       return -99;
12196     }
12197
12198   M (GET_NEXT_INDEX, mp);
12199   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12200   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12201   vec_free (node_name);
12202   vec_free (next_node_name);
12203
12204   S (mp);
12205   W (ret);
12206   return ret;
12207 }
12208
12209 static int
12210 api_add_node_next (vat_main_t * vam)
12211 {
12212   unformat_input_t *i = vam->input;
12213   vl_api_add_node_next_t *mp;
12214   u8 *name = 0;
12215   u8 *next = 0;
12216   int ret;
12217
12218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12219     {
12220       if (unformat (i, "node %s", &name))
12221         ;
12222       else if (unformat (i, "next %s", &next))
12223         ;
12224       else
12225         break;
12226     }
12227   if (name == 0)
12228     {
12229       errmsg ("node name required");
12230       return -99;
12231     }
12232   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12233     {
12234       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12235       return -99;
12236     }
12237   if (next == 0)
12238     {
12239       errmsg ("next node required");
12240       return -99;
12241     }
12242   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12243     {
12244       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12245       return -99;
12246     }
12247
12248   M (ADD_NODE_NEXT, mp);
12249   clib_memcpy (mp->node_name, name, vec_len (name));
12250   clib_memcpy (mp->next_name, next, vec_len (next));
12251   vec_free (name);
12252   vec_free (next);
12253
12254   S (mp);
12255   W (ret);
12256   return ret;
12257 }
12258
12259 static int
12260 api_l2tpv3_create_tunnel (vat_main_t * vam)
12261 {
12262   unformat_input_t *i = vam->input;
12263   ip6_address_t client_address, our_address;
12264   int client_address_set = 0;
12265   int our_address_set = 0;
12266   u32 local_session_id = 0;
12267   u32 remote_session_id = 0;
12268   u64 local_cookie = 0;
12269   u64 remote_cookie = 0;
12270   u8 l2_sublayer_present = 0;
12271   vl_api_l2tpv3_create_tunnel_t *mp;
12272   int ret;
12273
12274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12275     {
12276       if (unformat (i, "client_address %U", unformat_ip6_address,
12277                     &client_address))
12278         client_address_set = 1;
12279       else if (unformat (i, "our_address %U", unformat_ip6_address,
12280                          &our_address))
12281         our_address_set = 1;
12282       else if (unformat (i, "local_session_id %d", &local_session_id))
12283         ;
12284       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12285         ;
12286       else if (unformat (i, "local_cookie %lld", &local_cookie))
12287         ;
12288       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12289         ;
12290       else if (unformat (i, "l2-sublayer-present"))
12291         l2_sublayer_present = 1;
12292       else
12293         break;
12294     }
12295
12296   if (client_address_set == 0)
12297     {
12298       errmsg ("client_address required");
12299       return -99;
12300     }
12301
12302   if (our_address_set == 0)
12303     {
12304       errmsg ("our_address required");
12305       return -99;
12306     }
12307
12308   M (L2TPV3_CREATE_TUNNEL, mp);
12309
12310   clib_memcpy (mp->client_address, client_address.as_u8,
12311                sizeof (mp->client_address));
12312
12313   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12314
12315   mp->local_session_id = ntohl (local_session_id);
12316   mp->remote_session_id = ntohl (remote_session_id);
12317   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12318   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12319   mp->l2_sublayer_present = l2_sublayer_present;
12320   mp->is_ipv6 = 1;
12321
12322   S (mp);
12323   W (ret);
12324   return ret;
12325 }
12326
12327 static int
12328 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12329 {
12330   unformat_input_t *i = vam->input;
12331   u32 sw_if_index;
12332   u8 sw_if_index_set = 0;
12333   u64 new_local_cookie = 0;
12334   u64 new_remote_cookie = 0;
12335   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12336   int ret;
12337
12338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12339     {
12340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12341         sw_if_index_set = 1;
12342       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12343         sw_if_index_set = 1;
12344       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12345         ;
12346       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12347         ;
12348       else
12349         break;
12350     }
12351
12352   if (sw_if_index_set == 0)
12353     {
12354       errmsg ("missing interface name or sw_if_index");
12355       return -99;
12356     }
12357
12358   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12359
12360   mp->sw_if_index = ntohl (sw_if_index);
12361   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12362   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12363
12364   S (mp);
12365   W (ret);
12366   return ret;
12367 }
12368
12369 static int
12370 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12371 {
12372   unformat_input_t *i = vam->input;
12373   vl_api_l2tpv3_interface_enable_disable_t *mp;
12374   u32 sw_if_index;
12375   u8 sw_if_index_set = 0;
12376   u8 enable_disable = 1;
12377   int ret;
12378
12379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12380     {
12381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12382         sw_if_index_set = 1;
12383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12384         sw_if_index_set = 1;
12385       else if (unformat (i, "enable"))
12386         enable_disable = 1;
12387       else if (unformat (i, "disable"))
12388         enable_disable = 0;
12389       else
12390         break;
12391     }
12392
12393   if (sw_if_index_set == 0)
12394     {
12395       errmsg ("missing interface name or sw_if_index");
12396       return -99;
12397     }
12398
12399   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12400
12401   mp->sw_if_index = ntohl (sw_if_index);
12402   mp->enable_disable = enable_disable;
12403
12404   S (mp);
12405   W (ret);
12406   return ret;
12407 }
12408
12409 static int
12410 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12411 {
12412   unformat_input_t *i = vam->input;
12413   vl_api_l2tpv3_set_lookup_key_t *mp;
12414   u8 key = ~0;
12415   int ret;
12416
12417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12418     {
12419       if (unformat (i, "lookup_v6_src"))
12420         key = L2T_LOOKUP_SRC_ADDRESS;
12421       else if (unformat (i, "lookup_v6_dst"))
12422         key = L2T_LOOKUP_DST_ADDRESS;
12423       else if (unformat (i, "lookup_session_id"))
12424         key = L2T_LOOKUP_SESSION_ID;
12425       else
12426         break;
12427     }
12428
12429   if (key == (u8) ~ 0)
12430     {
12431       errmsg ("l2tp session lookup key unset");
12432       return -99;
12433     }
12434
12435   M (L2TPV3_SET_LOOKUP_KEY, mp);
12436
12437   mp->key = key;
12438
12439   S (mp);
12440   W (ret);
12441   return ret;
12442 }
12443
12444 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12445   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12446 {
12447   vat_main_t *vam = &vat_main;
12448
12449   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12450          format_ip6_address, mp->our_address,
12451          format_ip6_address, mp->client_address,
12452          clib_net_to_host_u32 (mp->sw_if_index));
12453
12454   print (vam->ofp,
12455          "   local cookies %016llx %016llx remote cookie %016llx",
12456          clib_net_to_host_u64 (mp->local_cookie[0]),
12457          clib_net_to_host_u64 (mp->local_cookie[1]),
12458          clib_net_to_host_u64 (mp->remote_cookie));
12459
12460   print (vam->ofp, "   local session-id %d remote session-id %d",
12461          clib_net_to_host_u32 (mp->local_session_id),
12462          clib_net_to_host_u32 (mp->remote_session_id));
12463
12464   print (vam->ofp, "   l2 specific sublayer %s\n",
12465          mp->l2_sublayer_present ? "preset" : "absent");
12466
12467 }
12468
12469 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12470   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12471 {
12472   vat_main_t *vam = &vat_main;
12473   vat_json_node_t *node = NULL;
12474   struct in6_addr addr;
12475
12476   if (VAT_JSON_ARRAY != vam->json_tree.type)
12477     {
12478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12479       vat_json_init_array (&vam->json_tree);
12480     }
12481   node = vat_json_array_add (&vam->json_tree);
12482
12483   vat_json_init_object (node);
12484
12485   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12486   vat_json_object_add_ip6 (node, "our_address", addr);
12487   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12488   vat_json_object_add_ip6 (node, "client_address", addr);
12489
12490   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12491   vat_json_init_array (lc);
12492   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12493   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12494   vat_json_object_add_uint (node, "remote_cookie",
12495                             clib_net_to_host_u64 (mp->remote_cookie));
12496
12497   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12498   vat_json_object_add_uint (node, "local_session_id",
12499                             clib_net_to_host_u32 (mp->local_session_id));
12500   vat_json_object_add_uint (node, "remote_session_id",
12501                             clib_net_to_host_u32 (mp->remote_session_id));
12502   vat_json_object_add_string_copy (node, "l2_sublayer",
12503                                    mp->l2_sublayer_present ? (u8 *) "present"
12504                                    : (u8 *) "absent");
12505 }
12506
12507 static int
12508 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12509 {
12510   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12511   vl_api_control_ping_t *mp_ping;
12512   int ret;
12513
12514   /* Get list of l2tpv3-tunnel interfaces */
12515   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12516   S (mp);
12517
12518   /* Use a control ping for synchronization */
12519   MPING (CONTROL_PING, mp_ping);
12520   S (mp_ping);
12521
12522   W (ret);
12523   return ret;
12524 }
12525
12526
12527 static void vl_api_sw_interface_tap_v2_details_t_handler
12528   (vl_api_sw_interface_tap_v2_details_t * mp)
12529 {
12530   vat_main_t *vam = &vat_main;
12531
12532   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12533                     mp->host_ip4_prefix_len);
12534   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12535                     mp->host_ip6_prefix_len);
12536
12537   print (vam->ofp,
12538          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12539          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12540          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12541          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12542          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12543
12544   vec_free (ip4);
12545   vec_free (ip6);
12546 }
12547
12548 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12549   (vl_api_sw_interface_tap_v2_details_t * mp)
12550 {
12551   vat_main_t *vam = &vat_main;
12552   vat_json_node_t *node = NULL;
12553
12554   if (VAT_JSON_ARRAY != vam->json_tree.type)
12555     {
12556       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12557       vat_json_init_array (&vam->json_tree);
12558     }
12559   node = vat_json_array_add (&vam->json_tree);
12560
12561   vat_json_init_object (node);
12562   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12563   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12564   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12565   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12566   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12567   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12568   vat_json_object_add_string_copy (node, "host_mac_addr",
12569                                    format (0, "%U", format_ethernet_address,
12570                                            &mp->host_mac_addr));
12571   vat_json_object_add_string_copy (node, "host_namespace",
12572                                    mp->host_namespace);
12573   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12574   vat_json_object_add_string_copy (node, "host_ip4_addr",
12575                                    format (0, "%U/%d", format_ip4_address,
12576                                            mp->host_ip4_addr,
12577                                            mp->host_ip4_prefix_len));
12578   vat_json_object_add_string_copy (node, "host_ip6_addr",
12579                                    format (0, "%U/%d", format_ip6_address,
12580                                            mp->host_ip6_addr,
12581                                            mp->host_ip6_prefix_len));
12582
12583 }
12584
12585 static int
12586 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12587 {
12588   vl_api_sw_interface_tap_v2_dump_t *mp;
12589   vl_api_control_ping_t *mp_ping;
12590   int ret;
12591
12592   print (vam->ofp,
12593          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12594          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12595          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12596          "host_ip6_addr");
12597
12598   /* Get list of tap interfaces */
12599   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12600   S (mp);
12601
12602   /* Use a control ping for synchronization */
12603   MPING (CONTROL_PING, mp_ping);
12604   S (mp_ping);
12605
12606   W (ret);
12607   return ret;
12608 }
12609
12610 static void vl_api_sw_interface_virtio_pci_details_t_handler
12611   (vl_api_sw_interface_virtio_pci_details_t * mp)
12612 {
12613   vat_main_t *vam = &vat_main;
12614
12615   typedef union
12616   {
12617     struct
12618     {
12619       u16 domain;
12620       u8 bus;
12621       u8 slot:5;
12622       u8 function:3;
12623     };
12624     u32 as_u32;
12625   } pci_addr_t;
12626   pci_addr_t addr;
12627   addr.as_u32 = ntohl (mp->pci_addr);
12628   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12629                          addr.slot, addr.function);
12630
12631   print (vam->ofp,
12632          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12633          pci_addr, ntohl (mp->sw_if_index),
12634          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12635          format_ethernet_address, mp->mac_addr,
12636          clib_net_to_host_u64 (mp->features));
12637   vec_free (pci_addr);
12638 }
12639
12640 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12641   (vl_api_sw_interface_virtio_pci_details_t * mp)
12642 {
12643   vat_main_t *vam = &vat_main;
12644   vat_json_node_t *node = NULL;
12645
12646   if (VAT_JSON_ARRAY != vam->json_tree.type)
12647     {
12648       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12649       vat_json_init_array (&vam->json_tree);
12650     }
12651   node = vat_json_array_add (&vam->json_tree);
12652
12653   vat_json_init_object (node);
12654   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12655   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12656   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12657   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12658   vat_json_object_add_uint (node, "features",
12659                             clib_net_to_host_u64 (mp->features));
12660   vat_json_object_add_string_copy (node, "mac_addr",
12661                                    format (0, "%U", format_ethernet_address,
12662                                            &mp->mac_addr));
12663 }
12664
12665 static int
12666 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12667 {
12668   vl_api_sw_interface_virtio_pci_dump_t *mp;
12669   vl_api_control_ping_t *mp_ping;
12670   int ret;
12671
12672   print (vam->ofp,
12673          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12674          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12675          "mac_addr", "features");
12676
12677   /* Get list of tap interfaces */
12678   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12679   S (mp);
12680
12681   /* Use a control ping for synchronization */
12682   MPING (CONTROL_PING, mp_ping);
12683   S (mp_ping);
12684
12685   W (ret);
12686   return ret;
12687 }
12688
12689 static int
12690 api_vxlan_offload_rx (vat_main_t * vam)
12691 {
12692   unformat_input_t *line_input = vam->input;
12693   vl_api_vxlan_offload_rx_t *mp;
12694   u32 hw_if_index = ~0, rx_if_index = ~0;
12695   u8 is_add = 1;
12696   int ret;
12697
12698   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12699     {
12700       if (unformat (line_input, "del"))
12701         is_add = 0;
12702       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12703                          &hw_if_index))
12704         ;
12705       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12706         ;
12707       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12708                          &rx_if_index))
12709         ;
12710       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12711         ;
12712       else
12713         {
12714           errmsg ("parse error '%U'", format_unformat_error, line_input);
12715           return -99;
12716         }
12717     }
12718
12719   if (hw_if_index == ~0)
12720     {
12721       errmsg ("no hw interface");
12722       return -99;
12723     }
12724
12725   if (rx_if_index == ~0)
12726     {
12727       errmsg ("no rx tunnel");
12728       return -99;
12729     }
12730
12731   M (VXLAN_OFFLOAD_RX, mp);
12732
12733   mp->hw_if_index = ntohl (hw_if_index);
12734   mp->sw_if_index = ntohl (rx_if_index);
12735   mp->enable = is_add;
12736
12737   S (mp);
12738   W (ret);
12739   return ret;
12740 }
12741
12742 static uword unformat_vxlan_decap_next
12743   (unformat_input_t * input, va_list * args)
12744 {
12745   u32 *result = va_arg (*args, u32 *);
12746   u32 tmp;
12747
12748   if (unformat (input, "l2"))
12749     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12750   else if (unformat (input, "%d", &tmp))
12751     *result = tmp;
12752   else
12753     return 0;
12754   return 1;
12755 }
12756
12757 static int
12758 api_vxlan_add_del_tunnel (vat_main_t * vam)
12759 {
12760   unformat_input_t *line_input = vam->input;
12761   vl_api_vxlan_add_del_tunnel_t *mp;
12762   ip46_address_t src, dst;
12763   u8 is_add = 1;
12764   u8 ipv4_set = 0, ipv6_set = 0;
12765   u8 src_set = 0;
12766   u8 dst_set = 0;
12767   u8 grp_set = 0;
12768   u32 instance = ~0;
12769   u32 mcast_sw_if_index = ~0;
12770   u32 encap_vrf_id = 0;
12771   u32 decap_next_index = ~0;
12772   u32 vni = 0;
12773   int ret;
12774
12775   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12776   clib_memset (&src, 0, sizeof src);
12777   clib_memset (&dst, 0, sizeof dst);
12778
12779   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12780     {
12781       if (unformat (line_input, "del"))
12782         is_add = 0;
12783       else if (unformat (line_input, "instance %d", &instance))
12784         ;
12785       else
12786         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12787         {
12788           ipv4_set = 1;
12789           src_set = 1;
12790         }
12791       else
12792         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12793         {
12794           ipv4_set = 1;
12795           dst_set = 1;
12796         }
12797       else
12798         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12799         {
12800           ipv6_set = 1;
12801           src_set = 1;
12802         }
12803       else
12804         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12805         {
12806           ipv6_set = 1;
12807           dst_set = 1;
12808         }
12809       else if (unformat (line_input, "group %U %U",
12810                          unformat_ip4_address, &dst.ip4,
12811                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12812         {
12813           grp_set = dst_set = 1;
12814           ipv4_set = 1;
12815         }
12816       else if (unformat (line_input, "group %U",
12817                          unformat_ip4_address, &dst.ip4))
12818         {
12819           grp_set = dst_set = 1;
12820           ipv4_set = 1;
12821         }
12822       else if (unformat (line_input, "group %U %U",
12823                          unformat_ip6_address, &dst.ip6,
12824                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12825         {
12826           grp_set = dst_set = 1;
12827           ipv6_set = 1;
12828         }
12829       else if (unformat (line_input, "group %U",
12830                          unformat_ip6_address, &dst.ip6))
12831         {
12832           grp_set = dst_set = 1;
12833           ipv6_set = 1;
12834         }
12835       else
12836         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12837         ;
12838       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12839         ;
12840       else if (unformat (line_input, "decap-next %U",
12841                          unformat_vxlan_decap_next, &decap_next_index))
12842         ;
12843       else if (unformat (line_input, "vni %d", &vni))
12844         ;
12845       else
12846         {
12847           errmsg ("parse error '%U'", format_unformat_error, line_input);
12848           return -99;
12849         }
12850     }
12851
12852   if (src_set == 0)
12853     {
12854       errmsg ("tunnel src address not specified");
12855       return -99;
12856     }
12857   if (dst_set == 0)
12858     {
12859       errmsg ("tunnel dst address not specified");
12860       return -99;
12861     }
12862
12863   if (grp_set && !ip46_address_is_multicast (&dst))
12864     {
12865       errmsg ("tunnel group address not multicast");
12866       return -99;
12867     }
12868   if (grp_set && mcast_sw_if_index == ~0)
12869     {
12870       errmsg ("tunnel nonexistent multicast device");
12871       return -99;
12872     }
12873   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12874     {
12875       errmsg ("tunnel dst address must be unicast");
12876       return -99;
12877     }
12878
12879
12880   if (ipv4_set && ipv6_set)
12881     {
12882       errmsg ("both IPv4 and IPv6 addresses specified");
12883       return -99;
12884     }
12885
12886   if ((vni == 0) || (vni >> 24))
12887     {
12888       errmsg ("vni not specified or out of range");
12889       return -99;
12890     }
12891
12892   M (VXLAN_ADD_DEL_TUNNEL, mp);
12893
12894   if (ipv6_set)
12895     {
12896       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12897       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12898     }
12899   else
12900     {
12901       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12902       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12903     }
12904
12905   mp->instance = htonl (instance);
12906   mp->encap_vrf_id = ntohl (encap_vrf_id);
12907   mp->decap_next_index = ntohl (decap_next_index);
12908   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12909   mp->vni = ntohl (vni);
12910   mp->is_add = is_add;
12911   mp->is_ipv6 = ipv6_set;
12912
12913   S (mp);
12914   W (ret);
12915   return ret;
12916 }
12917
12918 static void vl_api_vxlan_tunnel_details_t_handler
12919   (vl_api_vxlan_tunnel_details_t * mp)
12920 {
12921   vat_main_t *vam = &vat_main;
12922   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12923   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12924
12925   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12926          ntohl (mp->sw_if_index),
12927          ntohl (mp->instance),
12928          format_ip46_address, &src, IP46_TYPE_ANY,
12929          format_ip46_address, &dst, IP46_TYPE_ANY,
12930          ntohl (mp->encap_vrf_id),
12931          ntohl (mp->decap_next_index), ntohl (mp->vni),
12932          ntohl (mp->mcast_sw_if_index));
12933 }
12934
12935 static void vl_api_vxlan_tunnel_details_t_handler_json
12936   (vl_api_vxlan_tunnel_details_t * mp)
12937 {
12938   vat_main_t *vam = &vat_main;
12939   vat_json_node_t *node = NULL;
12940
12941   if (VAT_JSON_ARRAY != vam->json_tree.type)
12942     {
12943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12944       vat_json_init_array (&vam->json_tree);
12945     }
12946   node = vat_json_array_add (&vam->json_tree);
12947
12948   vat_json_init_object (node);
12949   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12950
12951   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12952
12953   if (mp->is_ipv6)
12954     {
12955       struct in6_addr ip6;
12956
12957       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12958       vat_json_object_add_ip6 (node, "src_address", ip6);
12959       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12960       vat_json_object_add_ip6 (node, "dst_address", ip6);
12961     }
12962   else
12963     {
12964       struct in_addr ip4;
12965
12966       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12967       vat_json_object_add_ip4 (node, "src_address", ip4);
12968       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12969       vat_json_object_add_ip4 (node, "dst_address", ip4);
12970     }
12971   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12972   vat_json_object_add_uint (node, "decap_next_index",
12973                             ntohl (mp->decap_next_index));
12974   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12975   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12976   vat_json_object_add_uint (node, "mcast_sw_if_index",
12977                             ntohl (mp->mcast_sw_if_index));
12978 }
12979
12980 static int
12981 api_vxlan_tunnel_dump (vat_main_t * vam)
12982 {
12983   unformat_input_t *i = vam->input;
12984   vl_api_vxlan_tunnel_dump_t *mp;
12985   vl_api_control_ping_t *mp_ping;
12986   u32 sw_if_index;
12987   u8 sw_if_index_set = 0;
12988   int ret;
12989
12990   /* Parse args required to build the message */
12991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12992     {
12993       if (unformat (i, "sw_if_index %d", &sw_if_index))
12994         sw_if_index_set = 1;
12995       else
12996         break;
12997     }
12998
12999   if (sw_if_index_set == 0)
13000     {
13001       sw_if_index = ~0;
13002     }
13003
13004   if (!vam->json_output)
13005     {
13006       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13007              "sw_if_index", "instance", "src_address", "dst_address",
13008              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13009     }
13010
13011   /* Get list of vxlan-tunnel interfaces */
13012   M (VXLAN_TUNNEL_DUMP, mp);
13013
13014   mp->sw_if_index = htonl (sw_if_index);
13015
13016   S (mp);
13017
13018   /* Use a control ping for synchronization */
13019   MPING (CONTROL_PING, mp_ping);
13020   S (mp_ping);
13021
13022   W (ret);
13023   return ret;
13024 }
13025
13026 static uword unformat_geneve_decap_next
13027   (unformat_input_t * input, va_list * args)
13028 {
13029   u32 *result = va_arg (*args, u32 *);
13030   u32 tmp;
13031
13032   if (unformat (input, "l2"))
13033     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13034   else if (unformat (input, "%d", &tmp))
13035     *result = tmp;
13036   else
13037     return 0;
13038   return 1;
13039 }
13040
13041 static int
13042 api_geneve_add_del_tunnel (vat_main_t * vam)
13043 {
13044   unformat_input_t *line_input = vam->input;
13045   vl_api_geneve_add_del_tunnel_t *mp;
13046   ip46_address_t src, dst;
13047   u8 is_add = 1;
13048   u8 ipv4_set = 0, ipv6_set = 0;
13049   u8 src_set = 0;
13050   u8 dst_set = 0;
13051   u8 grp_set = 0;
13052   u32 mcast_sw_if_index = ~0;
13053   u32 encap_vrf_id = 0;
13054   u32 decap_next_index = ~0;
13055   u32 vni = 0;
13056   int ret;
13057
13058   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13059   clib_memset (&src, 0, sizeof src);
13060   clib_memset (&dst, 0, sizeof dst);
13061
13062   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13063     {
13064       if (unformat (line_input, "del"))
13065         is_add = 0;
13066       else
13067         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13068         {
13069           ipv4_set = 1;
13070           src_set = 1;
13071         }
13072       else
13073         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13074         {
13075           ipv4_set = 1;
13076           dst_set = 1;
13077         }
13078       else
13079         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13080         {
13081           ipv6_set = 1;
13082           src_set = 1;
13083         }
13084       else
13085         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13086         {
13087           ipv6_set = 1;
13088           dst_set = 1;
13089         }
13090       else if (unformat (line_input, "group %U %U",
13091                          unformat_ip4_address, &dst.ip4,
13092                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13093         {
13094           grp_set = dst_set = 1;
13095           ipv4_set = 1;
13096         }
13097       else if (unformat (line_input, "group %U",
13098                          unformat_ip4_address, &dst.ip4))
13099         {
13100           grp_set = dst_set = 1;
13101           ipv4_set = 1;
13102         }
13103       else if (unformat (line_input, "group %U %U",
13104                          unformat_ip6_address, &dst.ip6,
13105                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13106         {
13107           grp_set = dst_set = 1;
13108           ipv6_set = 1;
13109         }
13110       else if (unformat (line_input, "group %U",
13111                          unformat_ip6_address, &dst.ip6))
13112         {
13113           grp_set = dst_set = 1;
13114           ipv6_set = 1;
13115         }
13116       else
13117         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13118         ;
13119       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13120         ;
13121       else if (unformat (line_input, "decap-next %U",
13122                          unformat_geneve_decap_next, &decap_next_index))
13123         ;
13124       else if (unformat (line_input, "vni %d", &vni))
13125         ;
13126       else
13127         {
13128           errmsg ("parse error '%U'", format_unformat_error, line_input);
13129           return -99;
13130         }
13131     }
13132
13133   if (src_set == 0)
13134     {
13135       errmsg ("tunnel src address not specified");
13136       return -99;
13137     }
13138   if (dst_set == 0)
13139     {
13140       errmsg ("tunnel dst address not specified");
13141       return -99;
13142     }
13143
13144   if (grp_set && !ip46_address_is_multicast (&dst))
13145     {
13146       errmsg ("tunnel group address not multicast");
13147       return -99;
13148     }
13149   if (grp_set && mcast_sw_if_index == ~0)
13150     {
13151       errmsg ("tunnel nonexistent multicast device");
13152       return -99;
13153     }
13154   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13155     {
13156       errmsg ("tunnel dst address must be unicast");
13157       return -99;
13158     }
13159
13160
13161   if (ipv4_set && ipv6_set)
13162     {
13163       errmsg ("both IPv4 and IPv6 addresses specified");
13164       return -99;
13165     }
13166
13167   if ((vni == 0) || (vni >> 24))
13168     {
13169       errmsg ("vni not specified or out of range");
13170       return -99;
13171     }
13172
13173   M (GENEVE_ADD_DEL_TUNNEL, mp);
13174
13175   if (ipv6_set)
13176     {
13177       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13178       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13179     }
13180   else
13181     {
13182       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13183       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13184     }
13185   mp->encap_vrf_id = ntohl (encap_vrf_id);
13186   mp->decap_next_index = ntohl (decap_next_index);
13187   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13188   mp->vni = ntohl (vni);
13189   mp->is_add = is_add;
13190   mp->is_ipv6 = ipv6_set;
13191
13192   S (mp);
13193   W (ret);
13194   return ret;
13195 }
13196
13197 static void vl_api_geneve_tunnel_details_t_handler
13198   (vl_api_geneve_tunnel_details_t * mp)
13199 {
13200   vat_main_t *vam = &vat_main;
13201   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13202   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13203
13204   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13205          ntohl (mp->sw_if_index),
13206          format_ip46_address, &src, IP46_TYPE_ANY,
13207          format_ip46_address, &dst, IP46_TYPE_ANY,
13208          ntohl (mp->encap_vrf_id),
13209          ntohl (mp->decap_next_index), ntohl (mp->vni),
13210          ntohl (mp->mcast_sw_if_index));
13211 }
13212
13213 static void vl_api_geneve_tunnel_details_t_handler_json
13214   (vl_api_geneve_tunnel_details_t * mp)
13215 {
13216   vat_main_t *vam = &vat_main;
13217   vat_json_node_t *node = NULL;
13218
13219   if (VAT_JSON_ARRAY != vam->json_tree.type)
13220     {
13221       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13222       vat_json_init_array (&vam->json_tree);
13223     }
13224   node = vat_json_array_add (&vam->json_tree);
13225
13226   vat_json_init_object (node);
13227   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13228   if (mp->is_ipv6)
13229     {
13230       struct in6_addr ip6;
13231
13232       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13233       vat_json_object_add_ip6 (node, "src_address", ip6);
13234       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13235       vat_json_object_add_ip6 (node, "dst_address", ip6);
13236     }
13237   else
13238     {
13239       struct in_addr ip4;
13240
13241       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13242       vat_json_object_add_ip4 (node, "src_address", ip4);
13243       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13244       vat_json_object_add_ip4 (node, "dst_address", ip4);
13245     }
13246   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13247   vat_json_object_add_uint (node, "decap_next_index",
13248                             ntohl (mp->decap_next_index));
13249   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13250   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13251   vat_json_object_add_uint (node, "mcast_sw_if_index",
13252                             ntohl (mp->mcast_sw_if_index));
13253 }
13254
13255 static int
13256 api_geneve_tunnel_dump (vat_main_t * vam)
13257 {
13258   unformat_input_t *i = vam->input;
13259   vl_api_geneve_tunnel_dump_t *mp;
13260   vl_api_control_ping_t *mp_ping;
13261   u32 sw_if_index;
13262   u8 sw_if_index_set = 0;
13263   int ret;
13264
13265   /* Parse args required to build the message */
13266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13267     {
13268       if (unformat (i, "sw_if_index %d", &sw_if_index))
13269         sw_if_index_set = 1;
13270       else
13271         break;
13272     }
13273
13274   if (sw_if_index_set == 0)
13275     {
13276       sw_if_index = ~0;
13277     }
13278
13279   if (!vam->json_output)
13280     {
13281       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13282              "sw_if_index", "local_address", "remote_address",
13283              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13284     }
13285
13286   /* Get list of geneve-tunnel interfaces */
13287   M (GENEVE_TUNNEL_DUMP, mp);
13288
13289   mp->sw_if_index = htonl (sw_if_index);
13290
13291   S (mp);
13292
13293   /* Use a control ping for synchronization */
13294   M (CONTROL_PING, mp_ping);
13295   S (mp_ping);
13296
13297   W (ret);
13298   return ret;
13299 }
13300
13301 static int
13302 api_gre_tunnel_add_del (vat_main_t * vam)
13303 {
13304   unformat_input_t *line_input = vam->input;
13305   vl_api_address_t src = { }, dst =
13306   {
13307   };
13308   vl_api_gre_tunnel_add_del_t *mp;
13309   vl_api_gre_tunnel_type_t t_type;
13310   u8 is_add = 1;
13311   u8 ipv4_set = 0;
13312   u8 ipv6_set = 0;
13313   u8 src_set = 0;
13314   u8 dst_set = 0;
13315   u32 outer_fib_id = 0;
13316   u32 session_id = 0;
13317   u32 instance = ~0;
13318   int ret;
13319
13320   t_type = GRE_API_TUNNEL_TYPE_L3;
13321
13322   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13323     {
13324       if (unformat (line_input, "del"))
13325         is_add = 0;
13326       else if (unformat (line_input, "instance %d", &instance))
13327         ;
13328       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13329         {
13330           src_set = 1;
13331         }
13332       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13333         {
13334           dst_set = 1;
13335         }
13336       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13337         ;
13338       else if (unformat (line_input, "teb"))
13339         t_type = GRE_API_TUNNEL_TYPE_TEB;
13340       else if (unformat (line_input, "erspan %d", &session_id))
13341         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13342       else
13343         {
13344           errmsg ("parse error '%U'", format_unformat_error, line_input);
13345           return -99;
13346         }
13347     }
13348
13349   if (src_set == 0)
13350     {
13351       errmsg ("tunnel src address not specified");
13352       return -99;
13353     }
13354   if (dst_set == 0)
13355     {
13356       errmsg ("tunnel dst address not specified");
13357       return -99;
13358     }
13359
13360   M (GRE_TUNNEL_ADD_DEL, mp);
13361
13362   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13363   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13364
13365   mp->tunnel.instance = htonl (instance);
13366   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13367   mp->is_add = is_add;
13368   mp->tunnel.session_id = htons ((u16) session_id);
13369   mp->tunnel.type = htonl (t_type);
13370
13371   S (mp);
13372   W (ret);
13373   return ret;
13374 }
13375
13376 static void vl_api_gre_tunnel_details_t_handler
13377   (vl_api_gre_tunnel_details_t * mp)
13378 {
13379   vat_main_t *vam = &vat_main;
13380
13381   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13382          ntohl (mp->tunnel.sw_if_index),
13383          ntohl (mp->tunnel.instance),
13384          format_vl_api_address, &mp->tunnel.src,
13385          format_vl_api_address, &mp->tunnel.dst,
13386          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13387          ntohl (mp->tunnel.session_id));
13388 }
13389
13390 static void
13391 vat_json_object_add_address (vat_json_node_t * node,
13392                              const char *str, const vl_api_address_t * addr)
13393 {
13394   if (ADDRESS_IP6 == addr->af)
13395     {
13396       struct in6_addr ip6;
13397
13398       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13399       vat_json_object_add_ip6 (node, str, ip6);
13400     }
13401   else
13402     {
13403       struct in_addr ip4;
13404
13405       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13406       vat_json_object_add_ip4 (node, str, ip4);
13407     }
13408 }
13409
13410 static void vl_api_gre_tunnel_details_t_handler_json
13411   (vl_api_gre_tunnel_details_t * mp)
13412 {
13413   vat_main_t *vam = &vat_main;
13414   vat_json_node_t *node = NULL;
13415   struct in_addr ip4;
13416   struct in6_addr ip6;
13417
13418   if (VAT_JSON_ARRAY != vam->json_tree.type)
13419     {
13420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13421       vat_json_init_array (&vam->json_tree);
13422     }
13423   node = vat_json_array_add (&vam->json_tree);
13424
13425   vat_json_init_object (node);
13426   vat_json_object_add_uint (node, "sw_if_index",
13427                             ntohl (mp->tunnel.sw_if_index));
13428   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13429
13430   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13431   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13432   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13433   vat_json_object_add_uint (node, "outer_fib_id",
13434                             ntohl (mp->tunnel.outer_fib_id));
13435   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13436 }
13437
13438 static int
13439 api_gre_tunnel_dump (vat_main_t * vam)
13440 {
13441   unformat_input_t *i = vam->input;
13442   vl_api_gre_tunnel_dump_t *mp;
13443   vl_api_control_ping_t *mp_ping;
13444   u32 sw_if_index;
13445   u8 sw_if_index_set = 0;
13446   int ret;
13447
13448   /* Parse args required to build the message */
13449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13450     {
13451       if (unformat (i, "sw_if_index %d", &sw_if_index))
13452         sw_if_index_set = 1;
13453       else
13454         break;
13455     }
13456
13457   if (sw_if_index_set == 0)
13458     {
13459       sw_if_index = ~0;
13460     }
13461
13462   if (!vam->json_output)
13463     {
13464       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13465              "sw_if_index", "instance", "src_address", "dst_address",
13466              "tunnel_type", "outer_fib_id", "session_id");
13467     }
13468
13469   /* Get list of gre-tunnel interfaces */
13470   M (GRE_TUNNEL_DUMP, mp);
13471
13472   mp->sw_if_index = htonl (sw_if_index);
13473
13474   S (mp);
13475
13476   /* Use a control ping for synchronization */
13477   MPING (CONTROL_PING, mp_ping);
13478   S (mp_ping);
13479
13480   W (ret);
13481   return ret;
13482 }
13483
13484 static int
13485 api_l2_fib_clear_table (vat_main_t * vam)
13486 {
13487 //  unformat_input_t * i = vam->input;
13488   vl_api_l2_fib_clear_table_t *mp;
13489   int ret;
13490
13491   M (L2_FIB_CLEAR_TABLE, mp);
13492
13493   S (mp);
13494   W (ret);
13495   return ret;
13496 }
13497
13498 static int
13499 api_l2_interface_efp_filter (vat_main_t * vam)
13500 {
13501   unformat_input_t *i = vam->input;
13502   vl_api_l2_interface_efp_filter_t *mp;
13503   u32 sw_if_index;
13504   u8 enable = 1;
13505   u8 sw_if_index_set = 0;
13506   int ret;
13507
13508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13509     {
13510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13511         sw_if_index_set = 1;
13512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13513         sw_if_index_set = 1;
13514       else if (unformat (i, "enable"))
13515         enable = 1;
13516       else if (unformat (i, "disable"))
13517         enable = 0;
13518       else
13519         {
13520           clib_warning ("parse error '%U'", format_unformat_error, i);
13521           return -99;
13522         }
13523     }
13524
13525   if (sw_if_index_set == 0)
13526     {
13527       errmsg ("missing sw_if_index");
13528       return -99;
13529     }
13530
13531   M (L2_INTERFACE_EFP_FILTER, mp);
13532
13533   mp->sw_if_index = ntohl (sw_if_index);
13534   mp->enable_disable = enable;
13535
13536   S (mp);
13537   W (ret);
13538   return ret;
13539 }
13540
13541 #define foreach_vtr_op                          \
13542 _("disable",  L2_VTR_DISABLED)                  \
13543 _("push-1",  L2_VTR_PUSH_1)                     \
13544 _("push-2",  L2_VTR_PUSH_2)                     \
13545 _("pop-1",  L2_VTR_POP_1)                       \
13546 _("pop-2",  L2_VTR_POP_2)                       \
13547 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13548 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13549 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13550 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13551
13552 static int
13553 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13554 {
13555   unformat_input_t *i = vam->input;
13556   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13557   u32 sw_if_index;
13558   u8 sw_if_index_set = 0;
13559   u8 vtr_op_set = 0;
13560   u32 vtr_op = 0;
13561   u32 push_dot1q = 1;
13562   u32 tag1 = ~0;
13563   u32 tag2 = ~0;
13564   int ret;
13565
13566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13567     {
13568       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13569         sw_if_index_set = 1;
13570       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13571         sw_if_index_set = 1;
13572       else if (unformat (i, "vtr_op %d", &vtr_op))
13573         vtr_op_set = 1;
13574 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13575       foreach_vtr_op
13576 #undef _
13577         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13578         ;
13579       else if (unformat (i, "tag1 %d", &tag1))
13580         ;
13581       else if (unformat (i, "tag2 %d", &tag2))
13582         ;
13583       else
13584         {
13585           clib_warning ("parse error '%U'", format_unformat_error, i);
13586           return -99;
13587         }
13588     }
13589
13590   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13591     {
13592       errmsg ("missing vtr operation or sw_if_index");
13593       return -99;
13594     }
13595
13596   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13597   mp->sw_if_index = ntohl (sw_if_index);
13598   mp->vtr_op = ntohl (vtr_op);
13599   mp->push_dot1q = ntohl (push_dot1q);
13600   mp->tag1 = ntohl (tag1);
13601   mp->tag2 = ntohl (tag2);
13602
13603   S (mp);
13604   W (ret);
13605   return ret;
13606 }
13607
13608 static int
13609 api_create_vhost_user_if (vat_main_t * vam)
13610 {
13611   unformat_input_t *i = vam->input;
13612   vl_api_create_vhost_user_if_t *mp;
13613   u8 *file_name;
13614   u8 is_server = 0;
13615   u8 file_name_set = 0;
13616   u32 custom_dev_instance = ~0;
13617   u8 hwaddr[6];
13618   u8 use_custom_mac = 0;
13619   u8 disable_mrg_rxbuf = 0;
13620   u8 disable_indirect_desc = 0;
13621   u8 *tag = 0;
13622   int ret;
13623
13624   /* Shut up coverity */
13625   clib_memset (hwaddr, 0, sizeof (hwaddr));
13626
13627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13628     {
13629       if (unformat (i, "socket %s", &file_name))
13630         {
13631           file_name_set = 1;
13632         }
13633       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13634         ;
13635       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13636         use_custom_mac = 1;
13637       else if (unformat (i, "server"))
13638         is_server = 1;
13639       else if (unformat (i, "disable_mrg_rxbuf"))
13640         disable_mrg_rxbuf = 1;
13641       else if (unformat (i, "disable_indirect_desc"))
13642         disable_indirect_desc = 1;
13643       else if (unformat (i, "tag %s", &tag))
13644         ;
13645       else
13646         break;
13647     }
13648
13649   if (file_name_set == 0)
13650     {
13651       errmsg ("missing socket file name");
13652       return -99;
13653     }
13654
13655   if (vec_len (file_name) > 255)
13656     {
13657       errmsg ("socket file name too long");
13658       return -99;
13659     }
13660   vec_add1 (file_name, 0);
13661
13662   M (CREATE_VHOST_USER_IF, mp);
13663
13664   mp->is_server = is_server;
13665   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13666   mp->disable_indirect_desc = disable_indirect_desc;
13667   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13668   vec_free (file_name);
13669   if (custom_dev_instance != ~0)
13670     {
13671       mp->renumber = 1;
13672       mp->custom_dev_instance = ntohl (custom_dev_instance);
13673     }
13674
13675   mp->use_custom_mac = use_custom_mac;
13676   clib_memcpy (mp->mac_address, hwaddr, 6);
13677   if (tag)
13678     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13679   vec_free (tag);
13680
13681   S (mp);
13682   W (ret);
13683   return ret;
13684 }
13685
13686 static int
13687 api_modify_vhost_user_if (vat_main_t * vam)
13688 {
13689   unformat_input_t *i = vam->input;
13690   vl_api_modify_vhost_user_if_t *mp;
13691   u8 *file_name;
13692   u8 is_server = 0;
13693   u8 file_name_set = 0;
13694   u32 custom_dev_instance = ~0;
13695   u8 sw_if_index_set = 0;
13696   u32 sw_if_index = (u32) ~ 0;
13697   int ret;
13698
13699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13700     {
13701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13702         sw_if_index_set = 1;
13703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13704         sw_if_index_set = 1;
13705       else if (unformat (i, "socket %s", &file_name))
13706         {
13707           file_name_set = 1;
13708         }
13709       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13710         ;
13711       else if (unformat (i, "server"))
13712         is_server = 1;
13713       else
13714         break;
13715     }
13716
13717   if (sw_if_index_set == 0)
13718     {
13719       errmsg ("missing sw_if_index or interface name");
13720       return -99;
13721     }
13722
13723   if (file_name_set == 0)
13724     {
13725       errmsg ("missing socket file name");
13726       return -99;
13727     }
13728
13729   if (vec_len (file_name) > 255)
13730     {
13731       errmsg ("socket file name too long");
13732       return -99;
13733     }
13734   vec_add1 (file_name, 0);
13735
13736   M (MODIFY_VHOST_USER_IF, mp);
13737
13738   mp->sw_if_index = ntohl (sw_if_index);
13739   mp->is_server = is_server;
13740   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13741   vec_free (file_name);
13742   if (custom_dev_instance != ~0)
13743     {
13744       mp->renumber = 1;
13745       mp->custom_dev_instance = ntohl (custom_dev_instance);
13746     }
13747
13748   S (mp);
13749   W (ret);
13750   return ret;
13751 }
13752
13753 static int
13754 api_delete_vhost_user_if (vat_main_t * vam)
13755 {
13756   unformat_input_t *i = vam->input;
13757   vl_api_delete_vhost_user_if_t *mp;
13758   u32 sw_if_index = ~0;
13759   u8 sw_if_index_set = 0;
13760   int ret;
13761
13762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13763     {
13764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13765         sw_if_index_set = 1;
13766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13767         sw_if_index_set = 1;
13768       else
13769         break;
13770     }
13771
13772   if (sw_if_index_set == 0)
13773     {
13774       errmsg ("missing sw_if_index or interface name");
13775       return -99;
13776     }
13777
13778
13779   M (DELETE_VHOST_USER_IF, mp);
13780
13781   mp->sw_if_index = ntohl (sw_if_index);
13782
13783   S (mp);
13784   W (ret);
13785   return ret;
13786 }
13787
13788 static void vl_api_sw_interface_vhost_user_details_t_handler
13789   (vl_api_sw_interface_vhost_user_details_t * mp)
13790 {
13791   vat_main_t *vam = &vat_main;
13792
13793   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13794          (char *) mp->interface_name,
13795          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13796          clib_net_to_host_u64 (mp->features), mp->is_server,
13797          ntohl (mp->num_regions), (char *) mp->sock_filename);
13798   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13799 }
13800
13801 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13802   (vl_api_sw_interface_vhost_user_details_t * mp)
13803 {
13804   vat_main_t *vam = &vat_main;
13805   vat_json_node_t *node = NULL;
13806
13807   if (VAT_JSON_ARRAY != vam->json_tree.type)
13808     {
13809       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13810       vat_json_init_array (&vam->json_tree);
13811     }
13812   node = vat_json_array_add (&vam->json_tree);
13813
13814   vat_json_init_object (node);
13815   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13816   vat_json_object_add_string_copy (node, "interface_name",
13817                                    mp->interface_name);
13818   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13819                             ntohl (mp->virtio_net_hdr_sz));
13820   vat_json_object_add_uint (node, "features",
13821                             clib_net_to_host_u64 (mp->features));
13822   vat_json_object_add_uint (node, "is_server", mp->is_server);
13823   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13824   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13825   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13826 }
13827
13828 static int
13829 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13830 {
13831   vl_api_sw_interface_vhost_user_dump_t *mp;
13832   vl_api_control_ping_t *mp_ping;
13833   int ret;
13834   print (vam->ofp,
13835          "Interface name            idx hdr_sz features server regions filename");
13836
13837   /* Get list of vhost-user interfaces */
13838   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13839   S (mp);
13840
13841   /* Use a control ping for synchronization */
13842   MPING (CONTROL_PING, mp_ping);
13843   S (mp_ping);
13844
13845   W (ret);
13846   return ret;
13847 }
13848
13849 static int
13850 api_show_version (vat_main_t * vam)
13851 {
13852   vl_api_show_version_t *mp;
13853   int ret;
13854
13855   M (SHOW_VERSION, mp);
13856
13857   S (mp);
13858   W (ret);
13859   return ret;
13860 }
13861
13862
13863 static int
13864 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13865 {
13866   unformat_input_t *line_input = vam->input;
13867   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13868   ip4_address_t local4, remote4;
13869   ip6_address_t local6, remote6;
13870   u8 is_add = 1;
13871   u8 ipv4_set = 0, ipv6_set = 0;
13872   u8 local_set = 0;
13873   u8 remote_set = 0;
13874   u8 grp_set = 0;
13875   u32 mcast_sw_if_index = ~0;
13876   u32 encap_vrf_id = 0;
13877   u32 decap_vrf_id = 0;
13878   u8 protocol = ~0;
13879   u32 vni;
13880   u8 vni_set = 0;
13881   int ret;
13882
13883   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13884   clib_memset (&local4, 0, sizeof local4);
13885   clib_memset (&remote4, 0, sizeof remote4);
13886   clib_memset (&local6, 0, sizeof local6);
13887   clib_memset (&remote6, 0, sizeof remote6);
13888
13889   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13890     {
13891       if (unformat (line_input, "del"))
13892         is_add = 0;
13893       else if (unformat (line_input, "local %U",
13894                          unformat_ip4_address, &local4))
13895         {
13896           local_set = 1;
13897           ipv4_set = 1;
13898         }
13899       else if (unformat (line_input, "remote %U",
13900                          unformat_ip4_address, &remote4))
13901         {
13902           remote_set = 1;
13903           ipv4_set = 1;
13904         }
13905       else if (unformat (line_input, "local %U",
13906                          unformat_ip6_address, &local6))
13907         {
13908           local_set = 1;
13909           ipv6_set = 1;
13910         }
13911       else if (unformat (line_input, "remote %U",
13912                          unformat_ip6_address, &remote6))
13913         {
13914           remote_set = 1;
13915           ipv6_set = 1;
13916         }
13917       else if (unformat (line_input, "group %U %U",
13918                          unformat_ip4_address, &remote4,
13919                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13920         {
13921           grp_set = remote_set = 1;
13922           ipv4_set = 1;
13923         }
13924       else if (unformat (line_input, "group %U",
13925                          unformat_ip4_address, &remote4))
13926         {
13927           grp_set = remote_set = 1;
13928           ipv4_set = 1;
13929         }
13930       else if (unformat (line_input, "group %U %U",
13931                          unformat_ip6_address, &remote6,
13932                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13933         {
13934           grp_set = remote_set = 1;
13935           ipv6_set = 1;
13936         }
13937       else if (unformat (line_input, "group %U",
13938                          unformat_ip6_address, &remote6))
13939         {
13940           grp_set = remote_set = 1;
13941           ipv6_set = 1;
13942         }
13943       else
13944         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13945         ;
13946       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13947         ;
13948       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13949         ;
13950       else if (unformat (line_input, "vni %d", &vni))
13951         vni_set = 1;
13952       else if (unformat (line_input, "next-ip4"))
13953         protocol = 1;
13954       else if (unformat (line_input, "next-ip6"))
13955         protocol = 2;
13956       else if (unformat (line_input, "next-ethernet"))
13957         protocol = 3;
13958       else if (unformat (line_input, "next-nsh"))
13959         protocol = 4;
13960       else
13961         {
13962           errmsg ("parse error '%U'", format_unformat_error, line_input);
13963           return -99;
13964         }
13965     }
13966
13967   if (local_set == 0)
13968     {
13969       errmsg ("tunnel local address not specified");
13970       return -99;
13971     }
13972   if (remote_set == 0)
13973     {
13974       errmsg ("tunnel remote address not specified");
13975       return -99;
13976     }
13977   if (grp_set && mcast_sw_if_index == ~0)
13978     {
13979       errmsg ("tunnel nonexistent multicast device");
13980       return -99;
13981     }
13982   if (ipv4_set && ipv6_set)
13983     {
13984       errmsg ("both IPv4 and IPv6 addresses specified");
13985       return -99;
13986     }
13987
13988   if (vni_set == 0)
13989     {
13990       errmsg ("vni not specified");
13991       return -99;
13992     }
13993
13994   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13995
13996
13997   if (ipv6_set)
13998     {
13999       clib_memcpy (&mp->local, &local6, sizeof (local6));
14000       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14001     }
14002   else
14003     {
14004       clib_memcpy (&mp->local, &local4, sizeof (local4));
14005       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14006     }
14007
14008   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14009   mp->encap_vrf_id = ntohl (encap_vrf_id);
14010   mp->decap_vrf_id = ntohl (decap_vrf_id);
14011   mp->protocol = protocol;
14012   mp->vni = ntohl (vni);
14013   mp->is_add = is_add;
14014   mp->is_ipv6 = ipv6_set;
14015
14016   S (mp);
14017   W (ret);
14018   return ret;
14019 }
14020
14021 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14022   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14023 {
14024   vat_main_t *vam = &vat_main;
14025   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14026   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14027
14028   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14029          ntohl (mp->sw_if_index),
14030          format_ip46_address, &local, IP46_TYPE_ANY,
14031          format_ip46_address, &remote, IP46_TYPE_ANY,
14032          ntohl (mp->vni), mp->protocol,
14033          ntohl (mp->mcast_sw_if_index),
14034          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14035 }
14036
14037
14038 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14039   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14040 {
14041   vat_main_t *vam = &vat_main;
14042   vat_json_node_t *node = NULL;
14043   struct in_addr ip4;
14044   struct in6_addr ip6;
14045
14046   if (VAT_JSON_ARRAY != vam->json_tree.type)
14047     {
14048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14049       vat_json_init_array (&vam->json_tree);
14050     }
14051   node = vat_json_array_add (&vam->json_tree);
14052
14053   vat_json_init_object (node);
14054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14055   if (mp->is_ipv6)
14056     {
14057       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14058       vat_json_object_add_ip6 (node, "local", ip6);
14059       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14060       vat_json_object_add_ip6 (node, "remote", ip6);
14061     }
14062   else
14063     {
14064       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14065       vat_json_object_add_ip4 (node, "local", ip4);
14066       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14067       vat_json_object_add_ip4 (node, "remote", ip4);
14068     }
14069   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14070   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14071   vat_json_object_add_uint (node, "mcast_sw_if_index",
14072                             ntohl (mp->mcast_sw_if_index));
14073   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14074   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14075   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14076 }
14077
14078 static int
14079 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14080 {
14081   unformat_input_t *i = vam->input;
14082   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14083   vl_api_control_ping_t *mp_ping;
14084   u32 sw_if_index;
14085   u8 sw_if_index_set = 0;
14086   int ret;
14087
14088   /* Parse args required to build the message */
14089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14090     {
14091       if (unformat (i, "sw_if_index %d", &sw_if_index))
14092         sw_if_index_set = 1;
14093       else
14094         break;
14095     }
14096
14097   if (sw_if_index_set == 0)
14098     {
14099       sw_if_index = ~0;
14100     }
14101
14102   if (!vam->json_output)
14103     {
14104       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14105              "sw_if_index", "local", "remote", "vni",
14106              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14107     }
14108
14109   /* Get list of vxlan-tunnel interfaces */
14110   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14111
14112   mp->sw_if_index = htonl (sw_if_index);
14113
14114   S (mp);
14115
14116   /* Use a control ping for synchronization */
14117   MPING (CONTROL_PING, mp_ping);
14118   S (mp_ping);
14119
14120   W (ret);
14121   return ret;
14122 }
14123
14124 static void vl_api_l2_fib_table_details_t_handler
14125   (vl_api_l2_fib_table_details_t * mp)
14126 {
14127   vat_main_t *vam = &vat_main;
14128
14129   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14130          "       %d       %d     %d",
14131          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14132          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14133          mp->bvi_mac);
14134 }
14135
14136 static void vl_api_l2_fib_table_details_t_handler_json
14137   (vl_api_l2_fib_table_details_t * mp)
14138 {
14139   vat_main_t *vam = &vat_main;
14140   vat_json_node_t *node = NULL;
14141
14142   if (VAT_JSON_ARRAY != vam->json_tree.type)
14143     {
14144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14145       vat_json_init_array (&vam->json_tree);
14146     }
14147   node = vat_json_array_add (&vam->json_tree);
14148
14149   vat_json_init_object (node);
14150   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14151   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14152   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14153   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14154   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14155   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14156 }
14157
14158 static int
14159 api_l2_fib_table_dump (vat_main_t * vam)
14160 {
14161   unformat_input_t *i = vam->input;
14162   vl_api_l2_fib_table_dump_t *mp;
14163   vl_api_control_ping_t *mp_ping;
14164   u32 bd_id;
14165   u8 bd_id_set = 0;
14166   int ret;
14167
14168   /* Parse args required to build the message */
14169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14170     {
14171       if (unformat (i, "bd_id %d", &bd_id))
14172         bd_id_set = 1;
14173       else
14174         break;
14175     }
14176
14177   if (bd_id_set == 0)
14178     {
14179       errmsg ("missing bridge domain");
14180       return -99;
14181     }
14182
14183   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14184
14185   /* Get list of l2 fib entries */
14186   M (L2_FIB_TABLE_DUMP, mp);
14187
14188   mp->bd_id = ntohl (bd_id);
14189   S (mp);
14190
14191   /* Use a control ping for synchronization */
14192   MPING (CONTROL_PING, mp_ping);
14193   S (mp_ping);
14194
14195   W (ret);
14196   return ret;
14197 }
14198
14199
14200 static int
14201 api_interface_name_renumber (vat_main_t * vam)
14202 {
14203   unformat_input_t *line_input = vam->input;
14204   vl_api_interface_name_renumber_t *mp;
14205   u32 sw_if_index = ~0;
14206   u32 new_show_dev_instance = ~0;
14207   int ret;
14208
14209   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14210     {
14211       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14212                     &sw_if_index))
14213         ;
14214       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14215         ;
14216       else if (unformat (line_input, "new_show_dev_instance %d",
14217                          &new_show_dev_instance))
14218         ;
14219       else
14220         break;
14221     }
14222
14223   if (sw_if_index == ~0)
14224     {
14225       errmsg ("missing interface name or sw_if_index");
14226       return -99;
14227     }
14228
14229   if (new_show_dev_instance == ~0)
14230     {
14231       errmsg ("missing new_show_dev_instance");
14232       return -99;
14233     }
14234
14235   M (INTERFACE_NAME_RENUMBER, mp);
14236
14237   mp->sw_if_index = ntohl (sw_if_index);
14238   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14239
14240   S (mp);
14241   W (ret);
14242   return ret;
14243 }
14244
14245 static int
14246 api_ip_probe_neighbor (vat_main_t * vam)
14247 {
14248   unformat_input_t *i = vam->input;
14249   vl_api_ip_probe_neighbor_t *mp;
14250   vl_api_address_t dst_adr;
14251   u8 int_set = 0;
14252   u8 adr_set = 0;
14253   u32 sw_if_index;
14254   int ret;
14255
14256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14257     {
14258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14259         int_set = 1;
14260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14261         int_set = 1;
14262       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14263         adr_set = 1;
14264       else
14265         break;
14266     }
14267
14268   if (int_set == 0)
14269     {
14270       errmsg ("missing interface");
14271       return -99;
14272     }
14273
14274   if (adr_set == 0)
14275     {
14276       errmsg ("missing addresses");
14277       return -99;
14278     }
14279
14280   M (IP_PROBE_NEIGHBOR, mp);
14281
14282   mp->sw_if_index = ntohl (sw_if_index);
14283   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14284
14285   S (mp);
14286   W (ret);
14287   return ret;
14288 }
14289
14290 static int
14291 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14295   u8 mode = IP_SCAN_V46_NEIGHBORS;
14296   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14297   int ret;
14298
14299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14300     {
14301       if (unformat (i, "ip4"))
14302         mode = IP_SCAN_V4_NEIGHBORS;
14303       else if (unformat (i, "ip6"))
14304         mode = IP_SCAN_V6_NEIGHBORS;
14305       if (unformat (i, "both"))
14306         mode = IP_SCAN_V46_NEIGHBORS;
14307       else if (unformat (i, "disable"))
14308         mode = IP_SCAN_DISABLED;
14309       else if (unformat (i, "interval %d", &interval))
14310         ;
14311       else if (unformat (i, "max-time %d", &time))
14312         ;
14313       else if (unformat (i, "max-update %d", &update))
14314         ;
14315       else if (unformat (i, "delay %d", &delay))
14316         ;
14317       else if (unformat (i, "stale %d", &stale))
14318         ;
14319       else
14320         break;
14321     }
14322
14323   if (interval > 255)
14324     {
14325       errmsg ("interval cannot exceed 255 minutes.");
14326       return -99;
14327     }
14328   if (time > 255)
14329     {
14330       errmsg ("max-time cannot exceed 255 usec.");
14331       return -99;
14332     }
14333   if (update > 255)
14334     {
14335       errmsg ("max-update cannot exceed 255.");
14336       return -99;
14337     }
14338   if (delay > 255)
14339     {
14340       errmsg ("delay cannot exceed 255 msec.");
14341       return -99;
14342     }
14343   if (stale > 255)
14344     {
14345       errmsg ("stale cannot exceed 255 minutes.");
14346       return -99;
14347     }
14348
14349   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14350   mp->mode = mode;
14351   mp->scan_interval = interval;
14352   mp->max_proc_time = time;
14353   mp->max_update = update;
14354   mp->scan_int_delay = delay;
14355   mp->stale_threshold = stale;
14356
14357   S (mp);
14358   W (ret);
14359   return ret;
14360 }
14361
14362 static int
14363 api_want_ip4_arp_events (vat_main_t * vam)
14364 {
14365   unformat_input_t *line_input = vam->input;
14366   vl_api_want_ip4_arp_events_t *mp;
14367   ip4_address_t address;
14368   int address_set = 0;
14369   u32 enable_disable = 1;
14370   int ret;
14371
14372   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14373     {
14374       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14375         address_set = 1;
14376       else if (unformat (line_input, "del"))
14377         enable_disable = 0;
14378       else
14379         break;
14380     }
14381
14382   if (address_set == 0)
14383     {
14384       errmsg ("missing addresses");
14385       return -99;
14386     }
14387
14388   M (WANT_IP4_ARP_EVENTS, mp);
14389   mp->enable_disable = enable_disable;
14390   mp->pid = htonl (getpid ());
14391   clib_memcpy (mp->ip, &address, sizeof (address));
14392
14393   S (mp);
14394   W (ret);
14395   return ret;
14396 }
14397
14398 static int
14399 api_want_ip6_nd_events (vat_main_t * vam)
14400 {
14401   unformat_input_t *line_input = vam->input;
14402   vl_api_want_ip6_nd_events_t *mp;
14403   vl_api_ip6_address_t address;
14404   int address_set = 0;
14405   u32 enable_disable = 1;
14406   int ret;
14407
14408   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14409     {
14410       if (unformat
14411           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14412         address_set = 1;
14413       else if (unformat (line_input, "del"))
14414         enable_disable = 0;
14415       else
14416         break;
14417     }
14418
14419   if (address_set == 0)
14420     {
14421       errmsg ("missing addresses");
14422       return -99;
14423     }
14424
14425   M (WANT_IP6_ND_EVENTS, mp);
14426   mp->enable_disable = enable_disable;
14427   mp->pid = htonl (getpid ());
14428   clib_memcpy (&mp->ip, &address, sizeof (address));
14429
14430   S (mp);
14431   W (ret);
14432   return ret;
14433 }
14434
14435 static int
14436 api_want_l2_macs_events (vat_main_t * vam)
14437 {
14438   unformat_input_t *line_input = vam->input;
14439   vl_api_want_l2_macs_events_t *mp;
14440   u8 enable_disable = 1;
14441   u32 scan_delay = 0;
14442   u32 max_macs_in_event = 0;
14443   u32 learn_limit = 0;
14444   int ret;
14445
14446   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14447     {
14448       if (unformat (line_input, "learn-limit %d", &learn_limit))
14449         ;
14450       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14451         ;
14452       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14453         ;
14454       else if (unformat (line_input, "disable"))
14455         enable_disable = 0;
14456       else
14457         break;
14458     }
14459
14460   M (WANT_L2_MACS_EVENTS, mp);
14461   mp->enable_disable = enable_disable;
14462   mp->pid = htonl (getpid ());
14463   mp->learn_limit = htonl (learn_limit);
14464   mp->scan_delay = (u8) scan_delay;
14465   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14466   S (mp);
14467   W (ret);
14468   return ret;
14469 }
14470
14471 static int
14472 api_input_acl_set_interface (vat_main_t * vam)
14473 {
14474   unformat_input_t *i = vam->input;
14475   vl_api_input_acl_set_interface_t *mp;
14476   u32 sw_if_index;
14477   int sw_if_index_set;
14478   u32 ip4_table_index = ~0;
14479   u32 ip6_table_index = ~0;
14480   u32 l2_table_index = ~0;
14481   u8 is_add = 1;
14482   int ret;
14483
14484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14485     {
14486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14487         sw_if_index_set = 1;
14488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14489         sw_if_index_set = 1;
14490       else if (unformat (i, "del"))
14491         is_add = 0;
14492       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14493         ;
14494       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14495         ;
14496       else if (unformat (i, "l2-table %d", &l2_table_index))
14497         ;
14498       else
14499         {
14500           clib_warning ("parse error '%U'", format_unformat_error, i);
14501           return -99;
14502         }
14503     }
14504
14505   if (sw_if_index_set == 0)
14506     {
14507       errmsg ("missing interface name or sw_if_index");
14508       return -99;
14509     }
14510
14511   M (INPUT_ACL_SET_INTERFACE, mp);
14512
14513   mp->sw_if_index = ntohl (sw_if_index);
14514   mp->ip4_table_index = ntohl (ip4_table_index);
14515   mp->ip6_table_index = ntohl (ip6_table_index);
14516   mp->l2_table_index = ntohl (l2_table_index);
14517   mp->is_add = is_add;
14518
14519   S (mp);
14520   W (ret);
14521   return ret;
14522 }
14523
14524 static int
14525 api_output_acl_set_interface (vat_main_t * vam)
14526 {
14527   unformat_input_t *i = vam->input;
14528   vl_api_output_acl_set_interface_t *mp;
14529   u32 sw_if_index;
14530   int sw_if_index_set;
14531   u32 ip4_table_index = ~0;
14532   u32 ip6_table_index = ~0;
14533   u32 l2_table_index = ~0;
14534   u8 is_add = 1;
14535   int ret;
14536
14537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14538     {
14539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14540         sw_if_index_set = 1;
14541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14542         sw_if_index_set = 1;
14543       else if (unformat (i, "del"))
14544         is_add = 0;
14545       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14546         ;
14547       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14548         ;
14549       else if (unformat (i, "l2-table %d", &l2_table_index))
14550         ;
14551       else
14552         {
14553           clib_warning ("parse error '%U'", format_unformat_error, i);
14554           return -99;
14555         }
14556     }
14557
14558   if (sw_if_index_set == 0)
14559     {
14560       errmsg ("missing interface name or sw_if_index");
14561       return -99;
14562     }
14563
14564   M (OUTPUT_ACL_SET_INTERFACE, mp);
14565
14566   mp->sw_if_index = ntohl (sw_if_index);
14567   mp->ip4_table_index = ntohl (ip4_table_index);
14568   mp->ip6_table_index = ntohl (ip6_table_index);
14569   mp->l2_table_index = ntohl (l2_table_index);
14570   mp->is_add = is_add;
14571
14572   S (mp);
14573   W (ret);
14574   return ret;
14575 }
14576
14577 static int
14578 api_ip_address_dump (vat_main_t * vam)
14579 {
14580   unformat_input_t *i = vam->input;
14581   vl_api_ip_address_dump_t *mp;
14582   vl_api_control_ping_t *mp_ping;
14583   u32 sw_if_index = ~0;
14584   u8 sw_if_index_set = 0;
14585   u8 ipv4_set = 0;
14586   u8 ipv6_set = 0;
14587   int ret;
14588
14589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14590     {
14591       if (unformat (i, "sw_if_index %d", &sw_if_index))
14592         sw_if_index_set = 1;
14593       else
14594         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14595         sw_if_index_set = 1;
14596       else if (unformat (i, "ipv4"))
14597         ipv4_set = 1;
14598       else if (unformat (i, "ipv6"))
14599         ipv6_set = 1;
14600       else
14601         break;
14602     }
14603
14604   if (ipv4_set && ipv6_set)
14605     {
14606       errmsg ("ipv4 and ipv6 flags cannot be both set");
14607       return -99;
14608     }
14609
14610   if ((!ipv4_set) && (!ipv6_set))
14611     {
14612       errmsg ("no ipv4 nor ipv6 flag set");
14613       return -99;
14614     }
14615
14616   if (sw_if_index_set == 0)
14617     {
14618       errmsg ("missing interface name or sw_if_index");
14619       return -99;
14620     }
14621
14622   vam->current_sw_if_index = sw_if_index;
14623   vam->is_ipv6 = ipv6_set;
14624
14625   M (IP_ADDRESS_DUMP, mp);
14626   mp->sw_if_index = ntohl (sw_if_index);
14627   mp->is_ipv6 = ipv6_set;
14628   S (mp);
14629
14630   /* Use a control ping for synchronization */
14631   MPING (CONTROL_PING, mp_ping);
14632   S (mp_ping);
14633
14634   W (ret);
14635   return ret;
14636 }
14637
14638 static int
14639 api_ip_dump (vat_main_t * vam)
14640 {
14641   vl_api_ip_dump_t *mp;
14642   vl_api_control_ping_t *mp_ping;
14643   unformat_input_t *in = vam->input;
14644   int ipv4_set = 0;
14645   int ipv6_set = 0;
14646   int is_ipv6;
14647   int i;
14648   int ret;
14649
14650   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14651     {
14652       if (unformat (in, "ipv4"))
14653         ipv4_set = 1;
14654       else if (unformat (in, "ipv6"))
14655         ipv6_set = 1;
14656       else
14657         break;
14658     }
14659
14660   if (ipv4_set && ipv6_set)
14661     {
14662       errmsg ("ipv4 and ipv6 flags cannot be both set");
14663       return -99;
14664     }
14665
14666   if ((!ipv4_set) && (!ipv6_set))
14667     {
14668       errmsg ("no ipv4 nor ipv6 flag set");
14669       return -99;
14670     }
14671
14672   is_ipv6 = ipv6_set;
14673   vam->is_ipv6 = is_ipv6;
14674
14675   /* free old data */
14676   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14677     {
14678       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14679     }
14680   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14681
14682   M (IP_DUMP, mp);
14683   mp->is_ipv6 = ipv6_set;
14684   S (mp);
14685
14686   /* Use a control ping for synchronization */
14687   MPING (CONTROL_PING, mp_ping);
14688   S (mp_ping);
14689
14690   W (ret);
14691   return ret;
14692 }
14693
14694 static int
14695 api_ipsec_spd_add_del (vat_main_t * vam)
14696 {
14697   unformat_input_t *i = vam->input;
14698   vl_api_ipsec_spd_add_del_t *mp;
14699   u32 spd_id = ~0;
14700   u8 is_add = 1;
14701   int ret;
14702
14703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14704     {
14705       if (unformat (i, "spd_id %d", &spd_id))
14706         ;
14707       else if (unformat (i, "del"))
14708         is_add = 0;
14709       else
14710         {
14711           clib_warning ("parse error '%U'", format_unformat_error, i);
14712           return -99;
14713         }
14714     }
14715   if (spd_id == ~0)
14716     {
14717       errmsg ("spd_id must be set");
14718       return -99;
14719     }
14720
14721   M (IPSEC_SPD_ADD_DEL, mp);
14722
14723   mp->spd_id = ntohl (spd_id);
14724   mp->is_add = is_add;
14725
14726   S (mp);
14727   W (ret);
14728   return ret;
14729 }
14730
14731 static int
14732 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14733 {
14734   unformat_input_t *i = vam->input;
14735   vl_api_ipsec_interface_add_del_spd_t *mp;
14736   u32 sw_if_index;
14737   u8 sw_if_index_set = 0;
14738   u32 spd_id = (u32) ~ 0;
14739   u8 is_add = 1;
14740   int ret;
14741
14742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14743     {
14744       if (unformat (i, "del"))
14745         is_add = 0;
14746       else if (unformat (i, "spd_id %d", &spd_id))
14747         ;
14748       else
14749         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14750         sw_if_index_set = 1;
14751       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14752         sw_if_index_set = 1;
14753       else
14754         {
14755           clib_warning ("parse error '%U'", format_unformat_error, i);
14756           return -99;
14757         }
14758
14759     }
14760
14761   if (spd_id == (u32) ~ 0)
14762     {
14763       errmsg ("spd_id must be set");
14764       return -99;
14765     }
14766
14767   if (sw_if_index_set == 0)
14768     {
14769       errmsg ("missing interface name or sw_if_index");
14770       return -99;
14771     }
14772
14773   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14774
14775   mp->spd_id = ntohl (spd_id);
14776   mp->sw_if_index = ntohl (sw_if_index);
14777   mp->is_add = is_add;
14778
14779   S (mp);
14780   W (ret);
14781   return ret;
14782 }
14783
14784 static int
14785 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14786 {
14787   unformat_input_t *i = vam->input;
14788   vl_api_ipsec_spd_entry_add_del_t *mp;
14789   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14790   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14791   i32 priority = 0;
14792   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14793   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14794   vl_api_address_t laddr_start = { }, laddr_stop =
14795   {
14796   }, raddr_start =
14797   {
14798   }, raddr_stop =
14799   {
14800   };
14801   int ret;
14802
14803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14804     {
14805       if (unformat (i, "del"))
14806         is_add = 0;
14807       if (unformat (i, "outbound"))
14808         is_outbound = 1;
14809       if (unformat (i, "inbound"))
14810         is_outbound = 0;
14811       else if (unformat (i, "spd_id %d", &spd_id))
14812         ;
14813       else if (unformat (i, "sa_id %d", &sa_id))
14814         ;
14815       else if (unformat (i, "priority %d", &priority))
14816         ;
14817       else if (unformat (i, "protocol %d", &protocol))
14818         ;
14819       else if (unformat (i, "lport_start %d", &lport_start))
14820         ;
14821       else if (unformat (i, "lport_stop %d", &lport_stop))
14822         ;
14823       else if (unformat (i, "rport_start %d", &rport_start))
14824         ;
14825       else if (unformat (i, "rport_stop %d", &rport_stop))
14826         ;
14827       else if (unformat (i, "laddr_start %U",
14828                          unformat_vl_api_address, &laddr_start))
14829         is_ip_any = 0;
14830       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14831                          &laddr_stop))
14832         is_ip_any = 0;
14833       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14834                          &raddr_start))
14835         is_ip_any = 0;
14836       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14837                          &raddr_stop))
14838         is_ip_any = 0;
14839       else
14840         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14841         {
14842           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14843             {
14844               clib_warning ("unsupported action: 'resolve'");
14845               return -99;
14846             }
14847         }
14848       else
14849         {
14850           clib_warning ("parse error '%U'", format_unformat_error, i);
14851           return -99;
14852         }
14853
14854     }
14855
14856   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14857
14858   mp->is_add = is_add;
14859
14860   mp->entry.spd_id = ntohl (spd_id);
14861   mp->entry.priority = ntohl (priority);
14862   mp->entry.is_outbound = is_outbound;
14863
14864   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14865                sizeof (vl_api_address_t));
14866   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14867                sizeof (vl_api_address_t));
14868   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14869                sizeof (vl_api_address_t));
14870   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14871                sizeof (vl_api_address_t));
14872
14873   mp->entry.protocol = (u8) protocol;
14874   mp->entry.local_port_start = ntohs ((u16) lport_start);
14875   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14876   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14877   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14878   mp->entry.policy = (u8) policy;
14879   mp->entry.sa_id = ntohl (sa_id);
14880
14881   S (mp);
14882   W (ret);
14883   return ret;
14884 }
14885
14886 static int
14887 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14888 {
14889   unformat_input_t *i = vam->input;
14890   vl_api_ipsec_sad_entry_add_del_t *mp;
14891   u32 sad_id = 0, spi = 0;
14892   u8 *ck = 0, *ik = 0;
14893   u8 is_add = 1;
14894
14895   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14896   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14897   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14898   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14899   vl_api_address_t tun_src, tun_dst;
14900   int ret;
14901
14902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14903     {
14904       if (unformat (i, "del"))
14905         is_add = 0;
14906       else if (unformat (i, "sad_id %d", &sad_id))
14907         ;
14908       else if (unformat (i, "spi %d", &spi))
14909         ;
14910       else if (unformat (i, "esp"))
14911         protocol = IPSEC_API_PROTO_ESP;
14912       else
14913         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14914         {
14915           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14916           if (ADDRESS_IP6 == tun_src.af)
14917             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14918         }
14919       else
14920         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14921         {
14922           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14923           if (ADDRESS_IP6 == tun_src.af)
14924             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14925         }
14926       else
14927         if (unformat (i, "crypto_alg %U",
14928                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14929         ;
14930       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14931         ;
14932       else if (unformat (i, "integ_alg %U",
14933                          unformat_ipsec_api_integ_alg, &integ_alg))
14934         ;
14935       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14936         ;
14937       else
14938         {
14939           clib_warning ("parse error '%U'", format_unformat_error, i);
14940           return -99;
14941         }
14942
14943     }
14944
14945   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14946
14947   mp->is_add = is_add;
14948   mp->entry.sad_id = ntohl (sad_id);
14949   mp->entry.protocol = protocol;
14950   mp->entry.spi = ntohl (spi);
14951   mp->entry.flags = flags;
14952
14953   mp->entry.crypto_algorithm = crypto_alg;
14954   mp->entry.integrity_algorithm = integ_alg;
14955   mp->entry.crypto_key.length = vec_len (ck);
14956   mp->entry.integrity_key.length = vec_len (ik);
14957
14958   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14959     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14960
14961   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14962     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14963
14964   if (ck)
14965     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14966   if (ik)
14967     clib_memcpy (mp->entry.integrity_key.data, ik,
14968                  mp->entry.integrity_key.length);
14969
14970   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14971     {
14972       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14973                    sizeof (mp->entry.tunnel_src));
14974       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14975                    sizeof (mp->entry.tunnel_dst));
14976     }
14977
14978   S (mp);
14979   W (ret);
14980   return ret;
14981 }
14982
14983 static int
14984 api_ipsec_sa_set_key (vat_main_t * vam)
14985 {
14986   unformat_input_t *i = vam->input;
14987   vl_api_ipsec_sa_set_key_t *mp;
14988   u32 sa_id;
14989   u8 *ck = 0, *ik = 0;
14990   int ret;
14991
14992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14993     {
14994       if (unformat (i, "sa_id %d", &sa_id))
14995         ;
14996       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14997         ;
14998       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14999         ;
15000       else
15001         {
15002           clib_warning ("parse error '%U'", format_unformat_error, i);
15003           return -99;
15004         }
15005     }
15006
15007   M (IPSEC_SA_SET_KEY, mp);
15008
15009   mp->sa_id = ntohl (sa_id);
15010   mp->crypto_key.length = vec_len (ck);
15011   mp->integrity_key.length = vec_len (ik);
15012
15013   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15014     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15015
15016   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15017     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15018
15019   if (ck)
15020     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15021   if (ik)
15022     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15023
15024   S (mp);
15025   W (ret);
15026   return ret;
15027 }
15028
15029 static int
15030 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15031 {
15032   unformat_input_t *i = vam->input;
15033   vl_api_ipsec_tunnel_if_add_del_t *mp;
15034   u32 local_spi = 0, remote_spi = 0;
15035   u32 crypto_alg = 0, integ_alg = 0;
15036   u8 *lck = NULL, *rck = NULL;
15037   u8 *lik = NULL, *rik = NULL;
15038   vl_api_address_t local_ip = { 0 };
15039   vl_api_address_t remote_ip = { 0 };
15040   f64 before = 0;
15041   u8 is_add = 1;
15042   u8 esn = 0;
15043   u8 anti_replay = 0;
15044   u8 renumber = 0;
15045   u32 instance = ~0;
15046   u32 count = 1, jj;
15047   int ret;
15048
15049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15050     {
15051       if (unformat (i, "del"))
15052         is_add = 0;
15053       else if (unformat (i, "esn"))
15054         esn = 1;
15055       else if (unformat (i, "anti-replay"))
15056         anti_replay = 1;
15057       else if (unformat (i, "count %d", &count))
15058         ;
15059       else if (unformat (i, "local_spi %d", &local_spi))
15060         ;
15061       else if (unformat (i, "remote_spi %d", &remote_spi))
15062         ;
15063       else
15064         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
15065         ;
15066       else
15067         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
15068         ;
15069       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15070         ;
15071       else
15072         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15073         ;
15074       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15075         ;
15076       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15077         ;
15078       else
15079         if (unformat
15080             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15081         {
15082           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15083             {
15084               errmsg ("unsupported crypto-alg: '%U'\n",
15085                       format_ipsec_crypto_alg, crypto_alg);
15086               return -99;
15087             }
15088         }
15089       else
15090         if (unformat
15091             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15092         {
15093           if (integ_alg >= IPSEC_INTEG_N_ALG)
15094             {
15095               errmsg ("unsupported integ-alg: '%U'\n",
15096                       format_ipsec_integ_alg, integ_alg);
15097               return -99;
15098             }
15099         }
15100       else if (unformat (i, "instance %u", &instance))
15101         renumber = 1;
15102       else
15103         {
15104           errmsg ("parse error '%U'\n", format_unformat_error, i);
15105           return -99;
15106         }
15107     }
15108
15109   if (count > 1)
15110     {
15111       /* Turn on async mode */
15112       vam->async_mode = 1;
15113       vam->async_errors = 0;
15114       before = vat_time_now (vam);
15115     }
15116
15117   for (jj = 0; jj < count; jj++)
15118     {
15119       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15120
15121       mp->is_add = is_add;
15122       mp->esn = esn;
15123       mp->anti_replay = anti_replay;
15124
15125       if (jj > 0)
15126         increment_vl_address (&remote_ip);
15127
15128       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15129       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15130
15131       mp->local_spi = htonl (local_spi + jj);
15132       mp->remote_spi = htonl (remote_spi + jj);
15133       mp->crypto_alg = (u8) crypto_alg;
15134
15135       mp->local_crypto_key_len = 0;
15136       if (lck)
15137         {
15138           mp->local_crypto_key_len = vec_len (lck);
15139           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15140             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15141           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15142         }
15143
15144       mp->remote_crypto_key_len = 0;
15145       if (rck)
15146         {
15147           mp->remote_crypto_key_len = vec_len (rck);
15148           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15149             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15150           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15151         }
15152
15153       mp->integ_alg = (u8) integ_alg;
15154
15155       mp->local_integ_key_len = 0;
15156       if (lik)
15157         {
15158           mp->local_integ_key_len = vec_len (lik);
15159           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15160             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15161           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15162         }
15163
15164       mp->remote_integ_key_len = 0;
15165       if (rik)
15166         {
15167           mp->remote_integ_key_len = vec_len (rik);
15168           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15169             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15170           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15171         }
15172
15173       if (renumber)
15174         {
15175           mp->renumber = renumber;
15176           mp->show_instance = ntohl (instance);
15177         }
15178       S (mp);
15179     }
15180
15181   /* When testing multiple add/del ops, use a control-ping to sync */
15182   if (count > 1)
15183     {
15184       vl_api_control_ping_t *mp_ping;
15185       f64 after;
15186       f64 timeout;
15187
15188       /* Shut off async mode */
15189       vam->async_mode = 0;
15190
15191       MPING (CONTROL_PING, mp_ping);
15192       S (mp_ping);
15193
15194       timeout = vat_time_now (vam) + 1.0;
15195       while (vat_time_now (vam) < timeout)
15196         if (vam->result_ready == 1)
15197           goto out;
15198       vam->retval = -99;
15199
15200     out:
15201       if (vam->retval == -99)
15202         errmsg ("timeout");
15203
15204       if (vam->async_errors > 0)
15205         {
15206           errmsg ("%d asynchronous errors", vam->async_errors);
15207           vam->retval = -98;
15208         }
15209       vam->async_errors = 0;
15210       after = vat_time_now (vam);
15211
15212       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15213       if (jj > 0)
15214         count = jj;
15215
15216       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15217              count, after - before, count / (after - before));
15218     }
15219   else
15220     {
15221       /* Wait for a reply... */
15222       W (ret);
15223       return ret;
15224     }
15225
15226   return ret;
15227 }
15228
15229 static void
15230 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15231 {
15232   vat_main_t *vam = &vat_main;
15233
15234   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15235          "crypto_key %U integ_alg %u integ_key %U flags %x "
15236          "tunnel_src_addr %U tunnel_dst_addr %U "
15237          "salt %u seq_outbound %lu last_seq_inbound %lu "
15238          "replay_window %lu\n",
15239          ntohl (mp->entry.sad_id),
15240          ntohl (mp->sw_if_index),
15241          ntohl (mp->entry.spi),
15242          ntohl (mp->entry.protocol),
15243          ntohl (mp->entry.crypto_algorithm),
15244          format_hex_bytes, mp->entry.crypto_key.data,
15245          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15246          format_hex_bytes, mp->entry.integrity_key.data,
15247          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15248          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15249          &mp->entry.tunnel_dst, ntohl (mp->salt),
15250          clib_net_to_host_u64 (mp->seq_outbound),
15251          clib_net_to_host_u64 (mp->last_seq_inbound),
15252          clib_net_to_host_u64 (mp->replay_window));
15253 }
15254
15255 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15256 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15257
15258 static void vl_api_ipsec_sa_details_t_handler_json
15259   (vl_api_ipsec_sa_details_t * mp)
15260 {
15261   vat_main_t *vam = &vat_main;
15262   vat_json_node_t *node = NULL;
15263   vl_api_ipsec_sad_flags_t flags;
15264
15265   if (VAT_JSON_ARRAY != vam->json_tree.type)
15266     {
15267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15268       vat_json_init_array (&vam->json_tree);
15269     }
15270   node = vat_json_array_add (&vam->json_tree);
15271
15272   vat_json_init_object (node);
15273   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15275   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15276   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15277   vat_json_object_add_uint (node, "crypto_alg",
15278                             ntohl (mp->entry.crypto_algorithm));
15279   vat_json_object_add_uint (node, "integ_alg",
15280                             ntohl (mp->entry.integrity_algorithm));
15281   flags = ntohl (mp->entry.flags);
15282   vat_json_object_add_uint (node, "use_esn",
15283                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15284   vat_json_object_add_uint (node, "use_anti_replay",
15285                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15286   vat_json_object_add_uint (node, "is_tunnel",
15287                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15288   vat_json_object_add_uint (node, "is_tunnel_ip6",
15289                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15290   vat_json_object_add_uint (node, "udp_encap",
15291                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15292   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15293                              mp->entry.crypto_key.length);
15294   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15295                              mp->entry.integrity_key.length);
15296   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15297   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15298   vat_json_object_add_uint (node, "replay_window",
15299                             clib_net_to_host_u64 (mp->replay_window));
15300 }
15301
15302 static int
15303 api_ipsec_sa_dump (vat_main_t * vam)
15304 {
15305   unformat_input_t *i = vam->input;
15306   vl_api_ipsec_sa_dump_t *mp;
15307   vl_api_control_ping_t *mp_ping;
15308   u32 sa_id = ~0;
15309   int ret;
15310
15311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15312     {
15313       if (unformat (i, "sa_id %d", &sa_id))
15314         ;
15315       else
15316         {
15317           clib_warning ("parse error '%U'", format_unformat_error, i);
15318           return -99;
15319         }
15320     }
15321
15322   M (IPSEC_SA_DUMP, mp);
15323
15324   mp->sa_id = ntohl (sa_id);
15325
15326   S (mp);
15327
15328   /* Use a control ping for synchronization */
15329   M (CONTROL_PING, mp_ping);
15330   S (mp_ping);
15331
15332   W (ret);
15333   return ret;
15334 }
15335
15336 static int
15337 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15338 {
15339   unformat_input_t *i = vam->input;
15340   vl_api_ipsec_tunnel_if_set_key_t *mp;
15341   u32 sw_if_index = ~0;
15342   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15343   u8 *key = 0;
15344   u32 alg = ~0;
15345   int ret;
15346
15347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15348     {
15349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15350         ;
15351       else
15352         if (unformat
15353             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15354         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15355       else
15356         if (unformat
15357             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15358         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15359       else
15360         if (unformat
15361             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15362         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15363       else
15364         if (unformat
15365             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15366         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15367       else if (unformat (i, "%U", unformat_hex_string, &key))
15368         ;
15369       else
15370         {
15371           clib_warning ("parse error '%U'", format_unformat_error, i);
15372           return -99;
15373         }
15374     }
15375
15376   if (sw_if_index == ~0)
15377     {
15378       errmsg ("interface must be specified");
15379       return -99;
15380     }
15381
15382   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15383     {
15384       errmsg ("key type must be specified");
15385       return -99;
15386     }
15387
15388   if (alg == ~0)
15389     {
15390       errmsg ("algorithm must be specified");
15391       return -99;
15392     }
15393
15394   if (vec_len (key) == 0)
15395     {
15396       errmsg ("key must be specified");
15397       return -99;
15398     }
15399
15400   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15401
15402   mp->sw_if_index = htonl (sw_if_index);
15403   mp->alg = alg;
15404   mp->key_type = key_type;
15405   mp->key_len = vec_len (key);
15406   clib_memcpy (mp->key, key, vec_len (key));
15407
15408   S (mp);
15409   W (ret);
15410
15411   return ret;
15412 }
15413
15414 static int
15415 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15416 {
15417   unformat_input_t *i = vam->input;
15418   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15419   u32 sw_if_index = ~0;
15420   u32 sa_id = ~0;
15421   u8 is_outbound = (u8) ~ 0;
15422   int ret;
15423
15424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15425     {
15426       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15427         ;
15428       else if (unformat (i, "sa_id %d", &sa_id))
15429         ;
15430       else if (unformat (i, "outbound"))
15431         is_outbound = 1;
15432       else if (unformat (i, "inbound"))
15433         is_outbound = 0;
15434       else
15435         {
15436           clib_warning ("parse error '%U'", format_unformat_error, i);
15437           return -99;
15438         }
15439     }
15440
15441   if (sw_if_index == ~0)
15442     {
15443       errmsg ("interface must be specified");
15444       return -99;
15445     }
15446
15447   if (sa_id == ~0)
15448     {
15449       errmsg ("SA ID must be specified");
15450       return -99;
15451     }
15452
15453   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15454
15455   mp->sw_if_index = htonl (sw_if_index);
15456   mp->sa_id = htonl (sa_id);
15457   mp->is_outbound = is_outbound;
15458
15459   S (mp);
15460   W (ret);
15461
15462   return ret;
15463 }
15464
15465 static int
15466 api_get_first_msg_id (vat_main_t * vam)
15467 {
15468   vl_api_get_first_msg_id_t *mp;
15469   unformat_input_t *i = vam->input;
15470   u8 *name;
15471   u8 name_set = 0;
15472   int ret;
15473
15474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15475     {
15476       if (unformat (i, "client %s", &name))
15477         name_set = 1;
15478       else
15479         break;
15480     }
15481
15482   if (name_set == 0)
15483     {
15484       errmsg ("missing client name");
15485       return -99;
15486     }
15487   vec_add1 (name, 0);
15488
15489   if (vec_len (name) > 63)
15490     {
15491       errmsg ("client name too long");
15492       return -99;
15493     }
15494
15495   M (GET_FIRST_MSG_ID, mp);
15496   clib_memcpy (mp->name, name, vec_len (name));
15497   S (mp);
15498   W (ret);
15499   return ret;
15500 }
15501
15502 static int
15503 api_cop_interface_enable_disable (vat_main_t * vam)
15504 {
15505   unformat_input_t *line_input = vam->input;
15506   vl_api_cop_interface_enable_disable_t *mp;
15507   u32 sw_if_index = ~0;
15508   u8 enable_disable = 1;
15509   int ret;
15510
15511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15512     {
15513       if (unformat (line_input, "disable"))
15514         enable_disable = 0;
15515       if (unformat (line_input, "enable"))
15516         enable_disable = 1;
15517       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15518                          vam, &sw_if_index))
15519         ;
15520       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15521         ;
15522       else
15523         break;
15524     }
15525
15526   if (sw_if_index == ~0)
15527     {
15528       errmsg ("missing interface name or sw_if_index");
15529       return -99;
15530     }
15531
15532   /* Construct the API message */
15533   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15534   mp->sw_if_index = ntohl (sw_if_index);
15535   mp->enable_disable = enable_disable;
15536
15537   /* send it... */
15538   S (mp);
15539   /* Wait for the reply */
15540   W (ret);
15541   return ret;
15542 }
15543
15544 static int
15545 api_cop_whitelist_enable_disable (vat_main_t * vam)
15546 {
15547   unformat_input_t *line_input = vam->input;
15548   vl_api_cop_whitelist_enable_disable_t *mp;
15549   u32 sw_if_index = ~0;
15550   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15551   u32 fib_id = 0;
15552   int ret;
15553
15554   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15555     {
15556       if (unformat (line_input, "ip4"))
15557         ip4 = 1;
15558       else if (unformat (line_input, "ip6"))
15559         ip6 = 1;
15560       else if (unformat (line_input, "default"))
15561         default_cop = 1;
15562       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15563                          vam, &sw_if_index))
15564         ;
15565       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15566         ;
15567       else if (unformat (line_input, "fib-id %d", &fib_id))
15568         ;
15569       else
15570         break;
15571     }
15572
15573   if (sw_if_index == ~0)
15574     {
15575       errmsg ("missing interface name or sw_if_index");
15576       return -99;
15577     }
15578
15579   /* Construct the API message */
15580   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15581   mp->sw_if_index = ntohl (sw_if_index);
15582   mp->fib_id = ntohl (fib_id);
15583   mp->ip4 = ip4;
15584   mp->ip6 = ip6;
15585   mp->default_cop = default_cop;
15586
15587   /* send it... */
15588   S (mp);
15589   /* Wait for the reply */
15590   W (ret);
15591   return ret;
15592 }
15593
15594 static int
15595 api_get_node_graph (vat_main_t * vam)
15596 {
15597   vl_api_get_node_graph_t *mp;
15598   int ret;
15599
15600   M (GET_NODE_GRAPH, mp);
15601
15602   /* send it... */
15603   S (mp);
15604   /* Wait for the reply */
15605   W (ret);
15606   return ret;
15607 }
15608
15609 /* *INDENT-OFF* */
15610 /** Used for parsing LISP eids */
15611 typedef CLIB_PACKED(struct{
15612   u8 addr[16];   /**< eid address */
15613   u32 len;       /**< prefix length if IP */
15614   u8 type;      /**< type of eid */
15615 }) lisp_eid_vat_t;
15616 /* *INDENT-ON* */
15617
15618 static uword
15619 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15620 {
15621   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15622
15623   clib_memset (a, 0, sizeof (a[0]));
15624
15625   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15626     {
15627       a->type = 0;              /* ipv4 type */
15628     }
15629   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15630     {
15631       a->type = 1;              /* ipv6 type */
15632     }
15633   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15634     {
15635       a->type = 2;              /* mac type */
15636     }
15637   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15638     {
15639       a->type = 3;              /* NSH type */
15640       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15641       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15642     }
15643   else
15644     {
15645       return 0;
15646     }
15647
15648   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15649     {
15650       return 0;
15651     }
15652
15653   return 1;
15654 }
15655
15656 static int
15657 lisp_eid_size_vat (u8 type)
15658 {
15659   switch (type)
15660     {
15661     case 0:
15662       return 4;
15663     case 1:
15664       return 16;
15665     case 2:
15666       return 6;
15667     case 3:
15668       return 5;
15669     }
15670   return 0;
15671 }
15672
15673 static void
15674 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15675 {
15676   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15677 }
15678
15679 static int
15680 api_one_add_del_locator_set (vat_main_t * vam)
15681 {
15682   unformat_input_t *input = vam->input;
15683   vl_api_one_add_del_locator_set_t *mp;
15684   u8 is_add = 1;
15685   u8 *locator_set_name = NULL;
15686   u8 locator_set_name_set = 0;
15687   vl_api_local_locator_t locator, *locators = 0;
15688   u32 sw_if_index, priority, weight;
15689   u32 data_len = 0;
15690
15691   int ret;
15692   /* Parse args required to build the message */
15693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15694     {
15695       if (unformat (input, "del"))
15696         {
15697           is_add = 0;
15698         }
15699       else if (unformat (input, "locator-set %s", &locator_set_name))
15700         {
15701           locator_set_name_set = 1;
15702         }
15703       else if (unformat (input, "sw_if_index %u p %u w %u",
15704                          &sw_if_index, &priority, &weight))
15705         {
15706           locator.sw_if_index = htonl (sw_if_index);
15707           locator.priority = priority;
15708           locator.weight = weight;
15709           vec_add1 (locators, locator);
15710         }
15711       else
15712         if (unformat
15713             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15714              &sw_if_index, &priority, &weight))
15715         {
15716           locator.sw_if_index = htonl (sw_if_index);
15717           locator.priority = priority;
15718           locator.weight = weight;
15719           vec_add1 (locators, locator);
15720         }
15721       else
15722         break;
15723     }
15724
15725   if (locator_set_name_set == 0)
15726     {
15727       errmsg ("missing locator-set name");
15728       vec_free (locators);
15729       return -99;
15730     }
15731
15732   if (vec_len (locator_set_name) > 64)
15733     {
15734       errmsg ("locator-set name too long");
15735       vec_free (locator_set_name);
15736       vec_free (locators);
15737       return -99;
15738     }
15739   vec_add1 (locator_set_name, 0);
15740
15741   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15742
15743   /* Construct the API message */
15744   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15745
15746   mp->is_add = is_add;
15747   clib_memcpy (mp->locator_set_name, locator_set_name,
15748                vec_len (locator_set_name));
15749   vec_free (locator_set_name);
15750
15751   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15752   if (locators)
15753     clib_memcpy (mp->locators, locators, data_len);
15754   vec_free (locators);
15755
15756   /* send it... */
15757   S (mp);
15758
15759   /* Wait for a reply... */
15760   W (ret);
15761   return ret;
15762 }
15763
15764 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15765
15766 static int
15767 api_one_add_del_locator (vat_main_t * vam)
15768 {
15769   unformat_input_t *input = vam->input;
15770   vl_api_one_add_del_locator_t *mp;
15771   u32 tmp_if_index = ~0;
15772   u32 sw_if_index = ~0;
15773   u8 sw_if_index_set = 0;
15774   u8 sw_if_index_if_name_set = 0;
15775   u32 priority = ~0;
15776   u8 priority_set = 0;
15777   u32 weight = ~0;
15778   u8 weight_set = 0;
15779   u8 is_add = 1;
15780   u8 *locator_set_name = NULL;
15781   u8 locator_set_name_set = 0;
15782   int ret;
15783
15784   /* Parse args required to build the message */
15785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15786     {
15787       if (unformat (input, "del"))
15788         {
15789           is_add = 0;
15790         }
15791       else if (unformat (input, "locator-set %s", &locator_set_name))
15792         {
15793           locator_set_name_set = 1;
15794         }
15795       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15796                          &tmp_if_index))
15797         {
15798           sw_if_index_if_name_set = 1;
15799           sw_if_index = tmp_if_index;
15800         }
15801       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15802         {
15803           sw_if_index_set = 1;
15804           sw_if_index = tmp_if_index;
15805         }
15806       else if (unformat (input, "p %d", &priority))
15807         {
15808           priority_set = 1;
15809         }
15810       else if (unformat (input, "w %d", &weight))
15811         {
15812           weight_set = 1;
15813         }
15814       else
15815         break;
15816     }
15817
15818   if (locator_set_name_set == 0)
15819     {
15820       errmsg ("missing locator-set name");
15821       return -99;
15822     }
15823
15824   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15825     {
15826       errmsg ("missing sw_if_index");
15827       vec_free (locator_set_name);
15828       return -99;
15829     }
15830
15831   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15832     {
15833       errmsg ("cannot use both params interface name and sw_if_index");
15834       vec_free (locator_set_name);
15835       return -99;
15836     }
15837
15838   if (priority_set == 0)
15839     {
15840       errmsg ("missing locator-set priority");
15841       vec_free (locator_set_name);
15842       return -99;
15843     }
15844
15845   if (weight_set == 0)
15846     {
15847       errmsg ("missing locator-set weight");
15848       vec_free (locator_set_name);
15849       return -99;
15850     }
15851
15852   if (vec_len (locator_set_name) > 64)
15853     {
15854       errmsg ("locator-set name too long");
15855       vec_free (locator_set_name);
15856       return -99;
15857     }
15858   vec_add1 (locator_set_name, 0);
15859
15860   /* Construct the API message */
15861   M (ONE_ADD_DEL_LOCATOR, mp);
15862
15863   mp->is_add = is_add;
15864   mp->sw_if_index = ntohl (sw_if_index);
15865   mp->priority = priority;
15866   mp->weight = weight;
15867   clib_memcpy (mp->locator_set_name, locator_set_name,
15868                vec_len (locator_set_name));
15869   vec_free (locator_set_name);
15870
15871   /* send it... */
15872   S (mp);
15873
15874   /* Wait for a reply... */
15875   W (ret);
15876   return ret;
15877 }
15878
15879 #define api_lisp_add_del_locator api_one_add_del_locator
15880
15881 uword
15882 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15883 {
15884   u32 *key_id = va_arg (*args, u32 *);
15885   u8 *s = 0;
15886
15887   if (unformat (input, "%s", &s))
15888     {
15889       if (!strcmp ((char *) s, "sha1"))
15890         key_id[0] = HMAC_SHA_1_96;
15891       else if (!strcmp ((char *) s, "sha256"))
15892         key_id[0] = HMAC_SHA_256_128;
15893       else
15894         {
15895           clib_warning ("invalid key_id: '%s'", s);
15896           key_id[0] = HMAC_NO_KEY;
15897         }
15898     }
15899   else
15900     return 0;
15901
15902   vec_free (s);
15903   return 1;
15904 }
15905
15906 static int
15907 api_one_add_del_local_eid (vat_main_t * vam)
15908 {
15909   unformat_input_t *input = vam->input;
15910   vl_api_one_add_del_local_eid_t *mp;
15911   u8 is_add = 1;
15912   u8 eid_set = 0;
15913   lisp_eid_vat_t _eid, *eid = &_eid;
15914   u8 *locator_set_name = 0;
15915   u8 locator_set_name_set = 0;
15916   u32 vni = 0;
15917   u16 key_id = 0;
15918   u8 *key = 0;
15919   int ret;
15920
15921   /* Parse args required to build the message */
15922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15923     {
15924       if (unformat (input, "del"))
15925         {
15926           is_add = 0;
15927         }
15928       else if (unformat (input, "vni %d", &vni))
15929         {
15930           ;
15931         }
15932       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15933         {
15934           eid_set = 1;
15935         }
15936       else if (unformat (input, "locator-set %s", &locator_set_name))
15937         {
15938           locator_set_name_set = 1;
15939         }
15940       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15941         ;
15942       else if (unformat (input, "secret-key %_%v%_", &key))
15943         ;
15944       else
15945         break;
15946     }
15947
15948   if (locator_set_name_set == 0)
15949     {
15950       errmsg ("missing locator-set name");
15951       return -99;
15952     }
15953
15954   if (0 == eid_set)
15955     {
15956       errmsg ("EID address not set!");
15957       vec_free (locator_set_name);
15958       return -99;
15959     }
15960
15961   if (key && (0 == key_id))
15962     {
15963       errmsg ("invalid key_id!");
15964       return -99;
15965     }
15966
15967   if (vec_len (key) > 64)
15968     {
15969       errmsg ("key too long");
15970       vec_free (key);
15971       return -99;
15972     }
15973
15974   if (vec_len (locator_set_name) > 64)
15975     {
15976       errmsg ("locator-set name too long");
15977       vec_free (locator_set_name);
15978       return -99;
15979     }
15980   vec_add1 (locator_set_name, 0);
15981
15982   /* Construct the API message */
15983   M (ONE_ADD_DEL_LOCAL_EID, mp);
15984
15985   mp->is_add = is_add;
15986   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15987   mp->eid_type = eid->type;
15988   mp->prefix_len = eid->len;
15989   mp->vni = clib_host_to_net_u32 (vni);
15990   mp->key_id = clib_host_to_net_u16 (key_id);
15991   clib_memcpy (mp->locator_set_name, locator_set_name,
15992                vec_len (locator_set_name));
15993   clib_memcpy (mp->key, key, vec_len (key));
15994
15995   vec_free (locator_set_name);
15996   vec_free (key);
15997
15998   /* send it... */
15999   S (mp);
16000
16001   /* Wait for a reply... */
16002   W (ret);
16003   return ret;
16004 }
16005
16006 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16007
16008 static int
16009 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16010 {
16011   u32 dp_table = 0, vni = 0;;
16012   unformat_input_t *input = vam->input;
16013   vl_api_gpe_add_del_fwd_entry_t *mp;
16014   u8 is_add = 1;
16015   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16016   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16017   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16018   u32 action = ~0, w;
16019   ip4_address_t rmt_rloc4, lcl_rloc4;
16020   ip6_address_t rmt_rloc6, lcl_rloc6;
16021   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16022   int ret;
16023
16024   clib_memset (&rloc, 0, sizeof (rloc));
16025
16026   /* Parse args required to build the message */
16027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16028     {
16029       if (unformat (input, "del"))
16030         is_add = 0;
16031       else if (unformat (input, "add"))
16032         is_add = 1;
16033       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16034         {
16035           rmt_eid_set = 1;
16036         }
16037       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16038         {
16039           lcl_eid_set = 1;
16040         }
16041       else if (unformat (input, "vrf %d", &dp_table))
16042         ;
16043       else if (unformat (input, "bd %d", &dp_table))
16044         ;
16045       else if (unformat (input, "vni %d", &vni))
16046         ;
16047       else if (unformat (input, "w %d", &w))
16048         {
16049           if (!curr_rloc)
16050             {
16051               errmsg ("No RLOC configured for setting priority/weight!");
16052               return -99;
16053             }
16054           curr_rloc->weight = w;
16055         }
16056       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16057                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16058         {
16059           rloc.is_ip4 = 1;
16060
16061           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16062           rloc.weight = 0;
16063           vec_add1 (lcl_locs, rloc);
16064
16065           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16066           vec_add1 (rmt_locs, rloc);
16067           /* weight saved in rmt loc */
16068           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16069         }
16070       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16071                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16072         {
16073           rloc.is_ip4 = 0;
16074           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16075           rloc.weight = 0;
16076           vec_add1 (lcl_locs, rloc);
16077
16078           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16079           vec_add1 (rmt_locs, rloc);
16080           /* weight saved in rmt loc */
16081           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16082         }
16083       else if (unformat (input, "action %d", &action))
16084         {
16085           ;
16086         }
16087       else
16088         {
16089           clib_warning ("parse error '%U'", format_unformat_error, input);
16090           return -99;
16091         }
16092     }
16093
16094   if (!rmt_eid_set)
16095     {
16096       errmsg ("remote eid addresses not set");
16097       return -99;
16098     }
16099
16100   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16101     {
16102       errmsg ("eid types don't match");
16103       return -99;
16104     }
16105
16106   if (0 == rmt_locs && (u32) ~ 0 == action)
16107     {
16108       errmsg ("action not set for negative mapping");
16109       return -99;
16110     }
16111
16112   /* Construct the API message */
16113   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16114       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16115
16116   mp->is_add = is_add;
16117   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16118   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16119   mp->eid_type = rmt_eid->type;
16120   mp->dp_table = clib_host_to_net_u32 (dp_table);
16121   mp->vni = clib_host_to_net_u32 (vni);
16122   mp->rmt_len = rmt_eid->len;
16123   mp->lcl_len = lcl_eid->len;
16124   mp->action = action;
16125
16126   if (0 != rmt_locs && 0 != lcl_locs)
16127     {
16128       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16129       clib_memcpy (mp->locs, lcl_locs,
16130                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16131
16132       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16133       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16134                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16135     }
16136   vec_free (lcl_locs);
16137   vec_free (rmt_locs);
16138
16139   /* send it... */
16140   S (mp);
16141
16142   /* Wait for a reply... */
16143   W (ret);
16144   return ret;
16145 }
16146
16147 static int
16148 api_one_add_del_map_server (vat_main_t * vam)
16149 {
16150   unformat_input_t *input = vam->input;
16151   vl_api_one_add_del_map_server_t *mp;
16152   u8 is_add = 1;
16153   u8 ipv4_set = 0;
16154   u8 ipv6_set = 0;
16155   ip4_address_t ipv4;
16156   ip6_address_t ipv6;
16157   int ret;
16158
16159   /* Parse args required to build the message */
16160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16161     {
16162       if (unformat (input, "del"))
16163         {
16164           is_add = 0;
16165         }
16166       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16167         {
16168           ipv4_set = 1;
16169         }
16170       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16171         {
16172           ipv6_set = 1;
16173         }
16174       else
16175         break;
16176     }
16177
16178   if (ipv4_set && ipv6_set)
16179     {
16180       errmsg ("both eid v4 and v6 addresses set");
16181       return -99;
16182     }
16183
16184   if (!ipv4_set && !ipv6_set)
16185     {
16186       errmsg ("eid addresses not set");
16187       return -99;
16188     }
16189
16190   /* Construct the API message */
16191   M (ONE_ADD_DEL_MAP_SERVER, mp);
16192
16193   mp->is_add = is_add;
16194   if (ipv6_set)
16195     {
16196       mp->is_ipv6 = 1;
16197       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16198     }
16199   else
16200     {
16201       mp->is_ipv6 = 0;
16202       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16203     }
16204
16205   /* send it... */
16206   S (mp);
16207
16208   /* Wait for a reply... */
16209   W (ret);
16210   return ret;
16211 }
16212
16213 #define api_lisp_add_del_map_server api_one_add_del_map_server
16214
16215 static int
16216 api_one_add_del_map_resolver (vat_main_t * vam)
16217 {
16218   unformat_input_t *input = vam->input;
16219   vl_api_one_add_del_map_resolver_t *mp;
16220   u8 is_add = 1;
16221   u8 ipv4_set = 0;
16222   u8 ipv6_set = 0;
16223   ip4_address_t ipv4;
16224   ip6_address_t ipv6;
16225   int ret;
16226
16227   /* Parse args required to build the message */
16228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16229     {
16230       if (unformat (input, "del"))
16231         {
16232           is_add = 0;
16233         }
16234       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16235         {
16236           ipv4_set = 1;
16237         }
16238       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16239         {
16240           ipv6_set = 1;
16241         }
16242       else
16243         break;
16244     }
16245
16246   if (ipv4_set && ipv6_set)
16247     {
16248       errmsg ("both eid v4 and v6 addresses set");
16249       return -99;
16250     }
16251
16252   if (!ipv4_set && !ipv6_set)
16253     {
16254       errmsg ("eid addresses not set");
16255       return -99;
16256     }
16257
16258   /* Construct the API message */
16259   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16260
16261   mp->is_add = is_add;
16262   if (ipv6_set)
16263     {
16264       mp->is_ipv6 = 1;
16265       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16266     }
16267   else
16268     {
16269       mp->is_ipv6 = 0;
16270       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16271     }
16272
16273   /* send it... */
16274   S (mp);
16275
16276   /* Wait for a reply... */
16277   W (ret);
16278   return ret;
16279 }
16280
16281 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16282
16283 static int
16284 api_lisp_gpe_enable_disable (vat_main_t * vam)
16285 {
16286   unformat_input_t *input = vam->input;
16287   vl_api_gpe_enable_disable_t *mp;
16288   u8 is_set = 0;
16289   u8 is_en = 1;
16290   int ret;
16291
16292   /* Parse args required to build the message */
16293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16294     {
16295       if (unformat (input, "enable"))
16296         {
16297           is_set = 1;
16298           is_en = 1;
16299         }
16300       else if (unformat (input, "disable"))
16301         {
16302           is_set = 1;
16303           is_en = 0;
16304         }
16305       else
16306         break;
16307     }
16308
16309   if (is_set == 0)
16310     {
16311       errmsg ("Value not set");
16312       return -99;
16313     }
16314
16315   /* Construct the API message */
16316   M (GPE_ENABLE_DISABLE, mp);
16317
16318   mp->is_en = is_en;
16319
16320   /* send it... */
16321   S (mp);
16322
16323   /* Wait for a reply... */
16324   W (ret);
16325   return ret;
16326 }
16327
16328 static int
16329 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16330 {
16331   unformat_input_t *input = vam->input;
16332   vl_api_one_rloc_probe_enable_disable_t *mp;
16333   u8 is_set = 0;
16334   u8 is_en = 0;
16335   int ret;
16336
16337   /* Parse args required to build the message */
16338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16339     {
16340       if (unformat (input, "enable"))
16341         {
16342           is_set = 1;
16343           is_en = 1;
16344         }
16345       else if (unformat (input, "disable"))
16346         is_set = 1;
16347       else
16348         break;
16349     }
16350
16351   if (!is_set)
16352     {
16353       errmsg ("Value not set");
16354       return -99;
16355     }
16356
16357   /* Construct the API message */
16358   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16359
16360   mp->is_enabled = is_en;
16361
16362   /* send it... */
16363   S (mp);
16364
16365   /* Wait for a reply... */
16366   W (ret);
16367   return ret;
16368 }
16369
16370 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16371
16372 static int
16373 api_one_map_register_enable_disable (vat_main_t * vam)
16374 {
16375   unformat_input_t *input = vam->input;
16376   vl_api_one_map_register_enable_disable_t *mp;
16377   u8 is_set = 0;
16378   u8 is_en = 0;
16379   int ret;
16380
16381   /* Parse args required to build the message */
16382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16383     {
16384       if (unformat (input, "enable"))
16385         {
16386           is_set = 1;
16387           is_en = 1;
16388         }
16389       else if (unformat (input, "disable"))
16390         is_set = 1;
16391       else
16392         break;
16393     }
16394
16395   if (!is_set)
16396     {
16397       errmsg ("Value not set");
16398       return -99;
16399     }
16400
16401   /* Construct the API message */
16402   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16403
16404   mp->is_enabled = is_en;
16405
16406   /* send it... */
16407   S (mp);
16408
16409   /* Wait for a reply... */
16410   W (ret);
16411   return ret;
16412 }
16413
16414 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16415
16416 static int
16417 api_one_enable_disable (vat_main_t * vam)
16418 {
16419   unformat_input_t *input = vam->input;
16420   vl_api_one_enable_disable_t *mp;
16421   u8 is_set = 0;
16422   u8 is_en = 0;
16423   int ret;
16424
16425   /* Parse args required to build the message */
16426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16427     {
16428       if (unformat (input, "enable"))
16429         {
16430           is_set = 1;
16431           is_en = 1;
16432         }
16433       else if (unformat (input, "disable"))
16434         {
16435           is_set = 1;
16436         }
16437       else
16438         break;
16439     }
16440
16441   if (!is_set)
16442     {
16443       errmsg ("Value not set");
16444       return -99;
16445     }
16446
16447   /* Construct the API message */
16448   M (ONE_ENABLE_DISABLE, mp);
16449
16450   mp->is_en = is_en;
16451
16452   /* send it... */
16453   S (mp);
16454
16455   /* Wait for a reply... */
16456   W (ret);
16457   return ret;
16458 }
16459
16460 #define api_lisp_enable_disable api_one_enable_disable
16461
16462 static int
16463 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16464 {
16465   unformat_input_t *input = vam->input;
16466   vl_api_one_enable_disable_xtr_mode_t *mp;
16467   u8 is_set = 0;
16468   u8 is_en = 0;
16469   int ret;
16470
16471   /* Parse args required to build the message */
16472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16473     {
16474       if (unformat (input, "enable"))
16475         {
16476           is_set = 1;
16477           is_en = 1;
16478         }
16479       else if (unformat (input, "disable"))
16480         {
16481           is_set = 1;
16482         }
16483       else
16484         break;
16485     }
16486
16487   if (!is_set)
16488     {
16489       errmsg ("Value not set");
16490       return -99;
16491     }
16492
16493   /* Construct the API message */
16494   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16495
16496   mp->is_en = is_en;
16497
16498   /* send it... */
16499   S (mp);
16500
16501   /* Wait for a reply... */
16502   W (ret);
16503   return ret;
16504 }
16505
16506 static int
16507 api_one_show_xtr_mode (vat_main_t * vam)
16508 {
16509   vl_api_one_show_xtr_mode_t *mp;
16510   int ret;
16511
16512   /* Construct the API message */
16513   M (ONE_SHOW_XTR_MODE, mp);
16514
16515   /* send it... */
16516   S (mp);
16517
16518   /* Wait for a reply... */
16519   W (ret);
16520   return ret;
16521 }
16522
16523 static int
16524 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16525 {
16526   unformat_input_t *input = vam->input;
16527   vl_api_one_enable_disable_pitr_mode_t *mp;
16528   u8 is_set = 0;
16529   u8 is_en = 0;
16530   int ret;
16531
16532   /* Parse args required to build the message */
16533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16534     {
16535       if (unformat (input, "enable"))
16536         {
16537           is_set = 1;
16538           is_en = 1;
16539         }
16540       else if (unformat (input, "disable"))
16541         {
16542           is_set = 1;
16543         }
16544       else
16545         break;
16546     }
16547
16548   if (!is_set)
16549     {
16550       errmsg ("Value not set");
16551       return -99;
16552     }
16553
16554   /* Construct the API message */
16555   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16556
16557   mp->is_en = is_en;
16558
16559   /* send it... */
16560   S (mp);
16561
16562   /* Wait for a reply... */
16563   W (ret);
16564   return ret;
16565 }
16566
16567 static int
16568 api_one_show_pitr_mode (vat_main_t * vam)
16569 {
16570   vl_api_one_show_pitr_mode_t *mp;
16571   int ret;
16572
16573   /* Construct the API message */
16574   M (ONE_SHOW_PITR_MODE, mp);
16575
16576   /* send it... */
16577   S (mp);
16578
16579   /* Wait for a reply... */
16580   W (ret);
16581   return ret;
16582 }
16583
16584 static int
16585 api_one_enable_disable_petr_mode (vat_main_t * vam)
16586 {
16587   unformat_input_t *input = vam->input;
16588   vl_api_one_enable_disable_petr_mode_t *mp;
16589   u8 is_set = 0;
16590   u8 is_en = 0;
16591   int ret;
16592
16593   /* Parse args required to build the message */
16594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16595     {
16596       if (unformat (input, "enable"))
16597         {
16598           is_set = 1;
16599           is_en = 1;
16600         }
16601       else if (unformat (input, "disable"))
16602         {
16603           is_set = 1;
16604         }
16605       else
16606         break;
16607     }
16608
16609   if (!is_set)
16610     {
16611       errmsg ("Value not set");
16612       return -99;
16613     }
16614
16615   /* Construct the API message */
16616   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16617
16618   mp->is_en = is_en;
16619
16620   /* send it... */
16621   S (mp);
16622
16623   /* Wait for a reply... */
16624   W (ret);
16625   return ret;
16626 }
16627
16628 static int
16629 api_one_show_petr_mode (vat_main_t * vam)
16630 {
16631   vl_api_one_show_petr_mode_t *mp;
16632   int ret;
16633
16634   /* Construct the API message */
16635   M (ONE_SHOW_PETR_MODE, mp);
16636
16637   /* send it... */
16638   S (mp);
16639
16640   /* Wait for a reply... */
16641   W (ret);
16642   return ret;
16643 }
16644
16645 static int
16646 api_show_one_map_register_state (vat_main_t * vam)
16647 {
16648   vl_api_show_one_map_register_state_t *mp;
16649   int ret;
16650
16651   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16652
16653   /* send */
16654   S (mp);
16655
16656   /* wait for reply */
16657   W (ret);
16658   return ret;
16659 }
16660
16661 #define api_show_lisp_map_register_state api_show_one_map_register_state
16662
16663 static int
16664 api_show_one_rloc_probe_state (vat_main_t * vam)
16665 {
16666   vl_api_show_one_rloc_probe_state_t *mp;
16667   int ret;
16668
16669   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16670
16671   /* send */
16672   S (mp);
16673
16674   /* wait for reply */
16675   W (ret);
16676   return ret;
16677 }
16678
16679 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16680
16681 static int
16682 api_one_add_del_ndp_entry (vat_main_t * vam)
16683 {
16684   vl_api_one_add_del_ndp_entry_t *mp;
16685   unformat_input_t *input = vam->input;
16686   u8 is_add = 1;
16687   u8 mac_set = 0;
16688   u8 bd_set = 0;
16689   u8 ip_set = 0;
16690   u8 mac[6] = { 0, };
16691   u8 ip6[16] = { 0, };
16692   u32 bd = ~0;
16693   int ret;
16694
16695   /* Parse args required to build the message */
16696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16697     {
16698       if (unformat (input, "del"))
16699         is_add = 0;
16700       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16701         mac_set = 1;
16702       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16703         ip_set = 1;
16704       else if (unformat (input, "bd %d", &bd))
16705         bd_set = 1;
16706       else
16707         {
16708           errmsg ("parse error '%U'", format_unformat_error, input);
16709           return -99;
16710         }
16711     }
16712
16713   if (!bd_set || !ip_set || (!mac_set && is_add))
16714     {
16715       errmsg ("Missing BD, IP or MAC!");
16716       return -99;
16717     }
16718
16719   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16720   mp->is_add = is_add;
16721   clib_memcpy (mp->mac, mac, 6);
16722   mp->bd = clib_host_to_net_u32 (bd);
16723   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16724
16725   /* send */
16726   S (mp);
16727
16728   /* wait for reply */
16729   W (ret);
16730   return ret;
16731 }
16732
16733 static int
16734 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16735 {
16736   vl_api_one_add_del_l2_arp_entry_t *mp;
16737   unformat_input_t *input = vam->input;
16738   u8 is_add = 1;
16739   u8 mac_set = 0;
16740   u8 bd_set = 0;
16741   u8 ip_set = 0;
16742   u8 mac[6] = { 0, };
16743   u32 ip4 = 0, bd = ~0;
16744   int ret;
16745
16746   /* Parse args required to build the message */
16747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16748     {
16749       if (unformat (input, "del"))
16750         is_add = 0;
16751       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16752         mac_set = 1;
16753       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16754         ip_set = 1;
16755       else if (unformat (input, "bd %d", &bd))
16756         bd_set = 1;
16757       else
16758         {
16759           errmsg ("parse error '%U'", format_unformat_error, input);
16760           return -99;
16761         }
16762     }
16763
16764   if (!bd_set || !ip_set || (!mac_set && is_add))
16765     {
16766       errmsg ("Missing BD, IP or MAC!");
16767       return -99;
16768     }
16769
16770   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16771   mp->is_add = is_add;
16772   clib_memcpy (mp->mac, mac, 6);
16773   mp->bd = clib_host_to_net_u32 (bd);
16774   mp->ip4 = ip4;
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_ndp_bd_get (vat_main_t * vam)
16786 {
16787   vl_api_one_ndp_bd_get_t *mp;
16788   int ret;
16789
16790   M (ONE_NDP_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_ndp_entries_get (vat_main_t * vam)
16802 {
16803   vl_api_one_ndp_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_NDP_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_l2_arp_bd_get (vat_main_t * vam)
16840 {
16841   vl_api_one_l2_arp_bd_get_t *mp;
16842   int ret;
16843
16844   M (ONE_L2_ARP_BD_GET, mp);
16845
16846   /* send */
16847   S (mp);
16848
16849   /* wait for reply */
16850   W (ret);
16851   return ret;
16852 }
16853
16854 static int
16855 api_one_l2_arp_entries_get (vat_main_t * vam)
16856 {
16857   vl_api_one_l2_arp_entries_get_t *mp;
16858   unformat_input_t *input = vam->input;
16859   u8 bd_set = 0;
16860   u32 bd = ~0;
16861   int ret;
16862
16863   /* Parse args required to build the message */
16864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16865     {
16866       if (unformat (input, "bd %d", &bd))
16867         bd_set = 1;
16868       else
16869         {
16870           errmsg ("parse error '%U'", format_unformat_error, input);
16871           return -99;
16872         }
16873     }
16874
16875   if (!bd_set)
16876     {
16877       errmsg ("Expected bridge domain!");
16878       return -99;
16879     }
16880
16881   M (ONE_L2_ARP_ENTRIES_GET, mp);
16882   mp->bd = clib_host_to_net_u32 (bd);
16883
16884   /* send */
16885   S (mp);
16886
16887   /* wait for reply */
16888   W (ret);
16889   return ret;
16890 }
16891
16892 static int
16893 api_one_stats_enable_disable (vat_main_t * vam)
16894 {
16895   vl_api_one_stats_enable_disable_t *mp;
16896   unformat_input_t *input = vam->input;
16897   u8 is_set = 0;
16898   u8 is_en = 0;
16899   int ret;
16900
16901   /* Parse args required to build the message */
16902   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16903     {
16904       if (unformat (input, "enable"))
16905         {
16906           is_set = 1;
16907           is_en = 1;
16908         }
16909       else if (unformat (input, "disable"))
16910         {
16911           is_set = 1;
16912         }
16913       else
16914         break;
16915     }
16916
16917   if (!is_set)
16918     {
16919       errmsg ("Value not set");
16920       return -99;
16921     }
16922
16923   M (ONE_STATS_ENABLE_DISABLE, mp);
16924   mp->is_en = is_en;
16925
16926   /* send */
16927   S (mp);
16928
16929   /* wait for reply */
16930   W (ret);
16931   return ret;
16932 }
16933
16934 static int
16935 api_show_one_stats_enable_disable (vat_main_t * vam)
16936 {
16937   vl_api_show_one_stats_enable_disable_t *mp;
16938   int ret;
16939
16940   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16941
16942   /* send */
16943   S (mp);
16944
16945   /* wait for reply */
16946   W (ret);
16947   return ret;
16948 }
16949
16950 static int
16951 api_show_one_map_request_mode (vat_main_t * vam)
16952 {
16953   vl_api_show_one_map_request_mode_t *mp;
16954   int ret;
16955
16956   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16957
16958   /* send */
16959   S (mp);
16960
16961   /* wait for reply */
16962   W (ret);
16963   return ret;
16964 }
16965
16966 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16967
16968 static int
16969 api_one_map_request_mode (vat_main_t * vam)
16970 {
16971   unformat_input_t *input = vam->input;
16972   vl_api_one_map_request_mode_t *mp;
16973   u8 mode = 0;
16974   int ret;
16975
16976   /* Parse args required to build the message */
16977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16978     {
16979       if (unformat (input, "dst-only"))
16980         mode = 0;
16981       else if (unformat (input, "src-dst"))
16982         mode = 1;
16983       else
16984         {
16985           errmsg ("parse error '%U'", format_unformat_error, input);
16986           return -99;
16987         }
16988     }
16989
16990   M (ONE_MAP_REQUEST_MODE, mp);
16991
16992   mp->mode = mode;
16993
16994   /* send */
16995   S (mp);
16996
16997   /* wait for reply */
16998   W (ret);
16999   return ret;
17000 }
17001
17002 #define api_lisp_map_request_mode api_one_map_request_mode
17003
17004 /**
17005  * Enable/disable ONE proxy ITR.
17006  *
17007  * @param vam vpp API test context
17008  * @return return code
17009  */
17010 static int
17011 api_one_pitr_set_locator_set (vat_main_t * vam)
17012 {
17013   u8 ls_name_set = 0;
17014   unformat_input_t *input = vam->input;
17015   vl_api_one_pitr_set_locator_set_t *mp;
17016   u8 is_add = 1;
17017   u8 *ls_name = 0;
17018   int ret;
17019
17020   /* Parse args required to build the message */
17021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17022     {
17023       if (unformat (input, "del"))
17024         is_add = 0;
17025       else if (unformat (input, "locator-set %s", &ls_name))
17026         ls_name_set = 1;
17027       else
17028         {
17029           errmsg ("parse error '%U'", format_unformat_error, input);
17030           return -99;
17031         }
17032     }
17033
17034   if (!ls_name_set)
17035     {
17036       errmsg ("locator-set name not set!");
17037       return -99;
17038     }
17039
17040   M (ONE_PITR_SET_LOCATOR_SET, mp);
17041
17042   mp->is_add = is_add;
17043   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17044   vec_free (ls_name);
17045
17046   /* send */
17047   S (mp);
17048
17049   /* wait for reply */
17050   W (ret);
17051   return ret;
17052 }
17053
17054 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17055
17056 static int
17057 api_one_nsh_set_locator_set (vat_main_t * vam)
17058 {
17059   u8 ls_name_set = 0;
17060   unformat_input_t *input = vam->input;
17061   vl_api_one_nsh_set_locator_set_t *mp;
17062   u8 is_add = 1;
17063   u8 *ls_name = 0;
17064   int ret;
17065
17066   /* Parse args required to build the message */
17067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17068     {
17069       if (unformat (input, "del"))
17070         is_add = 0;
17071       else if (unformat (input, "ls %s", &ls_name))
17072         ls_name_set = 1;
17073       else
17074         {
17075           errmsg ("parse error '%U'", format_unformat_error, input);
17076           return -99;
17077         }
17078     }
17079
17080   if (!ls_name_set && is_add)
17081     {
17082       errmsg ("locator-set name not set!");
17083       return -99;
17084     }
17085
17086   M (ONE_NSH_SET_LOCATOR_SET, mp);
17087
17088   mp->is_add = is_add;
17089   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17090   vec_free (ls_name);
17091
17092   /* send */
17093   S (mp);
17094
17095   /* wait for reply */
17096   W (ret);
17097   return ret;
17098 }
17099
17100 static int
17101 api_show_one_pitr (vat_main_t * vam)
17102 {
17103   vl_api_show_one_pitr_t *mp;
17104   int ret;
17105
17106   if (!vam->json_output)
17107     {
17108       print (vam->ofp, "%=20s", "lisp status:");
17109     }
17110
17111   M (SHOW_ONE_PITR, mp);
17112   /* send it... */
17113   S (mp);
17114
17115   /* Wait for a reply... */
17116   W (ret);
17117   return ret;
17118 }
17119
17120 #define api_show_lisp_pitr api_show_one_pitr
17121
17122 static int
17123 api_one_use_petr (vat_main_t * vam)
17124 {
17125   unformat_input_t *input = vam->input;
17126   vl_api_one_use_petr_t *mp;
17127   u8 is_add = 0;
17128   ip_address_t ip;
17129   int ret;
17130
17131   clib_memset (&ip, 0, sizeof (ip));
17132
17133   /* Parse args required to build the message */
17134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17135     {
17136       if (unformat (input, "disable"))
17137         is_add = 0;
17138       else
17139         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17140         {
17141           is_add = 1;
17142           ip_addr_version (&ip) = IP4;
17143         }
17144       else
17145         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17146         {
17147           is_add = 1;
17148           ip_addr_version (&ip) = IP6;
17149         }
17150       else
17151         {
17152           errmsg ("parse error '%U'", format_unformat_error, input);
17153           return -99;
17154         }
17155     }
17156
17157   M (ONE_USE_PETR, mp);
17158
17159   mp->is_add = is_add;
17160   if (is_add)
17161     {
17162       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17163       if (mp->is_ip4)
17164         clib_memcpy (mp->address, &ip, 4);
17165       else
17166         clib_memcpy (mp->address, &ip, 16);
17167     }
17168
17169   /* send */
17170   S (mp);
17171
17172   /* wait for reply */
17173   W (ret);
17174   return ret;
17175 }
17176
17177 #define api_lisp_use_petr api_one_use_petr
17178
17179 static int
17180 api_show_one_nsh_mapping (vat_main_t * vam)
17181 {
17182   vl_api_show_one_use_petr_t *mp;
17183   int ret;
17184
17185   if (!vam->json_output)
17186     {
17187       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17188     }
17189
17190   M (SHOW_ONE_NSH_MAPPING, mp);
17191   /* send it... */
17192   S (mp);
17193
17194   /* Wait for a reply... */
17195   W (ret);
17196   return ret;
17197 }
17198
17199 static int
17200 api_show_one_use_petr (vat_main_t * vam)
17201 {
17202   vl_api_show_one_use_petr_t *mp;
17203   int ret;
17204
17205   if (!vam->json_output)
17206     {
17207       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17208     }
17209
17210   M (SHOW_ONE_USE_PETR, mp);
17211   /* send it... */
17212   S (mp);
17213
17214   /* Wait for a reply... */
17215   W (ret);
17216   return ret;
17217 }
17218
17219 #define api_show_lisp_use_petr api_show_one_use_petr
17220
17221 /**
17222  * Add/delete mapping between vni and vrf
17223  */
17224 static int
17225 api_one_eid_table_add_del_map (vat_main_t * vam)
17226 {
17227   unformat_input_t *input = vam->input;
17228   vl_api_one_eid_table_add_del_map_t *mp;
17229   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17230   u32 vni, vrf, bd_index;
17231   int ret;
17232
17233   /* Parse args required to build the message */
17234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17235     {
17236       if (unformat (input, "del"))
17237         is_add = 0;
17238       else if (unformat (input, "vrf %d", &vrf))
17239         vrf_set = 1;
17240       else if (unformat (input, "bd_index %d", &bd_index))
17241         bd_index_set = 1;
17242       else if (unformat (input, "vni %d", &vni))
17243         vni_set = 1;
17244       else
17245         break;
17246     }
17247
17248   if (!vni_set || (!vrf_set && !bd_index_set))
17249     {
17250       errmsg ("missing arguments!");
17251       return -99;
17252     }
17253
17254   if (vrf_set && bd_index_set)
17255     {
17256       errmsg ("error: both vrf and bd entered!");
17257       return -99;
17258     }
17259
17260   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17261
17262   mp->is_add = is_add;
17263   mp->vni = htonl (vni);
17264   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17265   mp->is_l2 = bd_index_set;
17266
17267   /* send */
17268   S (mp);
17269
17270   /* wait for reply */
17271   W (ret);
17272   return ret;
17273 }
17274
17275 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17276
17277 uword
17278 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17279 {
17280   u32 *action = va_arg (*args, u32 *);
17281   u8 *s = 0;
17282
17283   if (unformat (input, "%s", &s))
17284     {
17285       if (!strcmp ((char *) s, "no-action"))
17286         action[0] = 0;
17287       else if (!strcmp ((char *) s, "natively-forward"))
17288         action[0] = 1;
17289       else if (!strcmp ((char *) s, "send-map-request"))
17290         action[0] = 2;
17291       else if (!strcmp ((char *) s, "drop"))
17292         action[0] = 3;
17293       else
17294         {
17295           clib_warning ("invalid action: '%s'", s);
17296           action[0] = 3;
17297         }
17298     }
17299   else
17300     return 0;
17301
17302   vec_free (s);
17303   return 1;
17304 }
17305
17306 /**
17307  * Add/del remote mapping to/from ONE control plane
17308  *
17309  * @param vam vpp API test context
17310  * @return return code
17311  */
17312 static int
17313 api_one_add_del_remote_mapping (vat_main_t * vam)
17314 {
17315   unformat_input_t *input = vam->input;
17316   vl_api_one_add_del_remote_mapping_t *mp;
17317   u32 vni = 0;
17318   lisp_eid_vat_t _eid, *eid = &_eid;
17319   lisp_eid_vat_t _seid, *seid = &_seid;
17320   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17321   u32 action = ~0, p, w, data_len;
17322   ip4_address_t rloc4;
17323   ip6_address_t rloc6;
17324   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17325   int ret;
17326
17327   clib_memset (&rloc, 0, sizeof (rloc));
17328
17329   /* Parse args required to build the message */
17330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17331     {
17332       if (unformat (input, "del-all"))
17333         {
17334           del_all = 1;
17335         }
17336       else if (unformat (input, "del"))
17337         {
17338           is_add = 0;
17339         }
17340       else if (unformat (input, "add"))
17341         {
17342           is_add = 1;
17343         }
17344       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17345         {
17346           eid_set = 1;
17347         }
17348       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17349         {
17350           seid_set = 1;
17351         }
17352       else if (unformat (input, "vni %d", &vni))
17353         {
17354           ;
17355         }
17356       else if (unformat (input, "p %d w %d", &p, &w))
17357         {
17358           if (!curr_rloc)
17359             {
17360               errmsg ("No RLOC configured for setting priority/weight!");
17361               return -99;
17362             }
17363           curr_rloc->priority = p;
17364           curr_rloc->weight = w;
17365         }
17366       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17367         {
17368           rloc.is_ip4 = 1;
17369           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17370           vec_add1 (rlocs, rloc);
17371           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17372         }
17373       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17374         {
17375           rloc.is_ip4 = 0;
17376           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17377           vec_add1 (rlocs, rloc);
17378           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17379         }
17380       else if (unformat (input, "action %U",
17381                          unformat_negative_mapping_action, &action))
17382         {
17383           ;
17384         }
17385       else
17386         {
17387           clib_warning ("parse error '%U'", format_unformat_error, input);
17388           return -99;
17389         }
17390     }
17391
17392   if (0 == eid_set)
17393     {
17394       errmsg ("missing params!");
17395       return -99;
17396     }
17397
17398   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17399     {
17400       errmsg ("no action set for negative map-reply!");
17401       return -99;
17402     }
17403
17404   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17405
17406   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17407   mp->is_add = is_add;
17408   mp->vni = htonl (vni);
17409   mp->action = (u8) action;
17410   mp->is_src_dst = seid_set;
17411   mp->eid_len = eid->len;
17412   mp->seid_len = seid->len;
17413   mp->del_all = del_all;
17414   mp->eid_type = eid->type;
17415   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17416   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17417
17418   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17419   clib_memcpy (mp->rlocs, rlocs, data_len);
17420   vec_free (rlocs);
17421
17422   /* send it... */
17423   S (mp);
17424
17425   /* Wait for a reply... */
17426   W (ret);
17427   return ret;
17428 }
17429
17430 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17431
17432 /**
17433  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17434  * forwarding entries in data-plane accordingly.
17435  *
17436  * @param vam vpp API test context
17437  * @return return code
17438  */
17439 static int
17440 api_one_add_del_adjacency (vat_main_t * vam)
17441 {
17442   unformat_input_t *input = vam->input;
17443   vl_api_one_add_del_adjacency_t *mp;
17444   u32 vni = 0;
17445   ip4_address_t leid4, reid4;
17446   ip6_address_t leid6, reid6;
17447   u8 reid_mac[6] = { 0 };
17448   u8 leid_mac[6] = { 0 };
17449   u8 reid_type, leid_type;
17450   u32 leid_len = 0, reid_len = 0, len;
17451   u8 is_add = 1;
17452   int ret;
17453
17454   leid_type = reid_type = (u8) ~ 0;
17455
17456   /* Parse args required to build the message */
17457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17458     {
17459       if (unformat (input, "del"))
17460         {
17461           is_add = 0;
17462         }
17463       else if (unformat (input, "add"))
17464         {
17465           is_add = 1;
17466         }
17467       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17468                          &reid4, &len))
17469         {
17470           reid_type = 0;        /* ipv4 */
17471           reid_len = len;
17472         }
17473       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17474                          &reid6, &len))
17475         {
17476           reid_type = 1;        /* ipv6 */
17477           reid_len = len;
17478         }
17479       else if (unformat (input, "reid %U", unformat_ethernet_address,
17480                          reid_mac))
17481         {
17482           reid_type = 2;        /* mac */
17483         }
17484       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17485                          &leid4, &len))
17486         {
17487           leid_type = 0;        /* ipv4 */
17488           leid_len = len;
17489         }
17490       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17491                          &leid6, &len))
17492         {
17493           leid_type = 1;        /* ipv6 */
17494           leid_len = len;
17495         }
17496       else if (unformat (input, "leid %U", unformat_ethernet_address,
17497                          leid_mac))
17498         {
17499           leid_type = 2;        /* mac */
17500         }
17501       else if (unformat (input, "vni %d", &vni))
17502         {
17503           ;
17504         }
17505       else
17506         {
17507           errmsg ("parse error '%U'", format_unformat_error, input);
17508           return -99;
17509         }
17510     }
17511
17512   if ((u8) ~ 0 == reid_type)
17513     {
17514       errmsg ("missing params!");
17515       return -99;
17516     }
17517
17518   if (leid_type != reid_type)
17519     {
17520       errmsg ("remote and local EIDs are of different types!");
17521       return -99;
17522     }
17523
17524   M (ONE_ADD_DEL_ADJACENCY, mp);
17525   mp->is_add = is_add;
17526   mp->vni = htonl (vni);
17527   mp->leid_len = leid_len;
17528   mp->reid_len = reid_len;
17529   mp->eid_type = reid_type;
17530
17531   switch (mp->eid_type)
17532     {
17533     case 0:
17534       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17535       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17536       break;
17537     case 1:
17538       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17539       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17540       break;
17541     case 2:
17542       clib_memcpy (mp->leid, leid_mac, 6);
17543       clib_memcpy (mp->reid, reid_mac, 6);
17544       break;
17545     default:
17546       errmsg ("unknown EID type %d!", mp->eid_type);
17547       return 0;
17548     }
17549
17550   /* send it... */
17551   S (mp);
17552
17553   /* Wait for a reply... */
17554   W (ret);
17555   return ret;
17556 }
17557
17558 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17559
17560 uword
17561 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17562 {
17563   u32 *mode = va_arg (*args, u32 *);
17564
17565   if (unformat (input, "lisp"))
17566     *mode = 0;
17567   else if (unformat (input, "vxlan"))
17568     *mode = 1;
17569   else
17570     return 0;
17571
17572   return 1;
17573 }
17574
17575 static int
17576 api_gpe_get_encap_mode (vat_main_t * vam)
17577 {
17578   vl_api_gpe_get_encap_mode_t *mp;
17579   int ret;
17580
17581   /* Construct the API message */
17582   M (GPE_GET_ENCAP_MODE, mp);
17583
17584   /* send it... */
17585   S (mp);
17586
17587   /* Wait for a reply... */
17588   W (ret);
17589   return ret;
17590 }
17591
17592 static int
17593 api_gpe_set_encap_mode (vat_main_t * vam)
17594 {
17595   unformat_input_t *input = vam->input;
17596   vl_api_gpe_set_encap_mode_t *mp;
17597   int ret;
17598   u32 mode = 0;
17599
17600   /* Parse args required to build the message */
17601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17602     {
17603       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17604         ;
17605       else
17606         break;
17607     }
17608
17609   /* Construct the API message */
17610   M (GPE_SET_ENCAP_MODE, mp);
17611
17612   mp->mode = mode;
17613
17614   /* send it... */
17615   S (mp);
17616
17617   /* Wait for a reply... */
17618   W (ret);
17619   return ret;
17620 }
17621
17622 static int
17623 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17624 {
17625   unformat_input_t *input = vam->input;
17626   vl_api_gpe_add_del_iface_t *mp;
17627   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17628   u32 dp_table = 0, vni = 0;
17629   int ret;
17630
17631   /* Parse args required to build the message */
17632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17633     {
17634       if (unformat (input, "up"))
17635         {
17636           action_set = 1;
17637           is_add = 1;
17638         }
17639       else if (unformat (input, "down"))
17640         {
17641           action_set = 1;
17642           is_add = 0;
17643         }
17644       else if (unformat (input, "table_id %d", &dp_table))
17645         {
17646           dp_table_set = 1;
17647         }
17648       else if (unformat (input, "bd_id %d", &dp_table))
17649         {
17650           dp_table_set = 1;
17651           is_l2 = 1;
17652         }
17653       else if (unformat (input, "vni %d", &vni))
17654         {
17655           vni_set = 1;
17656         }
17657       else
17658         break;
17659     }
17660
17661   if (action_set == 0)
17662     {
17663       errmsg ("Action not set");
17664       return -99;
17665     }
17666   if (dp_table_set == 0 || vni_set == 0)
17667     {
17668       errmsg ("vni and dp_table must be set");
17669       return -99;
17670     }
17671
17672   /* Construct the API message */
17673   M (GPE_ADD_DEL_IFACE, mp);
17674
17675   mp->is_add = is_add;
17676   mp->dp_table = clib_host_to_net_u32 (dp_table);
17677   mp->is_l2 = is_l2;
17678   mp->vni = clib_host_to_net_u32 (vni);
17679
17680   /* send it... */
17681   S (mp);
17682
17683   /* Wait for a reply... */
17684   W (ret);
17685   return ret;
17686 }
17687
17688 static int
17689 api_one_map_register_fallback_threshold (vat_main_t * vam)
17690 {
17691   unformat_input_t *input = vam->input;
17692   vl_api_one_map_register_fallback_threshold_t *mp;
17693   u32 value = 0;
17694   u8 is_set = 0;
17695   int ret;
17696
17697   /* Parse args required to build the message */
17698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17699     {
17700       if (unformat (input, "%u", &value))
17701         is_set = 1;
17702       else
17703         {
17704           clib_warning ("parse error '%U'", format_unformat_error, input);
17705           return -99;
17706         }
17707     }
17708
17709   if (!is_set)
17710     {
17711       errmsg ("fallback threshold value is missing!");
17712       return -99;
17713     }
17714
17715   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17716   mp->value = clib_host_to_net_u32 (value);
17717
17718   /* send it... */
17719   S (mp);
17720
17721   /* Wait for a reply... */
17722   W (ret);
17723   return ret;
17724 }
17725
17726 static int
17727 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17728 {
17729   vl_api_show_one_map_register_fallback_threshold_t *mp;
17730   int ret;
17731
17732   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17733
17734   /* send it... */
17735   S (mp);
17736
17737   /* Wait for a reply... */
17738   W (ret);
17739   return ret;
17740 }
17741
17742 uword
17743 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17744 {
17745   u32 *proto = va_arg (*args, u32 *);
17746
17747   if (unformat (input, "udp"))
17748     *proto = 1;
17749   else if (unformat (input, "api"))
17750     *proto = 2;
17751   else
17752     return 0;
17753
17754   return 1;
17755 }
17756
17757 static int
17758 api_one_set_transport_protocol (vat_main_t * vam)
17759 {
17760   unformat_input_t *input = vam->input;
17761   vl_api_one_set_transport_protocol_t *mp;
17762   u8 is_set = 0;
17763   u32 protocol = 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", unformat_lisp_transport_protocol, &protocol))
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 ("Transport protocol missing!");
17781       return -99;
17782     }
17783
17784   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17785   mp->protocol = (u8) protocol;
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_one_get_transport_protocol (vat_main_t * vam)
17797 {
17798   vl_api_one_get_transport_protocol_t *mp;
17799   int ret;
17800
17801   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17802
17803   /* send it... */
17804   S (mp);
17805
17806   /* Wait for a reply... */
17807   W (ret);
17808   return ret;
17809 }
17810
17811 static int
17812 api_one_map_register_set_ttl (vat_main_t * vam)
17813 {
17814   unformat_input_t *input = vam->input;
17815   vl_api_one_map_register_set_ttl_t *mp;
17816   u32 ttl = 0;
17817   u8 is_set = 0;
17818   int ret;
17819
17820   /* Parse args required to build the message */
17821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17822     {
17823       if (unformat (input, "%u", &ttl))
17824         is_set = 1;
17825       else
17826         {
17827           clib_warning ("parse error '%U'", format_unformat_error, input);
17828           return -99;
17829         }
17830     }
17831
17832   if (!is_set)
17833     {
17834       errmsg ("TTL value missing!");
17835       return -99;
17836     }
17837
17838   M (ONE_MAP_REGISTER_SET_TTL, mp);
17839   mp->ttl = clib_host_to_net_u32 (ttl);
17840
17841   /* send it... */
17842   S (mp);
17843
17844   /* Wait for a reply... */
17845   W (ret);
17846   return ret;
17847 }
17848
17849 static int
17850 api_show_one_map_register_ttl (vat_main_t * vam)
17851 {
17852   vl_api_show_one_map_register_ttl_t *mp;
17853   int ret;
17854
17855   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17856
17857   /* send it... */
17858   S (mp);
17859
17860   /* Wait for a reply... */
17861   W (ret);
17862   return ret;
17863 }
17864
17865 /**
17866  * Add/del map request itr rlocs from ONE control plane and updates
17867  *
17868  * @param vam vpp API test context
17869  * @return return code
17870  */
17871 static int
17872 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17873 {
17874   unformat_input_t *input = vam->input;
17875   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17876   u8 *locator_set_name = 0;
17877   u8 locator_set_name_set = 0;
17878   u8 is_add = 1;
17879   int ret;
17880
17881   /* Parse args required to build the message */
17882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17883     {
17884       if (unformat (input, "del"))
17885         {
17886           is_add = 0;
17887         }
17888       else if (unformat (input, "%_%v%_", &locator_set_name))
17889         {
17890           locator_set_name_set = 1;
17891         }
17892       else
17893         {
17894           clib_warning ("parse error '%U'", format_unformat_error, input);
17895           return -99;
17896         }
17897     }
17898
17899   if (is_add && !locator_set_name_set)
17900     {
17901       errmsg ("itr-rloc is not set!");
17902       return -99;
17903     }
17904
17905   if (is_add && vec_len (locator_set_name) > 64)
17906     {
17907       errmsg ("itr-rloc locator-set name too long");
17908       vec_free (locator_set_name);
17909       return -99;
17910     }
17911
17912   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17913   mp->is_add = is_add;
17914   if (is_add)
17915     {
17916       clib_memcpy (mp->locator_set_name, locator_set_name,
17917                    vec_len (locator_set_name));
17918     }
17919   else
17920     {
17921       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17922     }
17923   vec_free (locator_set_name);
17924
17925   /* send it... */
17926   S (mp);
17927
17928   /* Wait for a reply... */
17929   W (ret);
17930   return ret;
17931 }
17932
17933 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17934
17935 static int
17936 api_one_locator_dump (vat_main_t * vam)
17937 {
17938   unformat_input_t *input = vam->input;
17939   vl_api_one_locator_dump_t *mp;
17940   vl_api_control_ping_t *mp_ping;
17941   u8 is_index_set = 0, is_name_set = 0;
17942   u8 *ls_name = 0;
17943   u32 ls_index = ~0;
17944   int ret;
17945
17946   /* Parse args required to build the message */
17947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17948     {
17949       if (unformat (input, "ls_name %_%v%_", &ls_name))
17950         {
17951           is_name_set = 1;
17952         }
17953       else if (unformat (input, "ls_index %d", &ls_index))
17954         {
17955           is_index_set = 1;
17956         }
17957       else
17958         {
17959           errmsg ("parse error '%U'", format_unformat_error, input);
17960           return -99;
17961         }
17962     }
17963
17964   if (!is_index_set && !is_name_set)
17965     {
17966       errmsg ("error: expected one of index or name!");
17967       return -99;
17968     }
17969
17970   if (is_index_set && is_name_set)
17971     {
17972       errmsg ("error: only one param expected!");
17973       return -99;
17974     }
17975
17976   if (vec_len (ls_name) > 62)
17977     {
17978       errmsg ("error: locator set name too long!");
17979       return -99;
17980     }
17981
17982   if (!vam->json_output)
17983     {
17984       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17985     }
17986
17987   M (ONE_LOCATOR_DUMP, mp);
17988   mp->is_index_set = is_index_set;
17989
17990   if (is_index_set)
17991     mp->ls_index = clib_host_to_net_u32 (ls_index);
17992   else
17993     {
17994       vec_add1 (ls_name, 0);
17995       strncpy ((char *) mp->ls_name, (char *) ls_name,
17996                sizeof (mp->ls_name) - 1);
17997     }
17998
17999   /* send it... */
18000   S (mp);
18001
18002   /* Use a control ping for synchronization */
18003   MPING (CONTROL_PING, mp_ping);
18004   S (mp_ping);
18005
18006   /* Wait for a reply... */
18007   W (ret);
18008   return ret;
18009 }
18010
18011 #define api_lisp_locator_dump api_one_locator_dump
18012
18013 static int
18014 api_one_locator_set_dump (vat_main_t * vam)
18015 {
18016   vl_api_one_locator_set_dump_t *mp;
18017   vl_api_control_ping_t *mp_ping;
18018   unformat_input_t *input = vam->input;
18019   u8 filter = 0;
18020   int ret;
18021
18022   /* Parse args required to build the message */
18023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18024     {
18025       if (unformat (input, "local"))
18026         {
18027           filter = 1;
18028         }
18029       else if (unformat (input, "remote"))
18030         {
18031           filter = 2;
18032         }
18033       else
18034         {
18035           errmsg ("parse error '%U'", format_unformat_error, input);
18036           return -99;
18037         }
18038     }
18039
18040   if (!vam->json_output)
18041     {
18042       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18043     }
18044
18045   M (ONE_LOCATOR_SET_DUMP, mp);
18046
18047   mp->filter = filter;
18048
18049   /* send it... */
18050   S (mp);
18051
18052   /* Use a control ping for synchronization */
18053   MPING (CONTROL_PING, mp_ping);
18054   S (mp_ping);
18055
18056   /* Wait for a reply... */
18057   W (ret);
18058   return ret;
18059 }
18060
18061 #define api_lisp_locator_set_dump api_one_locator_set_dump
18062
18063 static int
18064 api_one_eid_table_map_dump (vat_main_t * vam)
18065 {
18066   u8 is_l2 = 0;
18067   u8 mode_set = 0;
18068   unformat_input_t *input = vam->input;
18069   vl_api_one_eid_table_map_dump_t *mp;
18070   vl_api_control_ping_t *mp_ping;
18071   int ret;
18072
18073   /* Parse args required to build the message */
18074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18075     {
18076       if (unformat (input, "l2"))
18077         {
18078           is_l2 = 1;
18079           mode_set = 1;
18080         }
18081       else if (unformat (input, "l3"))
18082         {
18083           is_l2 = 0;
18084           mode_set = 1;
18085         }
18086       else
18087         {
18088           errmsg ("parse error '%U'", format_unformat_error, input);
18089           return -99;
18090         }
18091     }
18092
18093   if (!mode_set)
18094     {
18095       errmsg ("expected one of 'l2' or 'l3' parameter!");
18096       return -99;
18097     }
18098
18099   if (!vam->json_output)
18100     {
18101       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18102     }
18103
18104   M (ONE_EID_TABLE_MAP_DUMP, mp);
18105   mp->is_l2 = is_l2;
18106
18107   /* send it... */
18108   S (mp);
18109
18110   /* Use a control ping for synchronization */
18111   MPING (CONTROL_PING, mp_ping);
18112   S (mp_ping);
18113
18114   /* Wait for a reply... */
18115   W (ret);
18116   return ret;
18117 }
18118
18119 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18120
18121 static int
18122 api_one_eid_table_vni_dump (vat_main_t * vam)
18123 {
18124   vl_api_one_eid_table_vni_dump_t *mp;
18125   vl_api_control_ping_t *mp_ping;
18126   int ret;
18127
18128   if (!vam->json_output)
18129     {
18130       print (vam->ofp, "VNI");
18131     }
18132
18133   M (ONE_EID_TABLE_VNI_DUMP, mp);
18134
18135   /* send it... */
18136   S (mp);
18137
18138   /* Use a control ping for synchronization */
18139   MPING (CONTROL_PING, mp_ping);
18140   S (mp_ping);
18141
18142   /* Wait for a reply... */
18143   W (ret);
18144   return ret;
18145 }
18146
18147 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18148
18149 static int
18150 api_one_eid_table_dump (vat_main_t * vam)
18151 {
18152   unformat_input_t *i = vam->input;
18153   vl_api_one_eid_table_dump_t *mp;
18154   vl_api_control_ping_t *mp_ping;
18155   struct in_addr ip4;
18156   struct in6_addr ip6;
18157   u8 mac[6];
18158   u8 eid_type = ~0, eid_set = 0;
18159   u32 prefix_length = ~0, t, vni = 0;
18160   u8 filter = 0;
18161   int ret;
18162   lisp_nsh_api_t nsh;
18163
18164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18165     {
18166       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18167         {
18168           eid_set = 1;
18169           eid_type = 0;
18170           prefix_length = t;
18171         }
18172       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18173         {
18174           eid_set = 1;
18175           eid_type = 1;
18176           prefix_length = t;
18177         }
18178       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18179         {
18180           eid_set = 1;
18181           eid_type = 2;
18182         }
18183       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18184         {
18185           eid_set = 1;
18186           eid_type = 3;
18187         }
18188       else if (unformat (i, "vni %d", &t))
18189         {
18190           vni = t;
18191         }
18192       else if (unformat (i, "local"))
18193         {
18194           filter = 1;
18195         }
18196       else if (unformat (i, "remote"))
18197         {
18198           filter = 2;
18199         }
18200       else
18201         {
18202           errmsg ("parse error '%U'", format_unformat_error, i);
18203           return -99;
18204         }
18205     }
18206
18207   if (!vam->json_output)
18208     {
18209       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18210              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18211     }
18212
18213   M (ONE_EID_TABLE_DUMP, mp);
18214
18215   mp->filter = filter;
18216   if (eid_set)
18217     {
18218       mp->eid_set = 1;
18219       mp->vni = htonl (vni);
18220       mp->eid_type = eid_type;
18221       switch (eid_type)
18222         {
18223         case 0:
18224           mp->prefix_length = prefix_length;
18225           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18226           break;
18227         case 1:
18228           mp->prefix_length = prefix_length;
18229           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18230           break;
18231         case 2:
18232           clib_memcpy (mp->eid, mac, sizeof (mac));
18233           break;
18234         case 3:
18235           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18236           break;
18237         default:
18238           errmsg ("unknown EID type %d!", eid_type);
18239           return -99;
18240         }
18241     }
18242
18243   /* send it... */
18244   S (mp);
18245
18246   /* Use a control ping for synchronization */
18247   MPING (CONTROL_PING, mp_ping);
18248   S (mp_ping);
18249
18250   /* Wait for a reply... */
18251   W (ret);
18252   return ret;
18253 }
18254
18255 #define api_lisp_eid_table_dump api_one_eid_table_dump
18256
18257 static int
18258 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18259 {
18260   unformat_input_t *i = vam->input;
18261   vl_api_gpe_fwd_entries_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, "%10s %10s %s %40s", "fwd_index", "dp_table",
18288              "leid", "reid");
18289     }
18290
18291   M (GPE_FWD_ENTRIES_GET, mp);
18292   mp->vni = clib_host_to_net_u32 (vni);
18293
18294   /* send it... */
18295   S (mp);
18296
18297   /* Wait for a reply... */
18298   W (ret);
18299   return ret;
18300 }
18301
18302 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18303 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18304 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18305 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18306 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18307 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18308 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18309 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18310
18311 static int
18312 api_one_adjacencies_get (vat_main_t * vam)
18313 {
18314   unformat_input_t *i = vam->input;
18315   vl_api_one_adjacencies_get_t *mp;
18316   u8 vni_set = 0;
18317   u32 vni = ~0;
18318   int ret;
18319
18320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18321     {
18322       if (unformat (i, "vni %d", &vni))
18323         {
18324           vni_set = 1;
18325         }
18326       else
18327         {
18328           errmsg ("parse error '%U'", format_unformat_error, i);
18329           return -99;
18330         }
18331     }
18332
18333   if (!vni_set)
18334     {
18335       errmsg ("vni not set!");
18336       return -99;
18337     }
18338
18339   if (!vam->json_output)
18340     {
18341       print (vam->ofp, "%s %40s", "leid", "reid");
18342     }
18343
18344   M (ONE_ADJACENCIES_GET, mp);
18345   mp->vni = clib_host_to_net_u32 (vni);
18346
18347   /* send it... */
18348   S (mp);
18349
18350   /* Wait for a reply... */
18351   W (ret);
18352   return ret;
18353 }
18354
18355 #define api_lisp_adjacencies_get api_one_adjacencies_get
18356
18357 static int
18358 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18359 {
18360   unformat_input_t *i = vam->input;
18361   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18362   int ret;
18363   u8 ip_family_set = 0, is_ip4 = 1;
18364
18365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18366     {
18367       if (unformat (i, "ip4"))
18368         {
18369           ip_family_set = 1;
18370           is_ip4 = 1;
18371         }
18372       else if (unformat (i, "ip6"))
18373         {
18374           ip_family_set = 1;
18375           is_ip4 = 0;
18376         }
18377       else
18378         {
18379           errmsg ("parse error '%U'", format_unformat_error, i);
18380           return -99;
18381         }
18382     }
18383
18384   if (!ip_family_set)
18385     {
18386       errmsg ("ip family not set!");
18387       return -99;
18388     }
18389
18390   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18391   mp->is_ip4 = is_ip4;
18392
18393   /* send it... */
18394   S (mp);
18395
18396   /* Wait for a reply... */
18397   W (ret);
18398   return ret;
18399 }
18400
18401 static int
18402 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18403 {
18404   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18405   int ret;
18406
18407   if (!vam->json_output)
18408     {
18409       print (vam->ofp, "VNIs");
18410     }
18411
18412   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18413
18414   /* send it... */
18415   S (mp);
18416
18417   /* Wait for a reply... */
18418   W (ret);
18419   return ret;
18420 }
18421
18422 static int
18423 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18424 {
18425   unformat_input_t *i = vam->input;
18426   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18427   int ret = 0;
18428   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18429   struct in_addr ip4;
18430   struct in6_addr ip6;
18431   u32 table_id = 0, nh_sw_if_index = ~0;
18432
18433   clib_memset (&ip4, 0, sizeof (ip4));
18434   clib_memset (&ip6, 0, sizeof (ip6));
18435
18436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18437     {
18438       if (unformat (i, "del"))
18439         is_add = 0;
18440       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18441                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18442         {
18443           ip_set = 1;
18444           is_ip4 = 1;
18445         }
18446       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18447                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18448         {
18449           ip_set = 1;
18450           is_ip4 = 0;
18451         }
18452       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18453         {
18454           ip_set = 1;
18455           is_ip4 = 1;
18456           nh_sw_if_index = ~0;
18457         }
18458       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18459         {
18460           ip_set = 1;
18461           is_ip4 = 0;
18462           nh_sw_if_index = ~0;
18463         }
18464       else if (unformat (i, "table %d", &table_id))
18465         ;
18466       else
18467         {
18468           errmsg ("parse error '%U'", format_unformat_error, i);
18469           return -99;
18470         }
18471     }
18472
18473   if (!ip_set)
18474     {
18475       errmsg ("nh addr not set!");
18476       return -99;
18477     }
18478
18479   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18480   mp->is_add = is_add;
18481   mp->table_id = clib_host_to_net_u32 (table_id);
18482   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18483   mp->is_ip4 = is_ip4;
18484   if (is_ip4)
18485     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18486   else
18487     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18488
18489   /* send it... */
18490   S (mp);
18491
18492   /* Wait for a reply... */
18493   W (ret);
18494   return ret;
18495 }
18496
18497 static int
18498 api_one_map_server_dump (vat_main_t * vam)
18499 {
18500   vl_api_one_map_server_dump_t *mp;
18501   vl_api_control_ping_t *mp_ping;
18502   int ret;
18503
18504   if (!vam->json_output)
18505     {
18506       print (vam->ofp, "%=20s", "Map server");
18507     }
18508
18509   M (ONE_MAP_SERVER_DUMP, mp);
18510   /* send it... */
18511   S (mp);
18512
18513   /* Use a control ping for synchronization */
18514   MPING (CONTROL_PING, mp_ping);
18515   S (mp_ping);
18516
18517   /* Wait for a reply... */
18518   W (ret);
18519   return ret;
18520 }
18521
18522 #define api_lisp_map_server_dump api_one_map_server_dump
18523
18524 static int
18525 api_one_map_resolver_dump (vat_main_t * vam)
18526 {
18527   vl_api_one_map_resolver_dump_t *mp;
18528   vl_api_control_ping_t *mp_ping;
18529   int ret;
18530
18531   if (!vam->json_output)
18532     {
18533       print (vam->ofp, "%=20s", "Map resolver");
18534     }
18535
18536   M (ONE_MAP_RESOLVER_DUMP, mp);
18537   /* send it... */
18538   S (mp);
18539
18540   /* Use a control ping for synchronization */
18541   MPING (CONTROL_PING, mp_ping);
18542   S (mp_ping);
18543
18544   /* Wait for a reply... */
18545   W (ret);
18546   return ret;
18547 }
18548
18549 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18550
18551 static int
18552 api_one_stats_flush (vat_main_t * vam)
18553 {
18554   vl_api_one_stats_flush_t *mp;
18555   int ret = 0;
18556
18557   M (ONE_STATS_FLUSH, mp);
18558   S (mp);
18559   W (ret);
18560   return ret;
18561 }
18562
18563 static int
18564 api_one_stats_dump (vat_main_t * vam)
18565 {
18566   vl_api_one_stats_dump_t *mp;
18567   vl_api_control_ping_t *mp_ping;
18568   int ret;
18569
18570   M (ONE_STATS_DUMP, mp);
18571   /* send it... */
18572   S (mp);
18573
18574   /* Use a control ping for synchronization */
18575   MPING (CONTROL_PING, mp_ping);
18576   S (mp_ping);
18577
18578   /* Wait for a reply... */
18579   W (ret);
18580   return ret;
18581 }
18582
18583 static int
18584 api_show_one_status (vat_main_t * vam)
18585 {
18586   vl_api_show_one_status_t *mp;
18587   int ret;
18588
18589   if (!vam->json_output)
18590     {
18591       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18592     }
18593
18594   M (SHOW_ONE_STATUS, mp);
18595   /* send it... */
18596   S (mp);
18597   /* Wait for a reply... */
18598   W (ret);
18599   return ret;
18600 }
18601
18602 #define api_show_lisp_status api_show_one_status
18603
18604 static int
18605 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18606 {
18607   vl_api_gpe_fwd_entry_path_dump_t *mp;
18608   vl_api_control_ping_t *mp_ping;
18609   unformat_input_t *i = vam->input;
18610   u32 fwd_entry_index = ~0;
18611   int ret;
18612
18613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18614     {
18615       if (unformat (i, "index %d", &fwd_entry_index))
18616         ;
18617       else
18618         break;
18619     }
18620
18621   if (~0 == fwd_entry_index)
18622     {
18623       errmsg ("no index specified!");
18624       return -99;
18625     }
18626
18627   if (!vam->json_output)
18628     {
18629       print (vam->ofp, "first line");
18630     }
18631
18632   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18633
18634   /* send it... */
18635   S (mp);
18636   /* Use a control ping for synchronization */
18637   MPING (CONTROL_PING, mp_ping);
18638   S (mp_ping);
18639
18640   /* Wait for a reply... */
18641   W (ret);
18642   return ret;
18643 }
18644
18645 static int
18646 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18647 {
18648   vl_api_one_get_map_request_itr_rlocs_t *mp;
18649   int ret;
18650
18651   if (!vam->json_output)
18652     {
18653       print (vam->ofp, "%=20s", "itr-rlocs:");
18654     }
18655
18656   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18657   /* send it... */
18658   S (mp);
18659   /* Wait for a reply... */
18660   W (ret);
18661   return ret;
18662 }
18663
18664 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18665
18666 static int
18667 api_af_packet_create (vat_main_t * vam)
18668 {
18669   unformat_input_t *i = vam->input;
18670   vl_api_af_packet_create_t *mp;
18671   u8 *host_if_name = 0;
18672   u8 hw_addr[6];
18673   u8 random_hw_addr = 1;
18674   int ret;
18675
18676   clib_memset (hw_addr, 0, sizeof (hw_addr));
18677
18678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18679     {
18680       if (unformat (i, "name %s", &host_if_name))
18681         vec_add1 (host_if_name, 0);
18682       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18683         random_hw_addr = 0;
18684       else
18685         break;
18686     }
18687
18688   if (!vec_len (host_if_name))
18689     {
18690       errmsg ("host-interface name must be specified");
18691       return -99;
18692     }
18693
18694   if (vec_len (host_if_name) > 64)
18695     {
18696       errmsg ("host-interface name too long");
18697       return -99;
18698     }
18699
18700   M (AF_PACKET_CREATE, mp);
18701
18702   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18703   clib_memcpy (mp->hw_addr, hw_addr, 6);
18704   mp->use_random_hw_addr = random_hw_addr;
18705   vec_free (host_if_name);
18706
18707   S (mp);
18708
18709   /* *INDENT-OFF* */
18710   W2 (ret,
18711       ({
18712         if (ret == 0)
18713           fprintf (vam->ofp ? vam->ofp : stderr,
18714                    " new sw_if_index = %d\n", vam->sw_if_index);
18715       }));
18716   /* *INDENT-ON* */
18717   return ret;
18718 }
18719
18720 static int
18721 api_af_packet_delete (vat_main_t * vam)
18722 {
18723   unformat_input_t *i = vam->input;
18724   vl_api_af_packet_delete_t *mp;
18725   u8 *host_if_name = 0;
18726   int ret;
18727
18728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18729     {
18730       if (unformat (i, "name %s", &host_if_name))
18731         vec_add1 (host_if_name, 0);
18732       else
18733         break;
18734     }
18735
18736   if (!vec_len (host_if_name))
18737     {
18738       errmsg ("host-interface name must be specified");
18739       return -99;
18740     }
18741
18742   if (vec_len (host_if_name) > 64)
18743     {
18744       errmsg ("host-interface name too long");
18745       return -99;
18746     }
18747
18748   M (AF_PACKET_DELETE, mp);
18749
18750   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18751   vec_free (host_if_name);
18752
18753   S (mp);
18754   W (ret);
18755   return ret;
18756 }
18757
18758 static void vl_api_af_packet_details_t_handler
18759   (vl_api_af_packet_details_t * mp)
18760 {
18761   vat_main_t *vam = &vat_main;
18762
18763   print (vam->ofp, "%-16s %d",
18764          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18765 }
18766
18767 static void vl_api_af_packet_details_t_handler_json
18768   (vl_api_af_packet_details_t * mp)
18769 {
18770   vat_main_t *vam = &vat_main;
18771   vat_json_node_t *node = NULL;
18772
18773   if (VAT_JSON_ARRAY != vam->json_tree.type)
18774     {
18775       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18776       vat_json_init_array (&vam->json_tree);
18777     }
18778   node = vat_json_array_add (&vam->json_tree);
18779
18780   vat_json_init_object (node);
18781   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18782   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18783 }
18784
18785 static int
18786 api_af_packet_dump (vat_main_t * vam)
18787 {
18788   vl_api_af_packet_dump_t *mp;
18789   vl_api_control_ping_t *mp_ping;
18790   int ret;
18791
18792   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18793   /* Get list of tap interfaces */
18794   M (AF_PACKET_DUMP, mp);
18795   S (mp);
18796
18797   /* Use a control ping for synchronization */
18798   MPING (CONTROL_PING, mp_ping);
18799   S (mp_ping);
18800
18801   W (ret);
18802   return ret;
18803 }
18804
18805 static int
18806 api_policer_add_del (vat_main_t * vam)
18807 {
18808   unformat_input_t *i = vam->input;
18809   vl_api_policer_add_del_t *mp;
18810   u8 is_add = 1;
18811   u8 *name = 0;
18812   u32 cir = 0;
18813   u32 eir = 0;
18814   u64 cb = 0;
18815   u64 eb = 0;
18816   u8 rate_type = 0;
18817   u8 round_type = 0;
18818   u8 type = 0;
18819   u8 color_aware = 0;
18820   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18821   int ret;
18822
18823   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18824   conform_action.dscp = 0;
18825   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18826   exceed_action.dscp = 0;
18827   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18828   violate_action.dscp = 0;
18829
18830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18831     {
18832       if (unformat (i, "del"))
18833         is_add = 0;
18834       else if (unformat (i, "name %s", &name))
18835         vec_add1 (name, 0);
18836       else if (unformat (i, "cir %u", &cir))
18837         ;
18838       else if (unformat (i, "eir %u", &eir))
18839         ;
18840       else if (unformat (i, "cb %u", &cb))
18841         ;
18842       else if (unformat (i, "eb %u", &eb))
18843         ;
18844       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18845                          &rate_type))
18846         ;
18847       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18848                          &round_type))
18849         ;
18850       else if (unformat (i, "type %U", unformat_policer_type, &type))
18851         ;
18852       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18853                          &conform_action))
18854         ;
18855       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18856                          &exceed_action))
18857         ;
18858       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18859                          &violate_action))
18860         ;
18861       else if (unformat (i, "color-aware"))
18862         color_aware = 1;
18863       else
18864         break;
18865     }
18866
18867   if (!vec_len (name))
18868     {
18869       errmsg ("policer name must be specified");
18870       return -99;
18871     }
18872
18873   if (vec_len (name) > 64)
18874     {
18875       errmsg ("policer name too long");
18876       return -99;
18877     }
18878
18879   M (POLICER_ADD_DEL, mp);
18880
18881   clib_memcpy (mp->name, name, vec_len (name));
18882   vec_free (name);
18883   mp->is_add = is_add;
18884   mp->cir = ntohl (cir);
18885   mp->eir = ntohl (eir);
18886   mp->cb = clib_net_to_host_u64 (cb);
18887   mp->eb = clib_net_to_host_u64 (eb);
18888   mp->rate_type = rate_type;
18889   mp->round_type = round_type;
18890   mp->type = type;
18891   mp->conform_action_type = conform_action.action_type;
18892   mp->conform_dscp = conform_action.dscp;
18893   mp->exceed_action_type = exceed_action.action_type;
18894   mp->exceed_dscp = exceed_action.dscp;
18895   mp->violate_action_type = violate_action.action_type;
18896   mp->violate_dscp = violate_action.dscp;
18897   mp->color_aware = color_aware;
18898
18899   S (mp);
18900   W (ret);
18901   return ret;
18902 }
18903
18904 static int
18905 api_policer_dump (vat_main_t * vam)
18906 {
18907   unformat_input_t *i = vam->input;
18908   vl_api_policer_dump_t *mp;
18909   vl_api_control_ping_t *mp_ping;
18910   u8 *match_name = 0;
18911   u8 match_name_valid = 0;
18912   int ret;
18913
18914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18915     {
18916       if (unformat (i, "name %s", &match_name))
18917         {
18918           vec_add1 (match_name, 0);
18919           match_name_valid = 1;
18920         }
18921       else
18922         break;
18923     }
18924
18925   M (POLICER_DUMP, mp);
18926   mp->match_name_valid = match_name_valid;
18927   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18928   vec_free (match_name);
18929   /* send it... */
18930   S (mp);
18931
18932   /* Use a control ping for synchronization */
18933   MPING (CONTROL_PING, mp_ping);
18934   S (mp_ping);
18935
18936   /* Wait for a reply... */
18937   W (ret);
18938   return ret;
18939 }
18940
18941 static int
18942 api_policer_classify_set_interface (vat_main_t * vam)
18943 {
18944   unformat_input_t *i = vam->input;
18945   vl_api_policer_classify_set_interface_t *mp;
18946   u32 sw_if_index;
18947   int sw_if_index_set;
18948   u32 ip4_table_index = ~0;
18949   u32 ip6_table_index = ~0;
18950   u32 l2_table_index = ~0;
18951   u8 is_add = 1;
18952   int ret;
18953
18954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18955     {
18956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18957         sw_if_index_set = 1;
18958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18959         sw_if_index_set = 1;
18960       else if (unformat (i, "del"))
18961         is_add = 0;
18962       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18963         ;
18964       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18965         ;
18966       else if (unformat (i, "l2-table %d", &l2_table_index))
18967         ;
18968       else
18969         {
18970           clib_warning ("parse error '%U'", format_unformat_error, i);
18971           return -99;
18972         }
18973     }
18974
18975   if (sw_if_index_set == 0)
18976     {
18977       errmsg ("missing interface name or sw_if_index");
18978       return -99;
18979     }
18980
18981   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18982
18983   mp->sw_if_index = ntohl (sw_if_index);
18984   mp->ip4_table_index = ntohl (ip4_table_index);
18985   mp->ip6_table_index = ntohl (ip6_table_index);
18986   mp->l2_table_index = ntohl (l2_table_index);
18987   mp->is_add = is_add;
18988
18989   S (mp);
18990   W (ret);
18991   return ret;
18992 }
18993
18994 static int
18995 api_policer_classify_dump (vat_main_t * vam)
18996 {
18997   unformat_input_t *i = vam->input;
18998   vl_api_policer_classify_dump_t *mp;
18999   vl_api_control_ping_t *mp_ping;
19000   u8 type = POLICER_CLASSIFY_N_TABLES;
19001   int ret;
19002
19003   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19004     ;
19005   else
19006     {
19007       errmsg ("classify table type must be specified");
19008       return -99;
19009     }
19010
19011   if (!vam->json_output)
19012     {
19013       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19014     }
19015
19016   M (POLICER_CLASSIFY_DUMP, mp);
19017   mp->type = type;
19018   /* send it... */
19019   S (mp);
19020
19021   /* Use a control ping for synchronization */
19022   MPING (CONTROL_PING, mp_ping);
19023   S (mp_ping);
19024
19025   /* Wait for a reply... */
19026   W (ret);
19027   return ret;
19028 }
19029
19030 static int
19031 api_netmap_create (vat_main_t * vam)
19032 {
19033   unformat_input_t *i = vam->input;
19034   vl_api_netmap_create_t *mp;
19035   u8 *if_name = 0;
19036   u8 hw_addr[6];
19037   u8 random_hw_addr = 1;
19038   u8 is_pipe = 0;
19039   u8 is_master = 0;
19040   int ret;
19041
19042   clib_memset (hw_addr, 0, sizeof (hw_addr));
19043
19044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19045     {
19046       if (unformat (i, "name %s", &if_name))
19047         vec_add1 (if_name, 0);
19048       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19049         random_hw_addr = 0;
19050       else if (unformat (i, "pipe"))
19051         is_pipe = 1;
19052       else if (unformat (i, "master"))
19053         is_master = 1;
19054       else if (unformat (i, "slave"))
19055         is_master = 0;
19056       else
19057         break;
19058     }
19059
19060   if (!vec_len (if_name))
19061     {
19062       errmsg ("interface name must be specified");
19063       return -99;
19064     }
19065
19066   if (vec_len (if_name) > 64)
19067     {
19068       errmsg ("interface name too long");
19069       return -99;
19070     }
19071
19072   M (NETMAP_CREATE, mp);
19073
19074   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19075   clib_memcpy (mp->hw_addr, hw_addr, 6);
19076   mp->use_random_hw_addr = random_hw_addr;
19077   mp->is_pipe = is_pipe;
19078   mp->is_master = is_master;
19079   vec_free (if_name);
19080
19081   S (mp);
19082   W (ret);
19083   return ret;
19084 }
19085
19086 static int
19087 api_netmap_delete (vat_main_t * vam)
19088 {
19089   unformat_input_t *i = vam->input;
19090   vl_api_netmap_delete_t *mp;
19091   u8 *if_name = 0;
19092   int ret;
19093
19094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19095     {
19096       if (unformat (i, "name %s", &if_name))
19097         vec_add1 (if_name, 0);
19098       else
19099         break;
19100     }
19101
19102   if (!vec_len (if_name))
19103     {
19104       errmsg ("interface name must be specified");
19105       return -99;
19106     }
19107
19108   if (vec_len (if_name) > 64)
19109     {
19110       errmsg ("interface name too long");
19111       return -99;
19112     }
19113
19114   M (NETMAP_DELETE, mp);
19115
19116   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19117   vec_free (if_name);
19118
19119   S (mp);
19120   W (ret);
19121   return ret;
19122 }
19123
19124 static void
19125 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19126 {
19127   if (fp->afi == IP46_TYPE_IP6)
19128     print (vam->ofp,
19129            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19130            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19131            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19132            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19133            format_ip6_address, fp->next_hop);
19134   else if (fp->afi == IP46_TYPE_IP4)
19135     print (vam->ofp,
19136            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19137            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19138            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19139            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19140            format_ip4_address, fp->next_hop);
19141 }
19142
19143 static void
19144 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19145                                  vl_api_fib_path_t * fp)
19146 {
19147   struct in_addr ip4;
19148   struct in6_addr ip6;
19149
19150   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19151   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19152   vat_json_object_add_uint (node, "is_local", fp->is_local);
19153   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19154   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19155   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19156   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19157   if (fp->afi == IP46_TYPE_IP4)
19158     {
19159       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19160       vat_json_object_add_ip4 (node, "next_hop", ip4);
19161     }
19162   else if (fp->afi == IP46_TYPE_IP6)
19163     {
19164       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19165       vat_json_object_add_ip6 (node, "next_hop", ip6);
19166     }
19167 }
19168
19169 static void
19170 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19171 {
19172   vat_main_t *vam = &vat_main;
19173   int count = ntohl (mp->mt_count);
19174   vl_api_fib_path_t *fp;
19175   i32 i;
19176
19177   print (vam->ofp, "[%d]: sw_if_index %d via:",
19178          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19179   fp = mp->mt_paths;
19180   for (i = 0; i < count; i++)
19181     {
19182       vl_api_mpls_fib_path_print (vam, fp);
19183       fp++;
19184     }
19185
19186   print (vam->ofp, "");
19187 }
19188
19189 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19190 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19191
19192 static void
19193 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19194 {
19195   vat_main_t *vam = &vat_main;
19196   vat_json_node_t *node = NULL;
19197   int count = ntohl (mp->mt_count);
19198   vl_api_fib_path_t *fp;
19199   i32 i;
19200
19201   if (VAT_JSON_ARRAY != vam->json_tree.type)
19202     {
19203       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19204       vat_json_init_array (&vam->json_tree);
19205     }
19206   node = vat_json_array_add (&vam->json_tree);
19207
19208   vat_json_init_object (node);
19209   vat_json_object_add_uint (node, "tunnel_index",
19210                             ntohl (mp->mt_tunnel_index));
19211   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19212
19213   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19214
19215   fp = mp->mt_paths;
19216   for (i = 0; i < count; i++)
19217     {
19218       vl_api_mpls_fib_path_json_print (node, fp);
19219       fp++;
19220     }
19221 }
19222
19223 static int
19224 api_mpls_tunnel_dump (vat_main_t * vam)
19225 {
19226   vl_api_mpls_tunnel_dump_t *mp;
19227   vl_api_control_ping_t *mp_ping;
19228   u32 sw_if_index = ~0;
19229   int ret;
19230
19231   /* Parse args required to build the message */
19232   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19233     {
19234       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19235         ;
19236     }
19237
19238   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19239
19240   M (MPLS_TUNNEL_DUMP, mp);
19241   mp->sw_if_index = htonl (sw_if_index);
19242   S (mp);
19243
19244   /* Use a control ping for synchronization */
19245   MPING (CONTROL_PING, mp_ping);
19246   S (mp_ping);
19247
19248   W (ret);
19249   return ret;
19250 }
19251
19252 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19253 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19254
19255
19256 static void
19257 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19258 {
19259   vat_main_t *vam = &vat_main;
19260   int count = ntohl (mp->count);
19261   vl_api_fib_path_t *fp;
19262   int i;
19263
19264   print (vam->ofp,
19265          "table-id %d, label %u, ess_bit %u",
19266          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19267   fp = mp->path;
19268   for (i = 0; i < count; i++)
19269     {
19270       vl_api_mpls_fib_path_print (vam, fp);
19271       fp++;
19272     }
19273 }
19274
19275 static void vl_api_mpls_fib_details_t_handler_json
19276   (vl_api_mpls_fib_details_t * mp)
19277 {
19278   vat_main_t *vam = &vat_main;
19279   int count = ntohl (mp->count);
19280   vat_json_node_t *node = NULL;
19281   vl_api_fib_path_t *fp;
19282   int i;
19283
19284   if (VAT_JSON_ARRAY != vam->json_tree.type)
19285     {
19286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19287       vat_json_init_array (&vam->json_tree);
19288     }
19289   node = vat_json_array_add (&vam->json_tree);
19290
19291   vat_json_init_object (node);
19292   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19293   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19294   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19295   vat_json_object_add_uint (node, "path_count", count);
19296   fp = mp->path;
19297   for (i = 0; i < count; i++)
19298     {
19299       vl_api_mpls_fib_path_json_print (node, fp);
19300       fp++;
19301     }
19302 }
19303
19304 static int
19305 api_mpls_fib_dump (vat_main_t * vam)
19306 {
19307   vl_api_mpls_fib_dump_t *mp;
19308   vl_api_control_ping_t *mp_ping;
19309   int ret;
19310
19311   M (MPLS_FIB_DUMP, mp);
19312   S (mp);
19313
19314   /* Use a control ping for synchronization */
19315   MPING (CONTROL_PING, mp_ping);
19316   S (mp_ping);
19317
19318   W (ret);
19319   return ret;
19320 }
19321
19322 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19323 #define vl_api_ip_fib_details_t_print vl_noop_handler
19324
19325 static void
19326 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19327 {
19328   vat_main_t *vam = &vat_main;
19329   int count = ntohl (mp->count);
19330   vl_api_fib_path_t *fp;
19331   int i;
19332
19333   print (vam->ofp,
19334          "table-id %d, prefix %U/%d stats-index %d",
19335          ntohl (mp->table_id), format_ip4_address, mp->address,
19336          mp->address_length, ntohl (mp->stats_index));
19337   fp = mp->path;
19338   for (i = 0; i < count; i++)
19339     {
19340       if (fp->afi == IP46_TYPE_IP6)
19341         print (vam->ofp,
19342                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19343                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19344                "next_hop_table %d",
19345                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19346                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19347                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19348       else if (fp->afi == IP46_TYPE_IP4)
19349         print (vam->ofp,
19350                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19351                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19352                "next_hop_table %d",
19353                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19354                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19355                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19356       fp++;
19357     }
19358 }
19359
19360 static void vl_api_ip_fib_details_t_handler_json
19361   (vl_api_ip_fib_details_t * mp)
19362 {
19363   vat_main_t *vam = &vat_main;
19364   int count = ntohl (mp->count);
19365   vat_json_node_t *node = NULL;
19366   struct in_addr ip4;
19367   struct in6_addr ip6;
19368   vl_api_fib_path_t *fp;
19369   int i;
19370
19371   if (VAT_JSON_ARRAY != vam->json_tree.type)
19372     {
19373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19374       vat_json_init_array (&vam->json_tree);
19375     }
19376   node = vat_json_array_add (&vam->json_tree);
19377
19378   vat_json_init_object (node);
19379   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19380   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19381   vat_json_object_add_ip4 (node, "prefix", ip4);
19382   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19383   vat_json_object_add_uint (node, "path_count", count);
19384   fp = mp->path;
19385   for (i = 0; i < count; i++)
19386     {
19387       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19388       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19389       vat_json_object_add_uint (node, "is_local", fp->is_local);
19390       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19391       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19392       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19393       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19394       if (fp->afi == IP46_TYPE_IP4)
19395         {
19396           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19397           vat_json_object_add_ip4 (node, "next_hop", ip4);
19398         }
19399       else if (fp->afi == IP46_TYPE_IP6)
19400         {
19401           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19402           vat_json_object_add_ip6 (node, "next_hop", ip6);
19403         }
19404     }
19405 }
19406
19407 static int
19408 api_ip_fib_dump (vat_main_t * vam)
19409 {
19410   vl_api_ip_fib_dump_t *mp;
19411   vl_api_control_ping_t *mp_ping;
19412   int ret;
19413
19414   M (IP_FIB_DUMP, mp);
19415   S (mp);
19416
19417   /* Use a control ping for synchronization */
19418   MPING (CONTROL_PING, mp_ping);
19419   S (mp_ping);
19420
19421   W (ret);
19422   return ret;
19423 }
19424
19425 static int
19426 api_ip_mfib_dump (vat_main_t * vam)
19427 {
19428   vl_api_ip_mfib_dump_t *mp;
19429   vl_api_control_ping_t *mp_ping;
19430   int ret;
19431
19432   M (IP_MFIB_DUMP, mp);
19433   S (mp);
19434
19435   /* Use a control ping for synchronization */
19436   MPING (CONTROL_PING, mp_ping);
19437   S (mp_ping);
19438
19439   W (ret);
19440   return ret;
19441 }
19442
19443 static void vl_api_ip_neighbor_details_t_handler
19444   (vl_api_ip_neighbor_details_t * mp)
19445 {
19446   vat_main_t *vam = &vat_main;
19447
19448   print (vam->ofp, "%c %U %U",
19449          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19450          format_vl_api_mac_address, &mp->neighbor.mac_address,
19451          format_vl_api_address, &mp->neighbor.ip_address);
19452 }
19453
19454 static void vl_api_ip_neighbor_details_t_handler_json
19455   (vl_api_ip_neighbor_details_t * mp)
19456 {
19457
19458   vat_main_t *vam = &vat_main;
19459   vat_json_node_t *node;
19460
19461   if (VAT_JSON_ARRAY != vam->json_tree.type)
19462     {
19463       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19464       vat_json_init_array (&vam->json_tree);
19465     }
19466   node = vat_json_array_add (&vam->json_tree);
19467
19468   vat_json_init_object (node);
19469   vat_json_object_add_string_copy
19470     (node, "flag",
19471      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19472       (u8 *) "static" : (u8 *) "dynamic"));
19473
19474   vat_json_object_add_string_copy (node, "link_layer",
19475                                    format (0, "%U", format_vl_api_mac_address,
19476                                            &mp->neighbor.mac_address));
19477   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19478 }
19479
19480 static int
19481 api_ip_neighbor_dump (vat_main_t * vam)
19482 {
19483   unformat_input_t *i = vam->input;
19484   vl_api_ip_neighbor_dump_t *mp;
19485   vl_api_control_ping_t *mp_ping;
19486   u8 is_ipv6 = 0;
19487   u32 sw_if_index = ~0;
19488   int ret;
19489
19490   /* Parse args required to build the message */
19491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19492     {
19493       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19494         ;
19495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19496         ;
19497       else if (unformat (i, "ip6"))
19498         is_ipv6 = 1;
19499       else
19500         break;
19501     }
19502
19503   if (sw_if_index == ~0)
19504     {
19505       errmsg ("missing interface name or sw_if_index");
19506       return -99;
19507     }
19508
19509   M (IP_NEIGHBOR_DUMP, mp);
19510   mp->is_ipv6 = (u8) is_ipv6;
19511   mp->sw_if_index = ntohl (sw_if_index);
19512   S (mp);
19513
19514   /* Use a control ping for synchronization */
19515   MPING (CONTROL_PING, mp_ping);
19516   S (mp_ping);
19517
19518   W (ret);
19519   return ret;
19520 }
19521
19522 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19523 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19524
19525 static void
19526 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19527 {
19528   vat_main_t *vam = &vat_main;
19529   int count = ntohl (mp->count);
19530   vl_api_fib_path_t *fp;
19531   int i;
19532
19533   print (vam->ofp,
19534          "table-id %d, prefix %U/%d stats-index %d",
19535          ntohl (mp->table_id), format_ip6_address, mp->address,
19536          mp->address_length, ntohl (mp->stats_index));
19537   fp = mp->path;
19538   for (i = 0; i < count; i++)
19539     {
19540       if (fp->afi == IP46_TYPE_IP6)
19541         print (vam->ofp,
19542                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19543                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19544                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19545                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19546                format_ip6_address, fp->next_hop);
19547       else if (fp->afi == IP46_TYPE_IP4)
19548         print (vam->ofp,
19549                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19550                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19551                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19552                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19553                format_ip4_address, fp->next_hop);
19554       fp++;
19555     }
19556 }
19557
19558 static void vl_api_ip6_fib_details_t_handler_json
19559   (vl_api_ip6_fib_details_t * mp)
19560 {
19561   vat_main_t *vam = &vat_main;
19562   int count = ntohl (mp->count);
19563   vat_json_node_t *node = NULL;
19564   struct in_addr ip4;
19565   struct in6_addr ip6;
19566   vl_api_fib_path_t *fp;
19567   int i;
19568
19569   if (VAT_JSON_ARRAY != vam->json_tree.type)
19570     {
19571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19572       vat_json_init_array (&vam->json_tree);
19573     }
19574   node = vat_json_array_add (&vam->json_tree);
19575
19576   vat_json_init_object (node);
19577   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19578   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19579   vat_json_object_add_ip6 (node, "prefix", ip6);
19580   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19581   vat_json_object_add_uint (node, "path_count", count);
19582   fp = mp->path;
19583   for (i = 0; i < count; i++)
19584     {
19585       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19586       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19587       vat_json_object_add_uint (node, "is_local", fp->is_local);
19588       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19589       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19590       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19591       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19592       if (fp->afi == IP46_TYPE_IP4)
19593         {
19594           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19595           vat_json_object_add_ip4 (node, "next_hop", ip4);
19596         }
19597       else if (fp->afi == IP46_TYPE_IP6)
19598         {
19599           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19600           vat_json_object_add_ip6 (node, "next_hop", ip6);
19601         }
19602     }
19603 }
19604
19605 static int
19606 api_ip6_fib_dump (vat_main_t * vam)
19607 {
19608   vl_api_ip6_fib_dump_t *mp;
19609   vl_api_control_ping_t *mp_ping;
19610   int ret;
19611
19612   M (IP6_FIB_DUMP, mp);
19613   S (mp);
19614
19615   /* Use a control ping for synchronization */
19616   MPING (CONTROL_PING, mp_ping);
19617   S (mp_ping);
19618
19619   W (ret);
19620   return ret;
19621 }
19622
19623 static int
19624 api_ip6_mfib_dump (vat_main_t * vam)
19625 {
19626   vl_api_ip6_mfib_dump_t *mp;
19627   vl_api_control_ping_t *mp_ping;
19628   int ret;
19629
19630   M (IP6_MFIB_DUMP, mp);
19631   S (mp);
19632
19633   /* Use a control ping for synchronization */
19634   MPING (CONTROL_PING, mp_ping);
19635   S (mp_ping);
19636
19637   W (ret);
19638   return ret;
19639 }
19640
19641 int
19642 api_classify_table_ids (vat_main_t * vam)
19643 {
19644   vl_api_classify_table_ids_t *mp;
19645   int ret;
19646
19647   /* Construct the API message */
19648   M (CLASSIFY_TABLE_IDS, mp);
19649   mp->context = 0;
19650
19651   S (mp);
19652   W (ret);
19653   return ret;
19654 }
19655
19656 int
19657 api_classify_table_by_interface (vat_main_t * vam)
19658 {
19659   unformat_input_t *input = vam->input;
19660   vl_api_classify_table_by_interface_t *mp;
19661
19662   u32 sw_if_index = ~0;
19663   int ret;
19664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19665     {
19666       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19667         ;
19668       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19669         ;
19670       else
19671         break;
19672     }
19673   if (sw_if_index == ~0)
19674     {
19675       errmsg ("missing interface name or sw_if_index");
19676       return -99;
19677     }
19678
19679   /* Construct the API message */
19680   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19681   mp->context = 0;
19682   mp->sw_if_index = ntohl (sw_if_index);
19683
19684   S (mp);
19685   W (ret);
19686   return ret;
19687 }
19688
19689 int
19690 api_classify_table_info (vat_main_t * vam)
19691 {
19692   unformat_input_t *input = vam->input;
19693   vl_api_classify_table_info_t *mp;
19694
19695   u32 table_id = ~0;
19696   int ret;
19697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19698     {
19699       if (unformat (input, "table_id %d", &table_id))
19700         ;
19701       else
19702         break;
19703     }
19704   if (table_id == ~0)
19705     {
19706       errmsg ("missing table id");
19707       return -99;
19708     }
19709
19710   /* Construct the API message */
19711   M (CLASSIFY_TABLE_INFO, mp);
19712   mp->context = 0;
19713   mp->table_id = ntohl (table_id);
19714
19715   S (mp);
19716   W (ret);
19717   return ret;
19718 }
19719
19720 int
19721 api_classify_session_dump (vat_main_t * vam)
19722 {
19723   unformat_input_t *input = vam->input;
19724   vl_api_classify_session_dump_t *mp;
19725   vl_api_control_ping_t *mp_ping;
19726
19727   u32 table_id = ~0;
19728   int ret;
19729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19730     {
19731       if (unformat (input, "table_id %d", &table_id))
19732         ;
19733       else
19734         break;
19735     }
19736   if (table_id == ~0)
19737     {
19738       errmsg ("missing table id");
19739       return -99;
19740     }
19741
19742   /* Construct the API message */
19743   M (CLASSIFY_SESSION_DUMP, mp);
19744   mp->context = 0;
19745   mp->table_id = ntohl (table_id);
19746   S (mp);
19747
19748   /* Use a control ping for synchronization */
19749   MPING (CONTROL_PING, mp_ping);
19750   S (mp_ping);
19751
19752   W (ret);
19753   return ret;
19754 }
19755
19756 static void
19757 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19758 {
19759   vat_main_t *vam = &vat_main;
19760
19761   print (vam->ofp, "collector_address %U, collector_port %d, "
19762          "src_address %U, vrf_id %d, path_mtu %u, "
19763          "template_interval %u, udp_checksum %d",
19764          format_ip4_address, mp->collector_address,
19765          ntohs (mp->collector_port),
19766          format_ip4_address, mp->src_address,
19767          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19768          ntohl (mp->template_interval), mp->udp_checksum);
19769
19770   vam->retval = 0;
19771   vam->result_ready = 1;
19772 }
19773
19774 static void
19775   vl_api_ipfix_exporter_details_t_handler_json
19776   (vl_api_ipfix_exporter_details_t * mp)
19777 {
19778   vat_main_t *vam = &vat_main;
19779   vat_json_node_t node;
19780   struct in_addr collector_address;
19781   struct in_addr src_address;
19782
19783   vat_json_init_object (&node);
19784   clib_memcpy (&collector_address, &mp->collector_address,
19785                sizeof (collector_address));
19786   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19787   vat_json_object_add_uint (&node, "collector_port",
19788                             ntohs (mp->collector_port));
19789   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19790   vat_json_object_add_ip4 (&node, "src_address", src_address);
19791   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19792   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19793   vat_json_object_add_uint (&node, "template_interval",
19794                             ntohl (mp->template_interval));
19795   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19796
19797   vat_json_print (vam->ofp, &node);
19798   vat_json_free (&node);
19799   vam->retval = 0;
19800   vam->result_ready = 1;
19801 }
19802
19803 int
19804 api_ipfix_exporter_dump (vat_main_t * vam)
19805 {
19806   vl_api_ipfix_exporter_dump_t *mp;
19807   int ret;
19808
19809   /* Construct the API message */
19810   M (IPFIX_EXPORTER_DUMP, mp);
19811   mp->context = 0;
19812
19813   S (mp);
19814   W (ret);
19815   return ret;
19816 }
19817
19818 static int
19819 api_ipfix_classify_stream_dump (vat_main_t * vam)
19820 {
19821   vl_api_ipfix_classify_stream_dump_t *mp;
19822   int ret;
19823
19824   /* Construct the API message */
19825   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19826   mp->context = 0;
19827
19828   S (mp);
19829   W (ret);
19830   return ret;
19831   /* NOTREACHED */
19832   return 0;
19833 }
19834
19835 static void
19836   vl_api_ipfix_classify_stream_details_t_handler
19837   (vl_api_ipfix_classify_stream_details_t * mp)
19838 {
19839   vat_main_t *vam = &vat_main;
19840   print (vam->ofp, "domain_id %d, src_port %d",
19841          ntohl (mp->domain_id), ntohs (mp->src_port));
19842   vam->retval = 0;
19843   vam->result_ready = 1;
19844 }
19845
19846 static void
19847   vl_api_ipfix_classify_stream_details_t_handler_json
19848   (vl_api_ipfix_classify_stream_details_t * mp)
19849 {
19850   vat_main_t *vam = &vat_main;
19851   vat_json_node_t node;
19852
19853   vat_json_init_object (&node);
19854   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19855   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19856
19857   vat_json_print (vam->ofp, &node);
19858   vat_json_free (&node);
19859   vam->retval = 0;
19860   vam->result_ready = 1;
19861 }
19862
19863 static int
19864 api_ipfix_classify_table_dump (vat_main_t * vam)
19865 {
19866   vl_api_ipfix_classify_table_dump_t *mp;
19867   vl_api_control_ping_t *mp_ping;
19868   int ret;
19869
19870   if (!vam->json_output)
19871     {
19872       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19873              "transport_protocol");
19874     }
19875
19876   /* Construct the API message */
19877   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19878
19879   /* send it... */
19880   S (mp);
19881
19882   /* Use a control ping for synchronization */
19883   MPING (CONTROL_PING, mp_ping);
19884   S (mp_ping);
19885
19886   W (ret);
19887   return ret;
19888 }
19889
19890 static void
19891   vl_api_ipfix_classify_table_details_t_handler
19892   (vl_api_ipfix_classify_table_details_t * mp)
19893 {
19894   vat_main_t *vam = &vat_main;
19895   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19896          mp->transport_protocol);
19897 }
19898
19899 static void
19900   vl_api_ipfix_classify_table_details_t_handler_json
19901   (vl_api_ipfix_classify_table_details_t * mp)
19902 {
19903   vat_json_node_t *node = NULL;
19904   vat_main_t *vam = &vat_main;
19905
19906   if (VAT_JSON_ARRAY != vam->json_tree.type)
19907     {
19908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19909       vat_json_init_array (&vam->json_tree);
19910     }
19911
19912   node = vat_json_array_add (&vam->json_tree);
19913   vat_json_init_object (node);
19914
19915   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19916   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19917   vat_json_object_add_uint (node, "transport_protocol",
19918                             mp->transport_protocol);
19919 }
19920
19921 static int
19922 api_sw_interface_span_enable_disable (vat_main_t * vam)
19923 {
19924   unformat_input_t *i = vam->input;
19925   vl_api_sw_interface_span_enable_disable_t *mp;
19926   u32 src_sw_if_index = ~0;
19927   u32 dst_sw_if_index = ~0;
19928   u8 state = 3;
19929   int ret;
19930   u8 is_l2 = 0;
19931
19932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19933     {
19934       if (unformat
19935           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19936         ;
19937       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19938         ;
19939       else
19940         if (unformat
19941             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19942         ;
19943       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19944         ;
19945       else if (unformat (i, "disable"))
19946         state = 0;
19947       else if (unformat (i, "rx"))
19948         state = 1;
19949       else if (unformat (i, "tx"))
19950         state = 2;
19951       else if (unformat (i, "both"))
19952         state = 3;
19953       else if (unformat (i, "l2"))
19954         is_l2 = 1;
19955       else
19956         break;
19957     }
19958
19959   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19960
19961   mp->sw_if_index_from = htonl (src_sw_if_index);
19962   mp->sw_if_index_to = htonl (dst_sw_if_index);
19963   mp->state = state;
19964   mp->is_l2 = is_l2;
19965
19966   S (mp);
19967   W (ret);
19968   return ret;
19969 }
19970
19971 static void
19972 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19973                                             * mp)
19974 {
19975   vat_main_t *vam = &vat_main;
19976   u8 *sw_if_from_name = 0;
19977   u8 *sw_if_to_name = 0;
19978   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19979   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19980   char *states[] = { "none", "rx", "tx", "both" };
19981   hash_pair_t *p;
19982
19983   /* *INDENT-OFF* */
19984   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19985   ({
19986     if ((u32) p->value[0] == sw_if_index_from)
19987       {
19988         sw_if_from_name = (u8 *)(p->key);
19989         if (sw_if_to_name)
19990           break;
19991       }
19992     if ((u32) p->value[0] == sw_if_index_to)
19993       {
19994         sw_if_to_name = (u8 *)(p->key);
19995         if (sw_if_from_name)
19996           break;
19997       }
19998   }));
19999   /* *INDENT-ON* */
20000   print (vam->ofp, "%20s => %20s (%s) %s",
20001          sw_if_from_name, sw_if_to_name, states[mp->state],
20002          mp->is_l2 ? "l2" : "device");
20003 }
20004
20005 static void
20006   vl_api_sw_interface_span_details_t_handler_json
20007   (vl_api_sw_interface_span_details_t * mp)
20008 {
20009   vat_main_t *vam = &vat_main;
20010   vat_json_node_t *node = NULL;
20011   u8 *sw_if_from_name = 0;
20012   u8 *sw_if_to_name = 0;
20013   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20014   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20015   hash_pair_t *p;
20016
20017   /* *INDENT-OFF* */
20018   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20019   ({
20020     if ((u32) p->value[0] == sw_if_index_from)
20021       {
20022         sw_if_from_name = (u8 *)(p->key);
20023         if (sw_if_to_name)
20024           break;
20025       }
20026     if ((u32) p->value[0] == sw_if_index_to)
20027       {
20028         sw_if_to_name = (u8 *)(p->key);
20029         if (sw_if_from_name)
20030           break;
20031       }
20032   }));
20033   /* *INDENT-ON* */
20034
20035   if (VAT_JSON_ARRAY != vam->json_tree.type)
20036     {
20037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20038       vat_json_init_array (&vam->json_tree);
20039     }
20040   node = vat_json_array_add (&vam->json_tree);
20041
20042   vat_json_init_object (node);
20043   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20044   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20045   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20046   if (0 != sw_if_to_name)
20047     {
20048       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20049     }
20050   vat_json_object_add_uint (node, "state", mp->state);
20051   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20052 }
20053
20054 static int
20055 api_sw_interface_span_dump (vat_main_t * vam)
20056 {
20057   unformat_input_t *input = vam->input;
20058   vl_api_sw_interface_span_dump_t *mp;
20059   vl_api_control_ping_t *mp_ping;
20060   u8 is_l2 = 0;
20061   int ret;
20062
20063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20064     {
20065       if (unformat (input, "l2"))
20066         is_l2 = 1;
20067       else
20068         break;
20069     }
20070
20071   M (SW_INTERFACE_SPAN_DUMP, mp);
20072   mp->is_l2 = is_l2;
20073   S (mp);
20074
20075   /* Use a control ping for synchronization */
20076   MPING (CONTROL_PING, mp_ping);
20077   S (mp_ping);
20078
20079   W (ret);
20080   return ret;
20081 }
20082
20083 int
20084 api_pg_create_interface (vat_main_t * vam)
20085 {
20086   unformat_input_t *input = vam->input;
20087   vl_api_pg_create_interface_t *mp;
20088
20089   u32 if_id = ~0;
20090   int ret;
20091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20092     {
20093       if (unformat (input, "if_id %d", &if_id))
20094         ;
20095       else
20096         break;
20097     }
20098   if (if_id == ~0)
20099     {
20100       errmsg ("missing pg interface index");
20101       return -99;
20102     }
20103
20104   /* Construct the API message */
20105   M (PG_CREATE_INTERFACE, mp);
20106   mp->context = 0;
20107   mp->interface_id = ntohl (if_id);
20108
20109   S (mp);
20110   W (ret);
20111   return ret;
20112 }
20113
20114 int
20115 api_pg_capture (vat_main_t * vam)
20116 {
20117   unformat_input_t *input = vam->input;
20118   vl_api_pg_capture_t *mp;
20119
20120   u32 if_id = ~0;
20121   u8 enable = 1;
20122   u32 count = 1;
20123   u8 pcap_file_set = 0;
20124   u8 *pcap_file = 0;
20125   int ret;
20126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20127     {
20128       if (unformat (input, "if_id %d", &if_id))
20129         ;
20130       else if (unformat (input, "pcap %s", &pcap_file))
20131         pcap_file_set = 1;
20132       else if (unformat (input, "count %d", &count))
20133         ;
20134       else if (unformat (input, "disable"))
20135         enable = 0;
20136       else
20137         break;
20138     }
20139   if (if_id == ~0)
20140     {
20141       errmsg ("missing pg interface index");
20142       return -99;
20143     }
20144   if (pcap_file_set > 0)
20145     {
20146       if (vec_len (pcap_file) > 255)
20147         {
20148           errmsg ("pcap file name is too long");
20149           return -99;
20150         }
20151     }
20152
20153   u32 name_len = vec_len (pcap_file);
20154   /* Construct the API message */
20155   M (PG_CAPTURE, mp);
20156   mp->context = 0;
20157   mp->interface_id = ntohl (if_id);
20158   mp->is_enabled = enable;
20159   mp->count = ntohl (count);
20160   mp->pcap_name_length = ntohl (name_len);
20161   if (pcap_file_set != 0)
20162     {
20163       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20164     }
20165   vec_free (pcap_file);
20166
20167   S (mp);
20168   W (ret);
20169   return ret;
20170 }
20171
20172 int
20173 api_pg_enable_disable (vat_main_t * vam)
20174 {
20175   unformat_input_t *input = vam->input;
20176   vl_api_pg_enable_disable_t *mp;
20177
20178   u8 enable = 1;
20179   u8 stream_name_set = 0;
20180   u8 *stream_name = 0;
20181   int ret;
20182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20183     {
20184       if (unformat (input, "stream %s", &stream_name))
20185         stream_name_set = 1;
20186       else if (unformat (input, "disable"))
20187         enable = 0;
20188       else
20189         break;
20190     }
20191
20192   if (stream_name_set > 0)
20193     {
20194       if (vec_len (stream_name) > 255)
20195         {
20196           errmsg ("stream name too long");
20197           return -99;
20198         }
20199     }
20200
20201   u32 name_len = vec_len (stream_name);
20202   /* Construct the API message */
20203   M (PG_ENABLE_DISABLE, mp);
20204   mp->context = 0;
20205   mp->is_enabled = enable;
20206   if (stream_name_set != 0)
20207     {
20208       mp->stream_name_length = ntohl (name_len);
20209       clib_memcpy (mp->stream_name, stream_name, name_len);
20210     }
20211   vec_free (stream_name);
20212
20213   S (mp);
20214   W (ret);
20215   return ret;
20216 }
20217
20218 int
20219 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20220 {
20221   unformat_input_t *input = vam->input;
20222   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20223
20224   u16 *low_ports = 0;
20225   u16 *high_ports = 0;
20226   u16 this_low;
20227   u16 this_hi;
20228   vl_api_prefix_t prefix;
20229   u32 tmp, tmp2;
20230   u8 prefix_set = 0;
20231   u32 vrf_id = ~0;
20232   u8 is_add = 1;
20233   u8 is_ipv6 = 0;
20234   int ret;
20235
20236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20237     {
20238       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20239         prefix_set = 1;
20240       else if (unformat (input, "vrf %d", &vrf_id))
20241         ;
20242       else if (unformat (input, "del"))
20243         is_add = 0;
20244       else if (unformat (input, "port %d", &tmp))
20245         {
20246           if (tmp == 0 || tmp > 65535)
20247             {
20248               errmsg ("port %d out of range", tmp);
20249               return -99;
20250             }
20251           this_low = tmp;
20252           this_hi = this_low + 1;
20253           vec_add1 (low_ports, this_low);
20254           vec_add1 (high_ports, this_hi);
20255         }
20256       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20257         {
20258           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20259             {
20260               errmsg ("incorrect range parameters");
20261               return -99;
20262             }
20263           this_low = tmp;
20264           /* Note: in debug CLI +1 is added to high before
20265              passing to real fn that does "the work"
20266              (ip_source_and_port_range_check_add_del).
20267              This fn is a wrapper around the binary API fn a
20268              control plane will call, which expects this increment
20269              to have occurred. Hence letting the binary API control
20270              plane fn do the increment for consistency between VAT
20271              and other control planes.
20272            */
20273           this_hi = tmp2;
20274           vec_add1 (low_ports, this_low);
20275           vec_add1 (high_ports, this_hi);
20276         }
20277       else
20278         break;
20279     }
20280
20281   if (prefix_set == 0)
20282     {
20283       errmsg ("<address>/<mask> not specified");
20284       return -99;
20285     }
20286
20287   if (vrf_id == ~0)
20288     {
20289       errmsg ("VRF ID required, not specified");
20290       return -99;
20291     }
20292
20293   if (vrf_id == 0)
20294     {
20295       errmsg
20296         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20297       return -99;
20298     }
20299
20300   if (vec_len (low_ports) == 0)
20301     {
20302       errmsg ("At least one port or port range required");
20303       return -99;
20304     }
20305
20306   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20307
20308   mp->is_add = is_add;
20309
20310   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20311
20312   mp->number_of_ranges = vec_len (low_ports);
20313
20314   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20315   vec_free (low_ports);
20316
20317   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20318   vec_free (high_ports);
20319
20320   mp->vrf_id = ntohl (vrf_id);
20321
20322   S (mp);
20323   W (ret);
20324   return ret;
20325 }
20326
20327 int
20328 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20329 {
20330   unformat_input_t *input = vam->input;
20331   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20332   u32 sw_if_index = ~0;
20333   int vrf_set = 0;
20334   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20335   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20336   u8 is_add = 1;
20337   int ret;
20338
20339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20340     {
20341       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20342         ;
20343       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20344         ;
20345       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20346         vrf_set = 1;
20347       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20348         vrf_set = 1;
20349       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20350         vrf_set = 1;
20351       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20352         vrf_set = 1;
20353       else if (unformat (input, "del"))
20354         is_add = 0;
20355       else
20356         break;
20357     }
20358
20359   if (sw_if_index == ~0)
20360     {
20361       errmsg ("Interface required but not specified");
20362       return -99;
20363     }
20364
20365   if (vrf_set == 0)
20366     {
20367       errmsg ("VRF ID required but not specified");
20368       return -99;
20369     }
20370
20371   if (tcp_out_vrf_id == 0
20372       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20373     {
20374       errmsg
20375         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20376       return -99;
20377     }
20378
20379   /* Construct the API message */
20380   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20381
20382   mp->sw_if_index = ntohl (sw_if_index);
20383   mp->is_add = is_add;
20384   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20385   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20386   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20387   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20388
20389   /* send it... */
20390   S (mp);
20391
20392   /* Wait for a reply... */
20393   W (ret);
20394   return ret;
20395 }
20396
20397 static int
20398 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20399 {
20400   unformat_input_t *i = vam->input;
20401   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20402   u32 local_sa_id = 0;
20403   u32 remote_sa_id = 0;
20404   vl_api_ip4_address_t src_address;
20405   vl_api_ip4_address_t dst_address;
20406   u8 is_add = 1;
20407   int ret;
20408
20409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20410     {
20411       if (unformat (i, "local_sa %d", &local_sa_id))
20412         ;
20413       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20414         ;
20415       else
20416         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20417         ;
20418       else
20419         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20420         ;
20421       else if (unformat (i, "del"))
20422         is_add = 0;
20423       else
20424         {
20425           clib_warning ("parse error '%U'", format_unformat_error, i);
20426           return -99;
20427         }
20428     }
20429
20430   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20431
20432   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20433   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20434   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20435   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20436   mp->is_add = is_add;
20437
20438   S (mp);
20439   W (ret);
20440   return ret;
20441 }
20442
20443 static int
20444 api_set_punt (vat_main_t * vam)
20445 {
20446   unformat_input_t *i = vam->input;
20447   vl_api_set_punt_t *mp;
20448   u32 ipv = ~0;
20449   u32 protocol = ~0;
20450   u32 port = ~0;
20451   int is_add = 1;
20452   int ret;
20453
20454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20455     {
20456       if (unformat (i, "ip %d", &ipv))
20457         ;
20458       else if (unformat (i, "protocol %d", &protocol))
20459         ;
20460       else if (unformat (i, "port %d", &port))
20461         ;
20462       else if (unformat (i, "del"))
20463         is_add = 0;
20464       else
20465         {
20466           clib_warning ("parse error '%U'", format_unformat_error, i);
20467           return -99;
20468         }
20469     }
20470
20471   M (SET_PUNT, mp);
20472
20473   mp->is_add = (u8) is_add;
20474   mp->punt.ipv = (u8) ipv;
20475   mp->punt.l4_protocol = (u8) protocol;
20476   mp->punt.l4_port = htons ((u16) port);
20477
20478   S (mp);
20479   W (ret);
20480   return ret;
20481 }
20482
20483 static void vl_api_ipsec_gre_tunnel_details_t_handler
20484   (vl_api_ipsec_gre_tunnel_details_t * mp)
20485 {
20486   vat_main_t *vam = &vat_main;
20487
20488   print (vam->ofp, "%11d%15U%15U%14d%14d",
20489          ntohl (mp->tunnel.sw_if_index),
20490          format_vl_api_ip4_address, mp->tunnel.src,
20491          format_vl_api_ip4_address, mp->tunnel.dst,
20492          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20493 }
20494
20495 static void
20496 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20497                                 const char *name,
20498                                 const vl_api_ip4_address_t addr)
20499 {
20500   struct in_addr ip4;
20501
20502   clib_memcpy (&ip4, addr, sizeof (ip4));
20503   vat_json_object_add_ip4 (node, name, ip4);
20504 }
20505
20506 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20507   (vl_api_ipsec_gre_tunnel_details_t * mp)
20508 {
20509   vat_main_t *vam = &vat_main;
20510   vat_json_node_t *node = NULL;
20511   struct in_addr ip4;
20512
20513   if (VAT_JSON_ARRAY != vam->json_tree.type)
20514     {
20515       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20516       vat_json_init_array (&vam->json_tree);
20517     }
20518   node = vat_json_array_add (&vam->json_tree);
20519
20520   vat_json_init_object (node);
20521   vat_json_object_add_uint (node, "sw_if_index",
20522                             ntohl (mp->tunnel.sw_if_index));
20523   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20524   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20525   vat_json_object_add_uint (node, "local_sa_id",
20526                             ntohl (mp->tunnel.local_sa_id));
20527   vat_json_object_add_uint (node, "remote_sa_id",
20528                             ntohl (mp->tunnel.remote_sa_id));
20529 }
20530
20531 static int
20532 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20533 {
20534   unformat_input_t *i = vam->input;
20535   vl_api_ipsec_gre_tunnel_dump_t *mp;
20536   vl_api_control_ping_t *mp_ping;
20537   u32 sw_if_index;
20538   u8 sw_if_index_set = 0;
20539   int ret;
20540
20541   /* Parse args required to build the message */
20542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20543     {
20544       if (unformat (i, "sw_if_index %d", &sw_if_index))
20545         sw_if_index_set = 1;
20546       else
20547         break;
20548     }
20549
20550   if (sw_if_index_set == 0)
20551     {
20552       sw_if_index = ~0;
20553     }
20554
20555   if (!vam->json_output)
20556     {
20557       print (vam->ofp, "%11s%15s%15s%14s%14s",
20558              "sw_if_index", "src_address", "dst_address",
20559              "local_sa_id", "remote_sa_id");
20560     }
20561
20562   /* Get list of gre-tunnel interfaces */
20563   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20564
20565   mp->sw_if_index = htonl (sw_if_index);
20566
20567   S (mp);
20568
20569   /* Use a control ping for synchronization */
20570   MPING (CONTROL_PING, mp_ping);
20571   S (mp_ping);
20572
20573   W (ret);
20574   return ret;
20575 }
20576
20577 static int
20578 api_delete_subif (vat_main_t * vam)
20579 {
20580   unformat_input_t *i = vam->input;
20581   vl_api_delete_subif_t *mp;
20582   u32 sw_if_index = ~0;
20583   int ret;
20584
20585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20586     {
20587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20588         ;
20589       if (unformat (i, "sw_if_index %d", &sw_if_index))
20590         ;
20591       else
20592         break;
20593     }
20594
20595   if (sw_if_index == ~0)
20596     {
20597       errmsg ("missing sw_if_index");
20598       return -99;
20599     }
20600
20601   /* Construct the API message */
20602   M (DELETE_SUBIF, mp);
20603   mp->sw_if_index = ntohl (sw_if_index);
20604
20605   S (mp);
20606   W (ret);
20607   return ret;
20608 }
20609
20610 #define foreach_pbb_vtr_op      \
20611 _("disable",  L2_VTR_DISABLED)  \
20612 _("pop",  L2_VTR_POP_2)         \
20613 _("push",  L2_VTR_PUSH_2)
20614
20615 static int
20616 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20617 {
20618   unformat_input_t *i = vam->input;
20619   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20620   u32 sw_if_index = ~0, vtr_op = ~0;
20621   u16 outer_tag = ~0;
20622   u8 dmac[6], smac[6];
20623   u8 dmac_set = 0, smac_set = 0;
20624   u16 vlanid = 0;
20625   u32 sid = ~0;
20626   u32 tmp;
20627   int ret;
20628
20629   /* Shut up coverity */
20630   clib_memset (dmac, 0, sizeof (dmac));
20631   clib_memset (smac, 0, sizeof (smac));
20632
20633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20634     {
20635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20636         ;
20637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20638         ;
20639       else if (unformat (i, "vtr_op %d", &vtr_op))
20640         ;
20641 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20642       foreach_pbb_vtr_op
20643 #undef _
20644         else if (unformat (i, "translate_pbb_stag"))
20645         {
20646           if (unformat (i, "%d", &tmp))
20647             {
20648               vtr_op = L2_VTR_TRANSLATE_2_1;
20649               outer_tag = tmp;
20650             }
20651           else
20652             {
20653               errmsg
20654                 ("translate_pbb_stag operation requires outer tag definition");
20655               return -99;
20656             }
20657         }
20658       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20659         dmac_set++;
20660       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20661         smac_set++;
20662       else if (unformat (i, "sid %d", &sid))
20663         ;
20664       else if (unformat (i, "vlanid %d", &tmp))
20665         vlanid = tmp;
20666       else
20667         {
20668           clib_warning ("parse error '%U'", format_unformat_error, i);
20669           return -99;
20670         }
20671     }
20672
20673   if ((sw_if_index == ~0) || (vtr_op == ~0))
20674     {
20675       errmsg ("missing sw_if_index or vtr operation");
20676       return -99;
20677     }
20678   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20679       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20680     {
20681       errmsg
20682         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20683       return -99;
20684     }
20685
20686   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20687   mp->sw_if_index = ntohl (sw_if_index);
20688   mp->vtr_op = ntohl (vtr_op);
20689   mp->outer_tag = ntohs (outer_tag);
20690   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20691   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20692   mp->b_vlanid = ntohs (vlanid);
20693   mp->i_sid = ntohl (sid);
20694
20695   S (mp);
20696   W (ret);
20697   return ret;
20698 }
20699
20700 static int
20701 api_flow_classify_set_interface (vat_main_t * vam)
20702 {
20703   unformat_input_t *i = vam->input;
20704   vl_api_flow_classify_set_interface_t *mp;
20705   u32 sw_if_index;
20706   int sw_if_index_set;
20707   u32 ip4_table_index = ~0;
20708   u32 ip6_table_index = ~0;
20709   u8 is_add = 1;
20710   int ret;
20711
20712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20713     {
20714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20715         sw_if_index_set = 1;
20716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20717         sw_if_index_set = 1;
20718       else if (unformat (i, "del"))
20719         is_add = 0;
20720       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20721         ;
20722       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20723         ;
20724       else
20725         {
20726           clib_warning ("parse error '%U'", format_unformat_error, i);
20727           return -99;
20728         }
20729     }
20730
20731   if (sw_if_index_set == 0)
20732     {
20733       errmsg ("missing interface name or sw_if_index");
20734       return -99;
20735     }
20736
20737   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20738
20739   mp->sw_if_index = ntohl (sw_if_index);
20740   mp->ip4_table_index = ntohl (ip4_table_index);
20741   mp->ip6_table_index = ntohl (ip6_table_index);
20742   mp->is_add = is_add;
20743
20744   S (mp);
20745   W (ret);
20746   return ret;
20747 }
20748
20749 static int
20750 api_flow_classify_dump (vat_main_t * vam)
20751 {
20752   unformat_input_t *i = vam->input;
20753   vl_api_flow_classify_dump_t *mp;
20754   vl_api_control_ping_t *mp_ping;
20755   u8 type = FLOW_CLASSIFY_N_TABLES;
20756   int ret;
20757
20758   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20759     ;
20760   else
20761     {
20762       errmsg ("classify table type must be specified");
20763       return -99;
20764     }
20765
20766   if (!vam->json_output)
20767     {
20768       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20769     }
20770
20771   M (FLOW_CLASSIFY_DUMP, mp);
20772   mp->type = type;
20773   /* send it... */
20774   S (mp);
20775
20776   /* Use a control ping for synchronization */
20777   MPING (CONTROL_PING, mp_ping);
20778   S (mp_ping);
20779
20780   /* Wait for a reply... */
20781   W (ret);
20782   return ret;
20783 }
20784
20785 static int
20786 api_feature_enable_disable (vat_main_t * vam)
20787 {
20788   unformat_input_t *i = vam->input;
20789   vl_api_feature_enable_disable_t *mp;
20790   u8 *arc_name = 0;
20791   u8 *feature_name = 0;
20792   u32 sw_if_index = ~0;
20793   u8 enable = 1;
20794   int ret;
20795
20796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20797     {
20798       if (unformat (i, "arc_name %s", &arc_name))
20799         ;
20800       else if (unformat (i, "feature_name %s", &feature_name))
20801         ;
20802       else
20803         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20804         ;
20805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20806         ;
20807       else if (unformat (i, "disable"))
20808         enable = 0;
20809       else
20810         break;
20811     }
20812
20813   if (arc_name == 0)
20814     {
20815       errmsg ("missing arc name");
20816       return -99;
20817     }
20818   if (vec_len (arc_name) > 63)
20819     {
20820       errmsg ("arc name too long");
20821     }
20822
20823   if (feature_name == 0)
20824     {
20825       errmsg ("missing feature name");
20826       return -99;
20827     }
20828   if (vec_len (feature_name) > 63)
20829     {
20830       errmsg ("feature name too long");
20831     }
20832
20833   if (sw_if_index == ~0)
20834     {
20835       errmsg ("missing interface name or sw_if_index");
20836       return -99;
20837     }
20838
20839   /* Construct the API message */
20840   M (FEATURE_ENABLE_DISABLE, mp);
20841   mp->sw_if_index = ntohl (sw_if_index);
20842   mp->enable = enable;
20843   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20844   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20845   vec_free (arc_name);
20846   vec_free (feature_name);
20847
20848   S (mp);
20849   W (ret);
20850   return ret;
20851 }
20852
20853 static int
20854 api_sw_interface_tag_add_del (vat_main_t * vam)
20855 {
20856   unformat_input_t *i = vam->input;
20857   vl_api_sw_interface_tag_add_del_t *mp;
20858   u32 sw_if_index = ~0;
20859   u8 *tag = 0;
20860   u8 enable = 1;
20861   int ret;
20862
20863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20864     {
20865       if (unformat (i, "tag %s", &tag))
20866         ;
20867       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20868         ;
20869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20870         ;
20871       else if (unformat (i, "del"))
20872         enable = 0;
20873       else
20874         break;
20875     }
20876
20877   if (sw_if_index == ~0)
20878     {
20879       errmsg ("missing interface name or sw_if_index");
20880       return -99;
20881     }
20882
20883   if (enable && (tag == 0))
20884     {
20885       errmsg ("no tag specified");
20886       return -99;
20887     }
20888
20889   /* Construct the API message */
20890   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20891   mp->sw_if_index = ntohl (sw_if_index);
20892   mp->is_add = enable;
20893   if (enable)
20894     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20895   vec_free (tag);
20896
20897   S (mp);
20898   W (ret);
20899   return ret;
20900 }
20901
20902 static void vl_api_l2_xconnect_details_t_handler
20903   (vl_api_l2_xconnect_details_t * mp)
20904 {
20905   vat_main_t *vam = &vat_main;
20906
20907   print (vam->ofp, "%15d%15d",
20908          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20909 }
20910
20911 static void vl_api_l2_xconnect_details_t_handler_json
20912   (vl_api_l2_xconnect_details_t * mp)
20913 {
20914   vat_main_t *vam = &vat_main;
20915   vat_json_node_t *node = NULL;
20916
20917   if (VAT_JSON_ARRAY != vam->json_tree.type)
20918     {
20919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20920       vat_json_init_array (&vam->json_tree);
20921     }
20922   node = vat_json_array_add (&vam->json_tree);
20923
20924   vat_json_init_object (node);
20925   vat_json_object_add_uint (node, "rx_sw_if_index",
20926                             ntohl (mp->rx_sw_if_index));
20927   vat_json_object_add_uint (node, "tx_sw_if_index",
20928                             ntohl (mp->tx_sw_if_index));
20929 }
20930
20931 static int
20932 api_l2_xconnect_dump (vat_main_t * vam)
20933 {
20934   vl_api_l2_xconnect_dump_t *mp;
20935   vl_api_control_ping_t *mp_ping;
20936   int ret;
20937
20938   if (!vam->json_output)
20939     {
20940       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20941     }
20942
20943   M (L2_XCONNECT_DUMP, mp);
20944
20945   S (mp);
20946
20947   /* Use a control ping for synchronization */
20948   MPING (CONTROL_PING, mp_ping);
20949   S (mp_ping);
20950
20951   W (ret);
20952   return ret;
20953 }
20954
20955 static int
20956 api_hw_interface_set_mtu (vat_main_t * vam)
20957 {
20958   unformat_input_t *i = vam->input;
20959   vl_api_hw_interface_set_mtu_t *mp;
20960   u32 sw_if_index = ~0;
20961   u32 mtu = 0;
20962   int ret;
20963
20964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20965     {
20966       if (unformat (i, "mtu %d", &mtu))
20967         ;
20968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20969         ;
20970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20971         ;
20972       else
20973         break;
20974     }
20975
20976   if (sw_if_index == ~0)
20977     {
20978       errmsg ("missing interface name or sw_if_index");
20979       return -99;
20980     }
20981
20982   if (mtu == 0)
20983     {
20984       errmsg ("no mtu specified");
20985       return -99;
20986     }
20987
20988   /* Construct the API message */
20989   M (HW_INTERFACE_SET_MTU, mp);
20990   mp->sw_if_index = ntohl (sw_if_index);
20991   mp->mtu = ntohs ((u16) mtu);
20992
20993   S (mp);
20994   W (ret);
20995   return ret;
20996 }
20997
20998 static int
20999 api_p2p_ethernet_add (vat_main_t * vam)
21000 {
21001   unformat_input_t *i = vam->input;
21002   vl_api_p2p_ethernet_add_t *mp;
21003   u32 parent_if_index = ~0;
21004   u32 sub_id = ~0;
21005   u8 remote_mac[6];
21006   u8 mac_set = 0;
21007   int ret;
21008
21009   clib_memset (remote_mac, 0, sizeof (remote_mac));
21010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21011     {
21012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21013         ;
21014       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21015         ;
21016       else
21017         if (unformat
21018             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21019         mac_set++;
21020       else if (unformat (i, "sub_id %d", &sub_id))
21021         ;
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   if (sub_id == ~0)
21040     {
21041       errmsg ("missing sub-interface id");
21042       return -99;
21043     }
21044
21045   M (P2P_ETHERNET_ADD, mp);
21046   mp->parent_if_index = ntohl (parent_if_index);
21047   mp->subif_id = ntohl (sub_id);
21048   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21049
21050   S (mp);
21051   W (ret);
21052   return ret;
21053 }
21054
21055 static int
21056 api_p2p_ethernet_del (vat_main_t * vam)
21057 {
21058   unformat_input_t *i = vam->input;
21059   vl_api_p2p_ethernet_del_t *mp;
21060   u32 parent_if_index = ~0;
21061   u8 remote_mac[6];
21062   u8 mac_set = 0;
21063   int ret;
21064
21065   clib_memset (remote_mac, 0, sizeof (remote_mac));
21066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21067     {
21068       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21069         ;
21070       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21071         ;
21072       else
21073         if (unformat
21074             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21075         mac_set++;
21076       else
21077         {
21078           clib_warning ("parse error '%U'", format_unformat_error, i);
21079           return -99;
21080         }
21081     }
21082
21083   if (parent_if_index == ~0)
21084     {
21085       errmsg ("missing interface name or sw_if_index");
21086       return -99;
21087     }
21088   if (mac_set == 0)
21089     {
21090       errmsg ("missing remote mac address");
21091       return -99;
21092     }
21093
21094   M (P2P_ETHERNET_DEL, mp);
21095   mp->parent_if_index = ntohl (parent_if_index);
21096   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21097
21098   S (mp);
21099   W (ret);
21100   return ret;
21101 }
21102
21103 static int
21104 api_lldp_config (vat_main_t * vam)
21105 {
21106   unformat_input_t *i = vam->input;
21107   vl_api_lldp_config_t *mp;
21108   int tx_hold = 0;
21109   int tx_interval = 0;
21110   u8 *sys_name = NULL;
21111   int ret;
21112
21113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21114     {
21115       if (unformat (i, "system-name %s", &sys_name))
21116         ;
21117       else if (unformat (i, "tx-hold %d", &tx_hold))
21118         ;
21119       else if (unformat (i, "tx-interval %d", &tx_interval))
21120         ;
21121       else
21122         {
21123           clib_warning ("parse error '%U'", format_unformat_error, i);
21124           return -99;
21125         }
21126     }
21127
21128   vec_add1 (sys_name, 0);
21129
21130   M (LLDP_CONFIG, mp);
21131   mp->tx_hold = htonl (tx_hold);
21132   mp->tx_interval = htonl (tx_interval);
21133   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21134   vec_free (sys_name);
21135
21136   S (mp);
21137   W (ret);
21138   return ret;
21139 }
21140
21141 static int
21142 api_sw_interface_set_lldp (vat_main_t * vam)
21143 {
21144   unformat_input_t *i = vam->input;
21145   vl_api_sw_interface_set_lldp_t *mp;
21146   u32 sw_if_index = ~0;
21147   u32 enable = 1;
21148   u8 *port_desc = NULL, *mgmt_oid = NULL;
21149   ip4_address_t ip4_addr;
21150   ip6_address_t ip6_addr;
21151   int ret;
21152
21153   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21154   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21155
21156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21157     {
21158       if (unformat (i, "disable"))
21159         enable = 0;
21160       else
21161         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21162         ;
21163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21164         ;
21165       else if (unformat (i, "port-desc %s", &port_desc))
21166         ;
21167       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21168         ;
21169       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21170         ;
21171       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21172         ;
21173       else
21174         break;
21175     }
21176
21177   if (sw_if_index == ~0)
21178     {
21179       errmsg ("missing interface name or sw_if_index");
21180       return -99;
21181     }
21182
21183   /* Construct the API message */
21184   vec_add1 (port_desc, 0);
21185   vec_add1 (mgmt_oid, 0);
21186   M (SW_INTERFACE_SET_LLDP, mp);
21187   mp->sw_if_index = ntohl (sw_if_index);
21188   mp->enable = enable;
21189   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21190   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21191   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21192   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21193   vec_free (port_desc);
21194   vec_free (mgmt_oid);
21195
21196   S (mp);
21197   W (ret);
21198   return ret;
21199 }
21200
21201 static int
21202 api_tcp_configure_src_addresses (vat_main_t * vam)
21203 {
21204   vl_api_tcp_configure_src_addresses_t *mp;
21205   unformat_input_t *i = vam->input;
21206   ip4_address_t v4first, v4last;
21207   ip6_address_t v6first, v6last;
21208   u8 range_set = 0;
21209   u32 vrf_id = 0;
21210   int ret;
21211
21212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21213     {
21214       if (unformat (i, "%U - %U",
21215                     unformat_ip4_address, &v4first,
21216                     unformat_ip4_address, &v4last))
21217         {
21218           if (range_set)
21219             {
21220               errmsg ("one range per message (range already set)");
21221               return -99;
21222             }
21223           range_set = 1;
21224         }
21225       else if (unformat (i, "%U - %U",
21226                          unformat_ip6_address, &v6first,
21227                          unformat_ip6_address, &v6last))
21228         {
21229           if (range_set)
21230             {
21231               errmsg ("one range per message (range already set)");
21232               return -99;
21233             }
21234           range_set = 2;
21235         }
21236       else if (unformat (i, "vrf %d", &vrf_id))
21237         ;
21238       else
21239         break;
21240     }
21241
21242   if (range_set == 0)
21243     {
21244       errmsg ("address range not set");
21245       return -99;
21246     }
21247
21248   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21249   mp->vrf_id = ntohl (vrf_id);
21250   /* ipv6? */
21251   if (range_set == 2)
21252     {
21253       mp->is_ipv6 = 1;
21254       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21255       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21256     }
21257   else
21258     {
21259       mp->is_ipv6 = 0;
21260       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21261       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21262     }
21263   S (mp);
21264   W (ret);
21265   return ret;
21266 }
21267
21268 static void vl_api_app_namespace_add_del_reply_t_handler
21269   (vl_api_app_namespace_add_del_reply_t * mp)
21270 {
21271   vat_main_t *vam = &vat_main;
21272   i32 retval = ntohl (mp->retval);
21273   if (vam->async_mode)
21274     {
21275       vam->async_errors += (retval < 0);
21276     }
21277   else
21278     {
21279       vam->retval = retval;
21280       if (retval == 0)
21281         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21282       vam->result_ready = 1;
21283     }
21284 }
21285
21286 static void vl_api_app_namespace_add_del_reply_t_handler_json
21287   (vl_api_app_namespace_add_del_reply_t * mp)
21288 {
21289   vat_main_t *vam = &vat_main;
21290   vat_json_node_t node;
21291
21292   vat_json_init_object (&node);
21293   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21294   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21295
21296   vat_json_print (vam->ofp, &node);
21297   vat_json_free (&node);
21298
21299   vam->retval = ntohl (mp->retval);
21300   vam->result_ready = 1;
21301 }
21302
21303 static int
21304 api_app_namespace_add_del (vat_main_t * vam)
21305 {
21306   vl_api_app_namespace_add_del_t *mp;
21307   unformat_input_t *i = vam->input;
21308   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21309   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21310   u64 secret;
21311   int ret;
21312
21313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21314     {
21315       if (unformat (i, "id %_%v%_", &ns_id))
21316         ;
21317       else if (unformat (i, "secret %lu", &secret))
21318         secret_set = 1;
21319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21320         sw_if_index_set = 1;
21321       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21322         ;
21323       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21324         ;
21325       else
21326         break;
21327     }
21328   if (!ns_id || !secret_set || !sw_if_index_set)
21329     {
21330       errmsg ("namespace id, secret and sw_if_index must be set");
21331       return -99;
21332     }
21333   if (vec_len (ns_id) > 64)
21334     {
21335       errmsg ("namespace id too long");
21336       return -99;
21337     }
21338   M (APP_NAMESPACE_ADD_DEL, mp);
21339
21340   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21341   mp->namespace_id_len = vec_len (ns_id);
21342   mp->secret = clib_host_to_net_u64 (secret);
21343   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21344   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21345   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21346   vec_free (ns_id);
21347   S (mp);
21348   W (ret);
21349   return ret;
21350 }
21351
21352 static int
21353 api_sock_init_shm (vat_main_t * vam)
21354 {
21355 #if VPP_API_TEST_BUILTIN == 0
21356   unformat_input_t *i = vam->input;
21357   vl_api_shm_elem_config_t *config = 0;
21358   u64 size = 64 << 20;
21359   int rv;
21360
21361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21362     {
21363       if (unformat (i, "size %U", unformat_memory_size, &size))
21364         ;
21365       else
21366         break;
21367     }
21368
21369   /*
21370    * Canned custom ring allocator config.
21371    * Should probably parse all of this
21372    */
21373   vec_validate (config, 6);
21374   config[0].type = VL_API_VLIB_RING;
21375   config[0].size = 256;
21376   config[0].count = 32;
21377
21378   config[1].type = VL_API_VLIB_RING;
21379   config[1].size = 1024;
21380   config[1].count = 16;
21381
21382   config[2].type = VL_API_VLIB_RING;
21383   config[2].size = 4096;
21384   config[2].count = 2;
21385
21386   config[3].type = VL_API_CLIENT_RING;
21387   config[3].size = 256;
21388   config[3].count = 32;
21389
21390   config[4].type = VL_API_CLIENT_RING;
21391   config[4].size = 1024;
21392   config[4].count = 16;
21393
21394   config[5].type = VL_API_CLIENT_RING;
21395   config[5].size = 4096;
21396   config[5].count = 2;
21397
21398   config[6].type = VL_API_QUEUE;
21399   config[6].count = 128;
21400   config[6].size = sizeof (uword);
21401
21402   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21403   if (!rv)
21404     vam->client_index_invalid = 1;
21405   return rv;
21406 #else
21407   return -99;
21408 #endif
21409 }
21410
21411 static int
21412 api_dns_enable_disable (vat_main_t * vam)
21413 {
21414   unformat_input_t *line_input = vam->input;
21415   vl_api_dns_enable_disable_t *mp;
21416   u8 enable_disable = 1;
21417   int ret;
21418
21419   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21420     {
21421       if (unformat (line_input, "disable"))
21422         enable_disable = 0;
21423       if (unformat (line_input, "enable"))
21424         enable_disable = 1;
21425       else
21426         break;
21427     }
21428
21429   /* Construct the API message */
21430   M (DNS_ENABLE_DISABLE, mp);
21431   mp->enable = enable_disable;
21432
21433   /* send it... */
21434   S (mp);
21435   /* Wait for the reply */
21436   W (ret);
21437   return ret;
21438 }
21439
21440 static int
21441 api_dns_resolve_name (vat_main_t * vam)
21442 {
21443   unformat_input_t *line_input = vam->input;
21444   vl_api_dns_resolve_name_t *mp;
21445   u8 *name = 0;
21446   int ret;
21447
21448   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21449     {
21450       if (unformat (line_input, "%s", &name))
21451         ;
21452       else
21453         break;
21454     }
21455
21456   if (vec_len (name) > 127)
21457     {
21458       errmsg ("name too long");
21459       return -99;
21460     }
21461
21462   /* Construct the API message */
21463   M (DNS_RESOLVE_NAME, mp);
21464   memcpy (mp->name, name, vec_len (name));
21465   vec_free (name);
21466
21467   /* send it... */
21468   S (mp);
21469   /* Wait for the reply */
21470   W (ret);
21471   return ret;
21472 }
21473
21474 static int
21475 api_dns_resolve_ip (vat_main_t * vam)
21476 {
21477   unformat_input_t *line_input = vam->input;
21478   vl_api_dns_resolve_ip_t *mp;
21479   int is_ip6 = -1;
21480   ip4_address_t addr4;
21481   ip6_address_t addr6;
21482   int ret;
21483
21484   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21485     {
21486       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21487         is_ip6 = 1;
21488       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21489         is_ip6 = 0;
21490       else
21491         break;
21492     }
21493
21494   if (is_ip6 == -1)
21495     {
21496       errmsg ("missing address");
21497       return -99;
21498     }
21499
21500   /* Construct the API message */
21501   M (DNS_RESOLVE_IP, mp);
21502   mp->is_ip6 = is_ip6;
21503   if (is_ip6)
21504     memcpy (mp->address, &addr6, sizeof (addr6));
21505   else
21506     memcpy (mp->address, &addr4, sizeof (addr4));
21507
21508   /* send it... */
21509   S (mp);
21510   /* Wait for the reply */
21511   W (ret);
21512   return ret;
21513 }
21514
21515 static int
21516 api_dns_name_server_add_del (vat_main_t * vam)
21517 {
21518   unformat_input_t *i = vam->input;
21519   vl_api_dns_name_server_add_del_t *mp;
21520   u8 is_add = 1;
21521   ip6_address_t ip6_server;
21522   ip4_address_t ip4_server;
21523   int ip6_set = 0;
21524   int ip4_set = 0;
21525   int ret = 0;
21526
21527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21528     {
21529       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21530         ip6_set = 1;
21531       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21532         ip4_set = 1;
21533       else if (unformat (i, "del"))
21534         is_add = 0;
21535       else
21536         {
21537           clib_warning ("parse error '%U'", format_unformat_error, i);
21538           return -99;
21539         }
21540     }
21541
21542   if (ip4_set && ip6_set)
21543     {
21544       errmsg ("Only one server address allowed per message");
21545       return -99;
21546     }
21547   if ((ip4_set + ip6_set) == 0)
21548     {
21549       errmsg ("Server address required");
21550       return -99;
21551     }
21552
21553   /* Construct the API message */
21554   M (DNS_NAME_SERVER_ADD_DEL, mp);
21555
21556   if (ip6_set)
21557     {
21558       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21559       mp->is_ip6 = 1;
21560     }
21561   else
21562     {
21563       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21564       mp->is_ip6 = 0;
21565     }
21566
21567   mp->is_add = is_add;
21568
21569   /* send it... */
21570   S (mp);
21571
21572   /* Wait for a reply, return good/bad news  */
21573   W (ret);
21574   return ret;
21575 }
21576
21577 static void
21578 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21579 {
21580   vat_main_t *vam = &vat_main;
21581
21582   if (mp->is_ip4)
21583     {
21584       print (vam->ofp,
21585              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21586              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21587              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21588              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21589              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21590              clib_net_to_host_u32 (mp->action_index), mp->tag);
21591     }
21592   else
21593     {
21594       print (vam->ofp,
21595              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21596              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21597              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21598              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21599              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21600              clib_net_to_host_u32 (mp->action_index), mp->tag);
21601     }
21602 }
21603
21604 static void
21605 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21606                                              mp)
21607 {
21608   vat_main_t *vam = &vat_main;
21609   vat_json_node_t *node = NULL;
21610   struct in6_addr ip6;
21611   struct in_addr ip4;
21612
21613   if (VAT_JSON_ARRAY != vam->json_tree.type)
21614     {
21615       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21616       vat_json_init_array (&vam->json_tree);
21617     }
21618   node = vat_json_array_add (&vam->json_tree);
21619   vat_json_init_object (node);
21620
21621   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21622   vat_json_object_add_uint (node, "appns_index",
21623                             clib_net_to_host_u32 (mp->appns_index));
21624   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21625   vat_json_object_add_uint (node, "scope", mp->scope);
21626   vat_json_object_add_uint (node, "action_index",
21627                             clib_net_to_host_u32 (mp->action_index));
21628   vat_json_object_add_uint (node, "lcl_port",
21629                             clib_net_to_host_u16 (mp->lcl_port));
21630   vat_json_object_add_uint (node, "rmt_port",
21631                             clib_net_to_host_u16 (mp->rmt_port));
21632   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21633   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21634   vat_json_object_add_string_copy (node, "tag", mp->tag);
21635   if (mp->is_ip4)
21636     {
21637       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21638       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21639       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21640       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21641     }
21642   else
21643     {
21644       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21645       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21646       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21647       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21648     }
21649 }
21650
21651 static int
21652 api_session_rule_add_del (vat_main_t * vam)
21653 {
21654   vl_api_session_rule_add_del_t *mp;
21655   unformat_input_t *i = vam->input;
21656   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21657   u32 appns_index = 0, scope = 0;
21658   ip4_address_t lcl_ip4, rmt_ip4;
21659   ip6_address_t lcl_ip6, rmt_ip6;
21660   u8 is_ip4 = 1, conn_set = 0;
21661   u8 is_add = 1, *tag = 0;
21662   int ret;
21663
21664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21665     {
21666       if (unformat (i, "del"))
21667         is_add = 0;
21668       else if (unformat (i, "add"))
21669         ;
21670       else if (unformat (i, "proto tcp"))
21671         proto = 0;
21672       else if (unformat (i, "proto udp"))
21673         proto = 1;
21674       else if (unformat (i, "appns %d", &appns_index))
21675         ;
21676       else if (unformat (i, "scope %d", &scope))
21677         ;
21678       else if (unformat (i, "tag %_%v%_", &tag))
21679         ;
21680       else
21681         if (unformat
21682             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21683              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21684              &rmt_port))
21685         {
21686           is_ip4 = 1;
21687           conn_set = 1;
21688         }
21689       else
21690         if (unformat
21691             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21692              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21693              &rmt_port))
21694         {
21695           is_ip4 = 0;
21696           conn_set = 1;
21697         }
21698       else if (unformat (i, "action %d", &action))
21699         ;
21700       else
21701         break;
21702     }
21703   if (proto == ~0 || !conn_set || action == ~0)
21704     {
21705       errmsg ("transport proto, connection and action must be set");
21706       return -99;
21707     }
21708
21709   if (scope > 3)
21710     {
21711       errmsg ("scope should be 0-3");
21712       return -99;
21713     }
21714
21715   M (SESSION_RULE_ADD_DEL, mp);
21716
21717   mp->is_ip4 = is_ip4;
21718   mp->transport_proto = proto;
21719   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21720   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21721   mp->lcl_plen = lcl_plen;
21722   mp->rmt_plen = rmt_plen;
21723   mp->action_index = clib_host_to_net_u32 (action);
21724   mp->appns_index = clib_host_to_net_u32 (appns_index);
21725   mp->scope = scope;
21726   mp->is_add = is_add;
21727   if (is_ip4)
21728     {
21729       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21730       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21731     }
21732   else
21733     {
21734       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21735       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21736     }
21737   if (tag)
21738     {
21739       clib_memcpy (mp->tag, tag, vec_len (tag));
21740       vec_free (tag);
21741     }
21742
21743   S (mp);
21744   W (ret);
21745   return ret;
21746 }
21747
21748 static int
21749 api_session_rules_dump (vat_main_t * vam)
21750 {
21751   vl_api_session_rules_dump_t *mp;
21752   vl_api_control_ping_t *mp_ping;
21753   int ret;
21754
21755   if (!vam->json_output)
21756     {
21757       print (vam->ofp, "%=20s", "Session Rules");
21758     }
21759
21760   M (SESSION_RULES_DUMP, mp);
21761   /* send it... */
21762   S (mp);
21763
21764   /* Use a control ping for synchronization */
21765   MPING (CONTROL_PING, mp_ping);
21766   S (mp_ping);
21767
21768   /* Wait for a reply... */
21769   W (ret);
21770   return ret;
21771 }
21772
21773 static int
21774 api_ip_container_proxy_add_del (vat_main_t * vam)
21775 {
21776   vl_api_ip_container_proxy_add_del_t *mp;
21777   unformat_input_t *i = vam->input;
21778   u32 sw_if_index = ~0;
21779   vl_api_prefix_t pfx = { };
21780   u8 is_add = 1;
21781   int ret;
21782
21783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21784     {
21785       if (unformat (i, "del"))
21786         is_add = 0;
21787       else if (unformat (i, "add"))
21788         ;
21789       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21790         ;
21791       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21792         ;
21793       else
21794         break;
21795     }
21796   if (sw_if_index == ~0 || pfx.address_length == 0)
21797     {
21798       errmsg ("address and sw_if_index must be set");
21799       return -99;
21800     }
21801
21802   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21803
21804   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21805   mp->is_add = is_add;
21806   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21807
21808   S (mp);
21809   W (ret);
21810   return ret;
21811 }
21812
21813 static int
21814 api_qos_record_enable_disable (vat_main_t * vam)
21815 {
21816   unformat_input_t *i = vam->input;
21817   vl_api_qos_record_enable_disable_t *mp;
21818   u32 sw_if_index, qs = 0xff;
21819   u8 sw_if_index_set = 0;
21820   u8 enable = 1;
21821   int ret;
21822
21823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21824     {
21825       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21826         sw_if_index_set = 1;
21827       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21828         sw_if_index_set = 1;
21829       else if (unformat (i, "%U", unformat_qos_source, &qs))
21830         ;
21831       else if (unformat (i, "disable"))
21832         enable = 0;
21833       else
21834         {
21835           clib_warning ("parse error '%U'", format_unformat_error, i);
21836           return -99;
21837         }
21838     }
21839
21840   if (sw_if_index_set == 0)
21841     {
21842       errmsg ("missing interface name or sw_if_index");
21843       return -99;
21844     }
21845   if (qs == 0xff)
21846     {
21847       errmsg ("input location must be specified");
21848       return -99;
21849     }
21850
21851   M (QOS_RECORD_ENABLE_DISABLE, mp);
21852
21853   mp->sw_if_index = ntohl (sw_if_index);
21854   mp->input_source = qs;
21855   mp->enable = enable;
21856
21857   S (mp);
21858   W (ret);
21859   return ret;
21860 }
21861
21862
21863 static int
21864 q_or_quit (vat_main_t * vam)
21865 {
21866 #if VPP_API_TEST_BUILTIN == 0
21867   longjmp (vam->jump_buf, 1);
21868 #endif
21869   return 0;                     /* not so much */
21870 }
21871
21872 static int
21873 q (vat_main_t * vam)
21874 {
21875   return q_or_quit (vam);
21876 }
21877
21878 static int
21879 quit (vat_main_t * vam)
21880 {
21881   return q_or_quit (vam);
21882 }
21883
21884 static int
21885 comment (vat_main_t * vam)
21886 {
21887   return 0;
21888 }
21889
21890 static int
21891 statseg (vat_main_t * vam)
21892 {
21893   ssvm_private_t *ssvmp = &vam->stat_segment;
21894   ssvm_shared_header_t *shared_header = ssvmp->sh;
21895   vlib_counter_t **counters;
21896   u64 thread0_index1_packets;
21897   u64 thread0_index1_bytes;
21898   f64 vector_rate, input_rate;
21899   uword *p;
21900
21901   uword *counter_vector_by_name;
21902   if (vam->stat_segment_lockp == 0)
21903     {
21904       errmsg ("Stat segment not mapped...");
21905       return -99;
21906     }
21907
21908   /* look up "/if/rx for sw_if_index 1 as a test */
21909
21910   clib_spinlock_lock (vam->stat_segment_lockp);
21911
21912   counter_vector_by_name = (uword *) shared_header->opaque[1];
21913
21914   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21915   if (p == 0)
21916     {
21917       clib_spinlock_unlock (vam->stat_segment_lockp);
21918       errmsg ("/if/tx not found?");
21919       return -99;
21920     }
21921
21922   /* Fish per-thread vector of combined counters from shared memory */
21923   counters = (vlib_counter_t **) p[0];
21924
21925   if (vec_len (counters[0]) < 2)
21926     {
21927       clib_spinlock_unlock (vam->stat_segment_lockp);
21928       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21929       return -99;
21930     }
21931
21932   /* Read thread 0 sw_if_index 1 counter */
21933   thread0_index1_packets = counters[0][1].packets;
21934   thread0_index1_bytes = counters[0][1].bytes;
21935
21936   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21937   if (p == 0)
21938     {
21939       clib_spinlock_unlock (vam->stat_segment_lockp);
21940       errmsg ("vector_rate not found?");
21941       return -99;
21942     }
21943
21944   vector_rate = *(f64 *) (p[0]);
21945   p = hash_get_mem (counter_vector_by_name, "input_rate");
21946   if (p == 0)
21947     {
21948       clib_spinlock_unlock (vam->stat_segment_lockp);
21949       errmsg ("input_rate not found?");
21950       return -99;
21951     }
21952   input_rate = *(f64 *) (p[0]);
21953
21954   clib_spinlock_unlock (vam->stat_segment_lockp);
21955
21956   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21957          vector_rate, input_rate);
21958   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21959          thread0_index1_packets, thread0_index1_bytes);
21960
21961   return 0;
21962 }
21963
21964 static int
21965 cmd_cmp (void *a1, void *a2)
21966 {
21967   u8 **c1 = a1;
21968   u8 **c2 = a2;
21969
21970   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21971 }
21972
21973 static int
21974 help (vat_main_t * vam)
21975 {
21976   u8 **cmds = 0;
21977   u8 *name = 0;
21978   hash_pair_t *p;
21979   unformat_input_t *i = vam->input;
21980   int j;
21981
21982   if (unformat (i, "%s", &name))
21983     {
21984       uword *hs;
21985
21986       vec_add1 (name, 0);
21987
21988       hs = hash_get_mem (vam->help_by_name, name);
21989       if (hs)
21990         print (vam->ofp, "usage: %s %s", name, hs[0]);
21991       else
21992         print (vam->ofp, "No such msg / command '%s'", name);
21993       vec_free (name);
21994       return 0;
21995     }
21996
21997   print (vam->ofp, "Help is available for the following:");
21998
21999     /* *INDENT-OFF* */
22000     hash_foreach_pair (p, vam->function_by_name,
22001     ({
22002       vec_add1 (cmds, (u8 *)(p->key));
22003     }));
22004     /* *INDENT-ON* */
22005
22006   vec_sort_with_function (cmds, cmd_cmp);
22007
22008   for (j = 0; j < vec_len (cmds); j++)
22009     print (vam->ofp, "%s", cmds[j]);
22010
22011   vec_free (cmds);
22012   return 0;
22013 }
22014
22015 static int
22016 set (vat_main_t * vam)
22017 {
22018   u8 *name = 0, *value = 0;
22019   unformat_input_t *i = vam->input;
22020
22021   if (unformat (i, "%s", &name))
22022     {
22023       /* The input buffer is a vector, not a string. */
22024       value = vec_dup (i->buffer);
22025       vec_delete (value, i->index, 0);
22026       /* Almost certainly has a trailing newline */
22027       if (value[vec_len (value) - 1] == '\n')
22028         value[vec_len (value) - 1] = 0;
22029       /* Make sure it's a proper string, one way or the other */
22030       vec_add1 (value, 0);
22031       (void) clib_macro_set_value (&vam->macro_main,
22032                                    (char *) name, (char *) value);
22033     }
22034   else
22035     errmsg ("usage: set <name> <value>");
22036
22037   vec_free (name);
22038   vec_free (value);
22039   return 0;
22040 }
22041
22042 static int
22043 unset (vat_main_t * vam)
22044 {
22045   u8 *name = 0;
22046
22047   if (unformat (vam->input, "%s", &name))
22048     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22049       errmsg ("unset: %s wasn't set", name);
22050   vec_free (name);
22051   return 0;
22052 }
22053
22054 typedef struct
22055 {
22056   u8 *name;
22057   u8 *value;
22058 } macro_sort_t;
22059
22060
22061 static int
22062 macro_sort_cmp (void *a1, void *a2)
22063 {
22064   macro_sort_t *s1 = a1;
22065   macro_sort_t *s2 = a2;
22066
22067   return strcmp ((char *) (s1->name), (char *) (s2->name));
22068 }
22069
22070 static int
22071 dump_macro_table (vat_main_t * vam)
22072 {
22073   macro_sort_t *sort_me = 0, *sm;
22074   int i;
22075   hash_pair_t *p;
22076
22077     /* *INDENT-OFF* */
22078     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22079     ({
22080       vec_add2 (sort_me, sm, 1);
22081       sm->name = (u8 *)(p->key);
22082       sm->value = (u8 *) (p->value[0]);
22083     }));
22084     /* *INDENT-ON* */
22085
22086   vec_sort_with_function (sort_me, macro_sort_cmp);
22087
22088   if (vec_len (sort_me))
22089     print (vam->ofp, "%-15s%s", "Name", "Value");
22090   else
22091     print (vam->ofp, "The macro table is empty...");
22092
22093   for (i = 0; i < vec_len (sort_me); i++)
22094     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22095   return 0;
22096 }
22097
22098 static int
22099 dump_node_table (vat_main_t * vam)
22100 {
22101   int i, j;
22102   vlib_node_t *node, *next_node;
22103
22104   if (vec_len (vam->graph_nodes) == 0)
22105     {
22106       print (vam->ofp, "Node table empty, issue get_node_graph...");
22107       return 0;
22108     }
22109
22110   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22111     {
22112       node = vam->graph_nodes[0][i];
22113       print (vam->ofp, "[%d] %s", i, node->name);
22114       for (j = 0; j < vec_len (node->next_nodes); j++)
22115         {
22116           if (node->next_nodes[j] != ~0)
22117             {
22118               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22119               print (vam->ofp, "  [%d] %s", j, next_node->name);
22120             }
22121         }
22122     }
22123   return 0;
22124 }
22125
22126 static int
22127 value_sort_cmp (void *a1, void *a2)
22128 {
22129   name_sort_t *n1 = a1;
22130   name_sort_t *n2 = a2;
22131
22132   if (n1->value < n2->value)
22133     return -1;
22134   if (n1->value > n2->value)
22135     return 1;
22136   return 0;
22137 }
22138
22139
22140 static int
22141 dump_msg_api_table (vat_main_t * vam)
22142 {
22143   api_main_t *am = &api_main;
22144   name_sort_t *nses = 0, *ns;
22145   hash_pair_t *hp;
22146   int i;
22147
22148   /* *INDENT-OFF* */
22149   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22150   ({
22151     vec_add2 (nses, ns, 1);
22152     ns->name = (u8 *)(hp->key);
22153     ns->value = (u32) hp->value[0];
22154   }));
22155   /* *INDENT-ON* */
22156
22157   vec_sort_with_function (nses, value_sort_cmp);
22158
22159   for (i = 0; i < vec_len (nses); i++)
22160     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22161   vec_free (nses);
22162   return 0;
22163 }
22164
22165 static int
22166 get_msg_id (vat_main_t * vam)
22167 {
22168   u8 *name_and_crc;
22169   u32 message_index;
22170
22171   if (unformat (vam->input, "%s", &name_and_crc))
22172     {
22173       message_index = vl_msg_api_get_msg_index (name_and_crc);
22174       if (message_index == ~0)
22175         {
22176           print (vam->ofp, " '%s' not found", name_and_crc);
22177           return 0;
22178         }
22179       print (vam->ofp, " '%s' has message index %d",
22180              name_and_crc, message_index);
22181       return 0;
22182     }
22183   errmsg ("name_and_crc required...");
22184   return 0;
22185 }
22186
22187 static int
22188 search_node_table (vat_main_t * vam)
22189 {
22190   unformat_input_t *line_input = vam->input;
22191   u8 *node_to_find;
22192   int j;
22193   vlib_node_t *node, *next_node;
22194   uword *p;
22195
22196   if (vam->graph_node_index_by_name == 0)
22197     {
22198       print (vam->ofp, "Node table empty, issue get_node_graph...");
22199       return 0;
22200     }
22201
22202   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22203     {
22204       if (unformat (line_input, "%s", &node_to_find))
22205         {
22206           vec_add1 (node_to_find, 0);
22207           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22208           if (p == 0)
22209             {
22210               print (vam->ofp, "%s not found...", node_to_find);
22211               goto out;
22212             }
22213           node = vam->graph_nodes[0][p[0]];
22214           print (vam->ofp, "[%d] %s", p[0], node->name);
22215           for (j = 0; j < vec_len (node->next_nodes); j++)
22216             {
22217               if (node->next_nodes[j] != ~0)
22218                 {
22219                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22220                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22221                 }
22222             }
22223         }
22224
22225       else
22226         {
22227           clib_warning ("parse error '%U'", format_unformat_error,
22228                         line_input);
22229           return -99;
22230         }
22231
22232     out:
22233       vec_free (node_to_find);
22234
22235     }
22236
22237   return 0;
22238 }
22239
22240
22241 static int
22242 script (vat_main_t * vam)
22243 {
22244 #if (VPP_API_TEST_BUILTIN==0)
22245   u8 *s = 0;
22246   char *save_current_file;
22247   unformat_input_t save_input;
22248   jmp_buf save_jump_buf;
22249   u32 save_line_number;
22250
22251   FILE *new_fp, *save_ifp;
22252
22253   if (unformat (vam->input, "%s", &s))
22254     {
22255       new_fp = fopen ((char *) s, "r");
22256       if (new_fp == 0)
22257         {
22258           errmsg ("Couldn't open script file %s", s);
22259           vec_free (s);
22260           return -99;
22261         }
22262     }
22263   else
22264     {
22265       errmsg ("Missing script name");
22266       return -99;
22267     }
22268
22269   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22270   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22271   save_ifp = vam->ifp;
22272   save_line_number = vam->input_line_number;
22273   save_current_file = (char *) vam->current_file;
22274
22275   vam->input_line_number = 0;
22276   vam->ifp = new_fp;
22277   vam->current_file = s;
22278   do_one_file (vam);
22279
22280   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22281   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22282   vam->ifp = save_ifp;
22283   vam->input_line_number = save_line_number;
22284   vam->current_file = (u8 *) save_current_file;
22285   vec_free (s);
22286
22287   return 0;
22288 #else
22289   clib_warning ("use the exec command...");
22290   return -99;
22291 #endif
22292 }
22293
22294 static int
22295 echo (vat_main_t * vam)
22296 {
22297   print (vam->ofp, "%v", vam->input->buffer);
22298   return 0;
22299 }
22300
22301 /* List of API message constructors, CLI names map to api_xxx */
22302 #define foreach_vpe_api_msg                                             \
22303 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22304 _(sw_interface_dump,"")                                                 \
22305 _(sw_interface_set_flags,                                               \
22306   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22307 _(sw_interface_add_del_address,                                         \
22308   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22309 _(sw_interface_set_rx_mode,                                             \
22310   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22311 _(sw_interface_set_rx_placement,                                        \
22312   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22313 _(sw_interface_rx_placement_dump,                                       \
22314   "[<intfc> | sw_if_index <id>]")                                         \
22315 _(sw_interface_set_table,                                               \
22316   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22317 _(sw_interface_set_mpls_enable,                                         \
22318   "<intfc> | sw_if_index [disable | dis]")                              \
22319 _(sw_interface_set_vpath,                                               \
22320   "<intfc> | sw_if_index <id> enable | disable")                        \
22321 _(sw_interface_set_vxlan_bypass,                                        \
22322   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22323 _(sw_interface_set_geneve_bypass,                                       \
22324   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22325 _(sw_interface_set_l2_xconnect,                                         \
22326   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22327   "enable | disable")                                                   \
22328 _(sw_interface_set_l2_bridge,                                           \
22329   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22330   "[shg <split-horizon-group>] [bvi]\n"                                 \
22331   "enable | disable")                                                   \
22332 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22333 _(bridge_domain_add_del,                                                \
22334   "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") \
22335 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22336 _(l2fib_add_del,                                                        \
22337   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22338 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22339 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22340 _(l2_flags,                                                             \
22341   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22342 _(bridge_flags,                                                         \
22343   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22344 _(tap_create_v2,                                                        \
22345   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22346 _(tap_delete_v2,                                                        \
22347   "<vpp-if-name> | sw_if_index <id>")                                   \
22348 _(sw_interface_tap_v2_dump, "")                                         \
22349 _(virtio_pci_create,                                                    \
22350   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22351 _(virtio_pci_delete,                                                    \
22352   "<vpp-if-name> | sw_if_index <id>")                                   \
22353 _(sw_interface_virtio_pci_dump, "")                                     \
22354 _(bond_create,                                                          \
22355   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22356   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22357   "[id <if-id>]")                                                       \
22358 _(bond_delete,                                                          \
22359   "<vpp-if-name> | sw_if_index <id>")                                   \
22360 _(bond_enslave,                                                         \
22361   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22362 _(bond_detach_slave,                                                    \
22363   "sw_if_index <n>")                                                    \
22364 _(sw_interface_bond_dump, "")                                           \
22365 _(sw_interface_slave_dump,                                              \
22366   "<vpp-if-name> | sw_if_index <id>")                                   \
22367 _(ip_table_add_del,                                                     \
22368   "table <n> [ipv6] [add | del]\n")                                     \
22369 _(ip_add_del_route,                                                     \
22370   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22371   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22372   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22373   "[multipath] [count <n>] [del]")                                      \
22374 _(ip_mroute_add_del,                                                    \
22375   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22376   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22377 _(mpls_table_add_del,                                                   \
22378   "table <n> [add | del]\n")                                            \
22379 _(mpls_route_add_del,                                                   \
22380   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22381   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22382   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22383   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22384   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22385   "[count <n>] [del]")                                                  \
22386 _(mpls_ip_bind_unbind,                                                  \
22387   "<label> <addr/len>")                                                 \
22388 _(mpls_tunnel_add_del,                                                  \
22389   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22390   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22391   "[l2-only]  [out-label <n>]")                                         \
22392 _(sr_mpls_policy_add,                                                   \
22393   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22394 _(sr_mpls_policy_del,                                                   \
22395   "bsid <id>")                                                          \
22396 _(bier_table_add_del,                                                   \
22397   "<label> <sub-domain> <set> <bsl> [del]")                             \
22398 _(bier_route_add_del,                                                   \
22399   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22400   "[<intfc> | sw_if_index <id>]"                                        \
22401   "[weight <n>] [del] [multipath]")                                     \
22402 _(proxy_arp_add_del,                                                    \
22403   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22404 _(proxy_arp_intfc_enable_disable,                                       \
22405   "<intfc> | sw_if_index <id> enable | disable")                        \
22406 _(sw_interface_set_unnumbered,                                          \
22407   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22408 _(ip_neighbor_add_del,                                                  \
22409   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22410   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22411 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22412 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22413   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22414   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22415   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22416 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22417 _(reset_fib, "vrf <n> [ipv6]")                                          \
22418 _(dhcp_proxy_config,                                                    \
22419   "svr <v46-address> src <v46-address>\n"                               \
22420    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22421 _(dhcp_proxy_set_vss,                                                   \
22422   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22423 _(dhcp_proxy_dump, "ip6")                                               \
22424 _(dhcp_client_config,                                                   \
22425   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22426 _(set_ip_flow_hash,                                                     \
22427   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22428 _(sw_interface_ip6_enable_disable,                                      \
22429   "<intfc> | sw_if_index <id> enable | disable")                        \
22430 _(ip6nd_proxy_add_del,                                                  \
22431   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22432 _(ip6nd_proxy_dump, "")                                                 \
22433 _(sw_interface_ip6nd_ra_prefix,                                         \
22434   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22435   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22436   "[nolink] [isno]")                                                    \
22437 _(sw_interface_ip6nd_ra_config,                                         \
22438   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22439   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22440   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22441 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22442 _(l2_patch_add_del,                                                     \
22443   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22444   "enable | disable")                                                   \
22445 _(sr_localsid_add_del,                                                  \
22446   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22447   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22448 _(classify_add_del_table,                                               \
22449   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22450   " [del] [del-chain] mask <mask-value>\n"                              \
22451   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22452   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22453 _(classify_add_del_session,                                             \
22454   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22455   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22456   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22457   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22458 _(classify_set_interface_ip_table,                                      \
22459   "<intfc> | sw_if_index <nn> table <nn>")                              \
22460 _(classify_set_interface_l2_tables,                                     \
22461   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22462   "  [other-table <nn>]")                                               \
22463 _(get_node_index, "node <node-name")                                    \
22464 _(add_node_next, "node <node-name> next <next-node-name>")              \
22465 _(l2tpv3_create_tunnel,                                                 \
22466   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22467   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22468   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22469 _(l2tpv3_set_tunnel_cookies,                                            \
22470   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22471   "[new_remote_cookie <nn>]\n")                                         \
22472 _(l2tpv3_interface_enable_disable,                                      \
22473   "<intfc> | sw_if_index <nn> enable | disable")                        \
22474 _(l2tpv3_set_lookup_key,                                                \
22475   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22476 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22477 _(vxlan_offload_rx,                                                     \
22478   "hw { <interface name> | hw_if_index <nn>} "                          \
22479   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22480 _(vxlan_add_del_tunnel,                                                 \
22481   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22482   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22483   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22484 _(geneve_add_del_tunnel,                                                \
22485   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22486   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22487   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22488 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22489 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22490 _(gre_tunnel_add_del,                                                   \
22491   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22492   "[teb | erspan <session-id>] [del]")                                  \
22493 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22494 _(l2_fib_clear_table, "")                                               \
22495 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22496 _(l2_interface_vlan_tag_rewrite,                                        \
22497   "<intfc> | sw_if_index <nn> \n"                                       \
22498   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22499   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22500 _(create_vhost_user_if,                                                 \
22501         "socket <filename> [server] [renumber <dev_instance>] "         \
22502         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22503         "[mac <mac_address>]")                                          \
22504 _(modify_vhost_user_if,                                                 \
22505         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22506         "[server] [renumber <dev_instance>]")                           \
22507 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22508 _(sw_interface_vhost_user_dump, "")                                     \
22509 _(show_version, "")                                                     \
22510 _(show_threads, "")                                                     \
22511 _(vxlan_gpe_add_del_tunnel,                                             \
22512   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22513   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22514   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22515   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22516 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22517 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22518 _(interface_name_renumber,                                              \
22519   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22520 _(input_acl_set_interface,                                              \
22521   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22522   "  [l2-table <nn>] [del]")                                            \
22523 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22524 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22525   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22526 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22527 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22528 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22529 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22530 _(ip_dump, "ipv4 | ipv6")                                               \
22531 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22532 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22533   "  spid_id <n> ")                                                     \
22534 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22535   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22536   "  integ_alg <alg> integ_key <hex>")                                  \
22537 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22538   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22539   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22540   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22541 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22542 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22543   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22544   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22545   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22546   "  [instance <n>]")     \
22547 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22548 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22549   "  <alg> <hex>\n")                                                    \
22550 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22551 _(delete_loopback,"sw_if_index <nn>")                                   \
22552 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22553 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22554 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22555 _(want_interface_events,  "enable|disable")                             \
22556 _(get_first_msg_id, "client <name>")                                    \
22557 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22558 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22559   "fib-id <nn> [ip4][ip6][default]")                                    \
22560 _(get_node_graph, " ")                                                  \
22561 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22562 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22563 _(ioam_disable, "")                                                     \
22564 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22565                             " sw_if_index <sw_if_index> p <priority> "  \
22566                             "w <weight>] [del]")                        \
22567 _(one_add_del_locator, "locator-set <locator_name> "                    \
22568                         "iface <intf> | sw_if_index <sw_if_index> "     \
22569                         "p <priority> w <weight> [del]")                \
22570 _(one_add_del_local_eid,"vni <vni> eid "                                \
22571                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22572                          "locator-set <locator_name> [del]"             \
22573                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22574 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22575 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22576 _(one_enable_disable, "enable|disable")                                 \
22577 _(one_map_register_enable_disable, "enable|disable")                    \
22578 _(one_map_register_fallback_threshold, "<value>")                       \
22579 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22580 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22581                                "[seid <seid>] "                         \
22582                                "rloc <locator> p <prio> "               \
22583                                "w <weight> [rloc <loc> ... ] "          \
22584                                "action <action> [del-all]")             \
22585 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22586                           "<local-eid>")                                \
22587 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22588 _(one_use_petr, "ip-address> | disable")                                \
22589 _(one_map_request_mode, "src-dst|dst-only")                             \
22590 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22591 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22592 _(one_locator_set_dump, "[local | remote]")                             \
22593 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22594 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22595                        "[local] | [remote]")                            \
22596 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22597 _(one_ndp_bd_get, "")                                                   \
22598 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22599 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22600 _(one_l2_arp_bd_get, "")                                                \
22601 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22602 _(one_stats_enable_disable, "enable|disable")                           \
22603 _(show_one_stats_enable_disable, "")                                    \
22604 _(one_eid_table_vni_dump, "")                                           \
22605 _(one_eid_table_map_dump, "l2|l3")                                      \
22606 _(one_map_resolver_dump, "")                                            \
22607 _(one_map_server_dump, "")                                              \
22608 _(one_adjacencies_get, "vni <vni>")                                     \
22609 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22610 _(show_one_rloc_probe_state, "")                                        \
22611 _(show_one_map_register_state, "")                                      \
22612 _(show_one_status, "")                                                  \
22613 _(one_stats_dump, "")                                                   \
22614 _(one_stats_flush, "")                                                  \
22615 _(one_get_map_request_itr_rlocs, "")                                    \
22616 _(one_map_register_set_ttl, "<ttl>")                                    \
22617 _(one_set_transport_protocol, "udp|api")                                \
22618 _(one_get_transport_protocol, "")                                       \
22619 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22620 _(one_show_xtr_mode, "")                                                \
22621 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22622 _(one_show_pitr_mode, "")                                               \
22623 _(one_enable_disable_petr_mode, "enable|disable")                       \
22624 _(one_show_petr_mode, "")                                               \
22625 _(show_one_nsh_mapping, "")                                             \
22626 _(show_one_pitr, "")                                                    \
22627 _(show_one_use_petr, "")                                                \
22628 _(show_one_map_request_mode, "")                                        \
22629 _(show_one_map_register_ttl, "")                                        \
22630 _(show_one_map_register_fallback_threshold, "")                         \
22631 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22632                             " sw_if_index <sw_if_index> p <priority> "  \
22633                             "w <weight>] [del]")                        \
22634 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22635                         "iface <intf> | sw_if_index <sw_if_index> "     \
22636                         "p <priority> w <weight> [del]")                \
22637 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22638                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22639                          "locator-set <locator_name> [del]"             \
22640                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22641 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22642 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22643 _(lisp_enable_disable, "enable|disable")                                \
22644 _(lisp_map_register_enable_disable, "enable|disable")                   \
22645 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22646 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22647                                "[seid <seid>] "                         \
22648                                "rloc <locator> p <prio> "               \
22649                                "w <weight> [rloc <loc> ... ] "          \
22650                                "action <action> [del-all]")             \
22651 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22652                           "<local-eid>")                                \
22653 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22654 _(lisp_use_petr, "<ip-address> | disable")                              \
22655 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22656 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22657 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22658 _(lisp_locator_set_dump, "[local | remote]")                            \
22659 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22660 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22661                        "[local] | [remote]")                            \
22662 _(lisp_eid_table_vni_dump, "")                                          \
22663 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22664 _(lisp_map_resolver_dump, "")                                           \
22665 _(lisp_map_server_dump, "")                                             \
22666 _(lisp_adjacencies_get, "vni <vni>")                                    \
22667 _(gpe_fwd_entry_vnis_get, "")                                           \
22668 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22669 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22670                                 "[table <table-id>]")                   \
22671 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22672 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22673 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22674 _(gpe_get_encap_mode, "")                                               \
22675 _(lisp_gpe_add_del_iface, "up|down")                                    \
22676 _(lisp_gpe_enable_disable, "enable|disable")                            \
22677 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22678   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22679 _(show_lisp_rloc_probe_state, "")                                       \
22680 _(show_lisp_map_register_state, "")                                     \
22681 _(show_lisp_status, "")                                                 \
22682 _(lisp_get_map_request_itr_rlocs, "")                                   \
22683 _(show_lisp_pitr, "")                                                   \
22684 _(show_lisp_use_petr, "")                                               \
22685 _(show_lisp_map_request_mode, "")                                       \
22686 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22687 _(af_packet_delete, "name <host interface name>")                       \
22688 _(af_packet_dump, "")                                                   \
22689 _(policer_add_del, "name <policer name> <params> [del]")                \
22690 _(policer_dump, "[name <policer name>]")                                \
22691 _(policer_classify_set_interface,                                       \
22692   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22693   "  [l2-table <nn>] [del]")                                            \
22694 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22695 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22696     "[master|slave]")                                                   \
22697 _(netmap_delete, "name <interface name>")                               \
22698 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22699 _(mpls_fib_dump, "")                                                    \
22700 _(classify_table_ids, "")                                               \
22701 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22702 _(classify_table_info, "table_id <nn>")                                 \
22703 _(classify_session_dump, "table_id <nn>")                               \
22704 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22705     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22706     "[template_interval <nn>] [udp_checksum]")                          \
22707 _(ipfix_exporter_dump, "")                                              \
22708 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22709 _(ipfix_classify_stream_dump, "")                                       \
22710 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22711 _(ipfix_classify_table_dump, "")                                        \
22712 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22713 _(sw_interface_span_dump, "[l2]")                                           \
22714 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22715 _(pg_create_interface, "if_id <nn>")                                    \
22716 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22717 _(pg_enable_disable, "[stream <id>] disable")                           \
22718 _(ip_source_and_port_range_check_add_del,                               \
22719   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22720 _(ip_source_and_port_range_check_interface_add_del,                     \
22721   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22722   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22723 _(ipsec_gre_tunnel_add_del,                                             \
22724   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22725 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22726 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22727 _(l2_interface_pbb_tag_rewrite,                                         \
22728   "<intfc> | sw_if_index <nn> \n"                                       \
22729   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22730   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22731 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22732 _(flow_classify_set_interface,                                          \
22733   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22734 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22735 _(ip_fib_dump, "")                                                      \
22736 _(ip_mfib_dump, "")                                                     \
22737 _(ip6_fib_dump, "")                                                     \
22738 _(ip6_mfib_dump, "")                                                    \
22739 _(feature_enable_disable, "arc_name <arc_name> "                        \
22740   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22741 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22742 "[disable]")                                                            \
22743 _(l2_xconnect_dump, "")                                                 \
22744 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22745 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22746 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22747 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22748 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22749 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22750 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22751   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22752 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22753 _(sock_init_shm, "size <nnn>")                                          \
22754 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22755 _(dns_enable_disable, "[enable][disable]")                              \
22756 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22757 _(dns_resolve_name, "<hostname>")                                       \
22758 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22759 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22760 _(dns_resolve_name, "<hostname>")                                       \
22761 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22762   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22763 _(session_rules_dump, "")                                               \
22764 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22765 _(output_acl_set_interface,                                             \
22766   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22767   "  [l2-table <nn>] [del]")                                            \
22768 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22769
22770 /* List of command functions, CLI names map directly to functions */
22771 #define foreach_cli_function                                    \
22772 _(comment, "usage: comment <ignore-rest-of-line>")              \
22773 _(dump_interface_table, "usage: dump_interface_table")          \
22774 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22775 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22776 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22777 _(dump_macro_table, "usage: dump_macro_table ")                 \
22778 _(dump_node_table, "usage: dump_node_table")                    \
22779 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22780 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22781 _(echo, "usage: echo <message>")                                \
22782 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22783 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22784 _(help, "usage: help")                                          \
22785 _(q, "usage: quit")                                             \
22786 _(quit, "usage: quit")                                          \
22787 _(search_node_table, "usage: search_node_table <name>...")      \
22788 _(set, "usage: set <variable-name> <value>")                    \
22789 _(script, "usage: script <file-name>")                          \
22790 _(statseg, "usage: statseg");                                   \
22791 _(unset, "usage: unset <variable-name>")
22792
22793 #define _(N,n)                                  \
22794     static void vl_api_##n##_t_handler_uni      \
22795     (vl_api_##n##_t * mp)                       \
22796     {                                           \
22797         vat_main_t * vam = &vat_main;           \
22798         if (vam->json_output) {                 \
22799             vl_api_##n##_t_handler_json(mp);    \
22800         } else {                                \
22801             vl_api_##n##_t_handler(mp);         \
22802         }                                       \
22803     }
22804 foreach_vpe_api_reply_msg;
22805 #if VPP_API_TEST_BUILTIN == 0
22806 foreach_standalone_reply_msg;
22807 #endif
22808 #undef _
22809
22810 void
22811 vat_api_hookup (vat_main_t * vam)
22812 {
22813 #define _(N,n)                                                  \
22814     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22815                            vl_api_##n##_t_handler_uni,          \
22816                            vl_noop_handler,                     \
22817                            vl_api_##n##_t_endian,               \
22818                            vl_api_##n##_t_print,                \
22819                            sizeof(vl_api_##n##_t), 1);
22820   foreach_vpe_api_reply_msg;
22821 #if VPP_API_TEST_BUILTIN == 0
22822   foreach_standalone_reply_msg;
22823 #endif
22824 #undef _
22825
22826 #if (VPP_API_TEST_BUILTIN==0)
22827   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22828
22829   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22830
22831   vam->function_by_name = hash_create_string (0, sizeof (uword));
22832
22833   vam->help_by_name = hash_create_string (0, sizeof (uword));
22834 #endif
22835
22836   /* API messages we can send */
22837 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22838   foreach_vpe_api_msg;
22839 #undef _
22840
22841   /* Help strings */
22842 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22843   foreach_vpe_api_msg;
22844 #undef _
22845
22846   /* CLI functions */
22847 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22848   foreach_cli_function;
22849 #undef _
22850
22851   /* Help strings */
22852 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22853   foreach_cli_function;
22854 #undef _
22855 }
22856
22857 #if VPP_API_TEST_BUILTIN
22858 static clib_error_t *
22859 vat_api_hookup_shim (vlib_main_t * vm)
22860 {
22861   vat_api_hookup (&vat_main);
22862   return 0;
22863 }
22864
22865 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22866 #endif
22867
22868 /*
22869  * fd.io coding-style-patch-verification: ON
22870  *
22871  * Local Variables:
22872  * eval: (c-set-style "gnu")
22873  * End:
22874  */