IPSEC-GRE: fixes and API update to common types.
[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_v6_address (ip6_address_t * a)
717 {
718   u64 v0, v1;
719
720   v0 = clib_net_to_host_u64 (a->as_u64[0]);
721   v1 = clib_net_to_host_u64 (a->as_u64[1]);
722
723   v1 += 1;
724   if (v1 == 0)
725     v0 += 1;
726   a->as_u64[0] = clib_net_to_host_u64 (v0);
727   a->as_u64[1] = clib_net_to_host_u64 (v1);
728 }
729
730 static void
731 increment_mac_address (u8 * mac)
732 {
733   u64 tmp = *((u64 *) mac);
734   tmp = clib_net_to_host_u64 (tmp);
735   tmp += 1 << 16;               /* skip unused (least significant) octets */
736   tmp = clib_host_to_net_u64 (tmp);
737
738   clib_memcpy (mac, &tmp, 6);
739 }
740
741 static void vl_api_create_loopback_reply_t_handler
742   (vl_api_create_loopback_reply_t * mp)
743 {
744   vat_main_t *vam = &vat_main;
745   i32 retval = ntohl (mp->retval);
746
747   vam->retval = retval;
748   vam->regenerate_interface_table = 1;
749   vam->sw_if_index = ntohl (mp->sw_if_index);
750   vam->result_ready = 1;
751 }
752
753 static void vl_api_create_loopback_reply_t_handler_json
754   (vl_api_create_loopback_reply_t * mp)
755 {
756   vat_main_t *vam = &vat_main;
757   vat_json_node_t node;
758
759   vat_json_init_object (&node);
760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
761   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
762
763   vat_json_print (vam->ofp, &node);
764   vat_json_free (&node);
765   vam->retval = ntohl (mp->retval);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_loopback_instance_reply_t_handler
770   (vl_api_create_loopback_instance_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   i32 retval = ntohl (mp->retval);
774
775   vam->retval = retval;
776   vam->regenerate_interface_table = 1;
777   vam->sw_if_index = ntohl (mp->sw_if_index);
778   vam->result_ready = 1;
779 }
780
781 static void vl_api_create_loopback_instance_reply_t_handler_json
782   (vl_api_create_loopback_instance_reply_t * mp)
783 {
784   vat_main_t *vam = &vat_main;
785   vat_json_node_t node;
786
787   vat_json_init_object (&node);
788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
790
791   vat_json_print (vam->ofp, &node);
792   vat_json_free (&node);
793   vam->retval = ntohl (mp->retval);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_af_packet_create_reply_t_handler
798   (vl_api_af_packet_create_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   i32 retval = ntohl (mp->retval);
802
803   vam->retval = retval;
804   vam->regenerate_interface_table = 1;
805   vam->sw_if_index = ntohl (mp->sw_if_index);
806   vam->result_ready = 1;
807 }
808
809 static void vl_api_af_packet_create_reply_t_handler_json
810   (vl_api_af_packet_create_reply_t * mp)
811 {
812   vat_main_t *vam = &vat_main;
813   vat_json_node_t node;
814
815   vat_json_init_object (&node);
816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
818
819   vat_json_print (vam->ofp, &node);
820   vat_json_free (&node);
821
822   vam->retval = ntohl (mp->retval);
823   vam->result_ready = 1;
824 }
825
826 static void vl_api_create_vlan_subif_reply_t_handler
827   (vl_api_create_vlan_subif_reply_t * mp)
828 {
829   vat_main_t *vam = &vat_main;
830   i32 retval = ntohl (mp->retval);
831
832   vam->retval = retval;
833   vam->regenerate_interface_table = 1;
834   vam->sw_if_index = ntohl (mp->sw_if_index);
835   vam->result_ready = 1;
836 }
837
838 static void vl_api_create_vlan_subif_reply_t_handler_json
839   (vl_api_create_vlan_subif_reply_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   vat_json_node_t node;
843
844   vat_json_init_object (&node);
845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
846   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
847
848   vat_json_print (vam->ofp, &node);
849   vat_json_free (&node);
850
851   vam->retval = ntohl (mp->retval);
852   vam->result_ready = 1;
853 }
854
855 static void vl_api_create_subif_reply_t_handler
856   (vl_api_create_subif_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->regenerate_interface_table = 1;
863   vam->sw_if_index = ntohl (mp->sw_if_index);
864   vam->result_ready = 1;
865 }
866
867 static void vl_api_create_subif_reply_t_handler_json
868   (vl_api_create_subif_reply_t * mp)
869 {
870   vat_main_t *vam = &vat_main;
871   vat_json_node_t node;
872
873   vat_json_init_object (&node);
874   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
875   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
876
877   vat_json_print (vam->ofp, &node);
878   vat_json_free (&node);
879
880   vam->retval = ntohl (mp->retval);
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_interface_name_renumber_reply_t_handler
885   (vl_api_interface_name_renumber_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   i32 retval = ntohl (mp->retval);
889
890   vam->retval = retval;
891   vam->regenerate_interface_table = 1;
892   vam->result_ready = 1;
893 }
894
895 static void vl_api_interface_name_renumber_reply_t_handler_json
896   (vl_api_interface_name_renumber_reply_t * mp)
897 {
898   vat_main_t *vam = &vat_main;
899   vat_json_node_t node;
900
901   vat_json_init_object (&node);
902   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
903
904   vat_json_print (vam->ofp, &node);
905   vat_json_free (&node);
906
907   vam->retval = ntohl (mp->retval);
908   vam->result_ready = 1;
909 }
910
911 /*
912  * Special-case: build the interface table, maintain
913  * the next loopback sw_if_index vbl.
914  */
915 static void vl_api_sw_interface_details_t_handler
916   (vl_api_sw_interface_details_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   u8 *s = format (0, "%s%c", mp->interface_name, 0);
920
921   hash_set_mem (vam->sw_if_index_by_interface_name, s,
922                 ntohl (mp->sw_if_index));
923
924   /* In sub interface case, fill the sub interface table entry */
925   if (mp->sw_if_index != mp->sup_sw_if_index)
926     {
927       sw_interface_subif_t *sub = NULL;
928
929       vec_add2 (vam->sw_if_subif_table, sub, 1);
930
931       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
932       strncpy ((char *) sub->interface_name, (char *) s,
933                vec_len (sub->interface_name));
934       sub->sw_if_index = ntohl (mp->sw_if_index);
935       sub->sub_id = ntohl (mp->sub_id);
936
937       sub->sub_dot1ad = mp->sub_dot1ad;
938       sub->sub_number_of_tags = mp->sub_number_of_tags;
939       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
940       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
941       sub->sub_exact_match = mp->sub_exact_match;
942       sub->sub_default = mp->sub_default;
943       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
944       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
945
946       /* vlan tag rewrite */
947       sub->vtr_op = ntohl (mp->vtr_op);
948       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
949       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
950       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
951     }
952 }
953
954 static void vl_api_sw_interface_details_t_handler_json
955   (vl_api_sw_interface_details_t * mp)
956 {
957   vat_main_t *vam = &vat_main;
958   vat_json_node_t *node = NULL;
959
960   if (VAT_JSON_ARRAY != vam->json_tree.type)
961     {
962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
963       vat_json_init_array (&vam->json_tree);
964     }
965   node = vat_json_array_add (&vam->json_tree);
966
967   vat_json_init_object (node);
968   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
969   vat_json_object_add_uint (node, "sup_sw_if_index",
970                             ntohl (mp->sup_sw_if_index));
971   vat_json_object_add_uint (node, "l2_address_length",
972                             ntohl (mp->l2_address_length));
973   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
974                              sizeof (mp->l2_address));
975   vat_json_object_add_string_copy (node, "interface_name",
976                                    mp->interface_name);
977   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
978   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
979   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
980   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
981   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
982   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
983   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
984   vat_json_object_add_uint (node, "sub_number_of_tags",
985                             mp->sub_number_of_tags);
986   vat_json_object_add_uint (node, "sub_outer_vlan_id",
987                             ntohs (mp->sub_outer_vlan_id));
988   vat_json_object_add_uint (node, "sub_inner_vlan_id",
989                             ntohs (mp->sub_inner_vlan_id));
990   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
991   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
992   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
993                             mp->sub_outer_vlan_id_any);
994   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
995                             mp->sub_inner_vlan_id_any);
996   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
997   vat_json_object_add_uint (node, "vtr_push_dot1q",
998                             ntohl (mp->vtr_push_dot1q));
999   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1000   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1001   if (mp->sub_dot1ah)
1002     {
1003       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1004                                        format (0, "%U",
1005                                                format_ethernet_address,
1006                                                &mp->b_dmac));
1007       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1008                                        format (0, "%U",
1009                                                format_ethernet_address,
1010                                                &mp->b_smac));
1011       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1012       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1013     }
1014 }
1015
1016 #if VPP_API_TEST_BUILTIN == 0
1017 static void vl_api_sw_interface_event_t_handler
1018   (vl_api_sw_interface_event_t * mp)
1019 {
1020   vat_main_t *vam = &vat_main;
1021   if (vam->interface_event_display)
1022     errmsg ("interface flags: sw_if_index %d %s %s",
1023             ntohl (mp->sw_if_index),
1024             mp->admin_up_down ? "admin-up" : "admin-down",
1025             mp->link_up_down ? "link-up" : "link-down");
1026 }
1027 #endif
1028
1029 static void vl_api_sw_interface_event_t_handler_json
1030   (vl_api_sw_interface_event_t * mp)
1031 {
1032   /* JSON output not supported */
1033 }
1034
1035 static void
1036 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1037 {
1038   vat_main_t *vam = &vat_main;
1039   i32 retval = ntohl (mp->retval);
1040
1041   vam->retval = retval;
1042   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1043   vam->result_ready = 1;
1044 }
1045
1046 static void
1047 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1048 {
1049   vat_main_t *vam = &vat_main;
1050   vat_json_node_t node;
1051   api_main_t *am = &api_main;
1052   void *oldheap;
1053   u8 *reply;
1054
1055   vat_json_init_object (&node);
1056   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1057   vat_json_object_add_uint (&node, "reply_in_shmem",
1058                             ntohl (mp->reply_in_shmem));
1059   /* Toss the shared-memory original... */
1060   pthread_mutex_lock (&am->vlib_rp->mutex);
1061   oldheap = svm_push_data_heap (am->vlib_rp);
1062
1063   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1064   vec_free (reply);
1065
1066   svm_pop_heap (oldheap);
1067   pthread_mutex_unlock (&am->vlib_rp->mutex);
1068
1069   vat_json_print (vam->ofp, &node);
1070   vat_json_free (&node);
1071
1072   vam->retval = ntohl (mp->retval);
1073   vam->result_ready = 1;
1074 }
1075
1076 static void
1077 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1078 {
1079   vat_main_t *vam = &vat_main;
1080   i32 retval = ntohl (mp->retval);
1081   u32 length = vl_api_string_len (&mp->reply);
1082
1083   vec_reset_length (vam->cmd_reply);
1084
1085   vam->retval = retval;
1086   if (retval == 0)
1087     {
1088       vec_validate (vam->cmd_reply, length);
1089       clib_memcpy ((char *) (vam->cmd_reply),
1090                    vl_api_from_api_string (&mp->reply), length);
1091       vam->cmd_reply[length] = 0;
1092     }
1093   vam->result_ready = 1;
1094 }
1095
1096 static void
1097 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   vat_json_node_t node;
1101
1102   vec_reset_length (vam->cmd_reply);
1103
1104   vat_json_init_object (&node);
1105   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1106   vat_json_object_add_string_copy (&node, "reply",
1107                                    vl_api_from_api_string (&mp->reply));
1108
1109   vat_json_print (vam->ofp, &node);
1110   vat_json_free (&node);
1111
1112   vam->retval = ntohl (mp->retval);
1113   vam->result_ready = 1;
1114 }
1115
1116 static void vl_api_classify_add_del_table_reply_t_handler
1117   (vl_api_classify_add_del_table_reply_t * mp)
1118 {
1119   vat_main_t *vam = &vat_main;
1120   i32 retval = ntohl (mp->retval);
1121   if (vam->async_mode)
1122     {
1123       vam->async_errors += (retval < 0);
1124     }
1125   else
1126     {
1127       vam->retval = retval;
1128       if (retval == 0 &&
1129           ((mp->new_table_index != 0xFFFFFFFF) ||
1130            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1131            (mp->match_n_vectors != 0xFFFFFFFF)))
1132         /*
1133          * Note: this is just barely thread-safe, depends on
1134          * the main thread spinning waiting for an answer...
1135          */
1136         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1137                 ntohl (mp->new_table_index),
1138                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1139       vam->result_ready = 1;
1140     }
1141 }
1142
1143 static void vl_api_classify_add_del_table_reply_t_handler_json
1144   (vl_api_classify_add_del_table_reply_t * mp)
1145 {
1146   vat_main_t *vam = &vat_main;
1147   vat_json_node_t node;
1148
1149   vat_json_init_object (&node);
1150   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1151   vat_json_object_add_uint (&node, "new_table_index",
1152                             ntohl (mp->new_table_index));
1153   vat_json_object_add_uint (&node, "skip_n_vectors",
1154                             ntohl (mp->skip_n_vectors));
1155   vat_json_object_add_uint (&node, "match_n_vectors",
1156                             ntohl (mp->match_n_vectors));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_get_node_index_reply_t_handler
1166   (vl_api_get_node_index_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0)
1178         errmsg ("node index %d", ntohl (mp->node_index));
1179       vam->result_ready = 1;
1180     }
1181 }
1182
1183 static void vl_api_get_node_index_reply_t_handler_json
1184   (vl_api_get_node_index_reply_t * mp)
1185 {
1186   vat_main_t *vam = &vat_main;
1187   vat_json_node_t node;
1188
1189   vat_json_init_object (&node);
1190   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1191   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1192
1193   vat_json_print (vam->ofp, &node);
1194   vat_json_free (&node);
1195
1196   vam->retval = ntohl (mp->retval);
1197   vam->result_ready = 1;
1198 }
1199
1200 static void vl_api_get_next_index_reply_t_handler
1201   (vl_api_get_next_index_reply_t * mp)
1202 {
1203   vat_main_t *vam = &vat_main;
1204   i32 retval = ntohl (mp->retval);
1205   if (vam->async_mode)
1206     {
1207       vam->async_errors += (retval < 0);
1208     }
1209   else
1210     {
1211       vam->retval = retval;
1212       if (retval == 0)
1213         errmsg ("next node index %d", ntohl (mp->next_index));
1214       vam->result_ready = 1;
1215     }
1216 }
1217
1218 static void vl_api_get_next_index_reply_t_handler_json
1219   (vl_api_get_next_index_reply_t * mp)
1220 {
1221   vat_main_t *vam = &vat_main;
1222   vat_json_node_t node;
1223
1224   vat_json_init_object (&node);
1225   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1226   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1227
1228   vat_json_print (vam->ofp, &node);
1229   vat_json_free (&node);
1230
1231   vam->retval = ntohl (mp->retval);
1232   vam->result_ready = 1;
1233 }
1234
1235 static void vl_api_add_node_next_reply_t_handler
1236   (vl_api_add_node_next_reply_t * mp)
1237 {
1238   vat_main_t *vam = &vat_main;
1239   i32 retval = ntohl (mp->retval);
1240   if (vam->async_mode)
1241     {
1242       vam->async_errors += (retval < 0);
1243     }
1244   else
1245     {
1246       vam->retval = retval;
1247       if (retval == 0)
1248         errmsg ("next index %d", ntohl (mp->next_index));
1249       vam->result_ready = 1;
1250     }
1251 }
1252
1253 static void vl_api_add_node_next_reply_t_handler_json
1254   (vl_api_add_node_next_reply_t * mp)
1255 {
1256   vat_main_t *vam = &vat_main;
1257   vat_json_node_t node;
1258
1259   vat_json_init_object (&node);
1260   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1261   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1262
1263   vat_json_print (vam->ofp, &node);
1264   vat_json_free (&node);
1265
1266   vam->retval = ntohl (mp->retval);
1267   vam->result_ready = 1;
1268 }
1269
1270 static void vl_api_show_version_reply_t_handler
1271   (vl_api_show_version_reply_t * mp)
1272 {
1273   vat_main_t *vam = &vat_main;
1274   i32 retval = ntohl (mp->retval);
1275
1276   if (retval >= 0)
1277     {
1278       char *s;
1279       char *p = (char *) &mp->program;
1280
1281       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1282       errmsg ("        program: %s\n", s);
1283       free (s);
1284
1285       p +=
1286         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1287       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1288       errmsg ("        version: %s\n", s);
1289       free (s);
1290
1291       p +=
1292         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1293       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1294       errmsg ("     build date: %s\n", s);
1295       free (s);
1296
1297       p +=
1298         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1299       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1300       errmsg ("build directory: %s\n", s);
1301       free (s);
1302     }
1303   vam->retval = retval;
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_show_version_reply_t_handler_json
1308   (vl_api_show_version_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   vat_json_node_t node;
1312
1313   vat_json_init_object (&node);
1314   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1315   char *p = (char *) &mp->program;
1316   vat_json_object_add_string_copy (&node, "program",
1317                                    vl_api_from_api_string ((vl_api_string_t *)
1318                                                            p));
1319   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1320   vat_json_object_add_string_copy (&node, "version",
1321                                    vl_api_from_api_string ((vl_api_string_t *)
1322                                                            p));
1323   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1324   vat_json_object_add_string_copy (&node, "build_date",
1325                                    vl_api_from_api_string ((vl_api_string_t *)
1326                                                            p));
1327   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1328   vat_json_object_add_string_copy (&node, "build_directory",
1329                                    vl_api_from_api_string ((vl_api_string_t *)
1330                                                            p));
1331
1332   vat_json_print (vam->ofp, &node);
1333   vat_json_free (&node);
1334
1335   vam->retval = ntohl (mp->retval);
1336   vam->result_ready = 1;
1337 }
1338
1339 static void vl_api_show_threads_reply_t_handler
1340   (vl_api_show_threads_reply_t * mp)
1341 {
1342   vat_main_t *vam = &vat_main;
1343   i32 retval = ntohl (mp->retval);
1344   int i, count = 0;
1345
1346   if (retval >= 0)
1347     count = ntohl (mp->count);
1348
1349   for (i = 0; i < count; i++)
1350     print (vam->ofp,
1351            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1352            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1353            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1354            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1355            ntohl (mp->thread_data[i].cpu_socket));
1356
1357   vam->retval = retval;
1358   vam->result_ready = 1;
1359 }
1360
1361 static void vl_api_show_threads_reply_t_handler_json
1362   (vl_api_show_threads_reply_t * mp)
1363 {
1364   vat_main_t *vam = &vat_main;
1365   vat_json_node_t node;
1366   vl_api_thread_data_t *td;
1367   i32 retval = ntohl (mp->retval);
1368   int i, count = 0;
1369
1370   if (retval >= 0)
1371     count = ntohl (mp->count);
1372
1373   vat_json_init_object (&node);
1374   vat_json_object_add_int (&node, "retval", retval);
1375   vat_json_object_add_uint (&node, "count", count);
1376
1377   for (i = 0; i < count; i++)
1378     {
1379       td = &mp->thread_data[i];
1380       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1381       vat_json_object_add_string_copy (&node, "name", td->name);
1382       vat_json_object_add_string_copy (&node, "type", td->type);
1383       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1384       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1385       vat_json_object_add_int (&node, "core", ntohl (td->id));
1386       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1387     }
1388
1389   vat_json_print (vam->ofp, &node);
1390   vat_json_free (&node);
1391
1392   vam->retval = retval;
1393   vam->result_ready = 1;
1394 }
1395
1396 static int
1397 api_show_threads (vat_main_t * vam)
1398 {
1399   vl_api_show_threads_t *mp;
1400   int ret;
1401
1402   print (vam->ofp,
1403          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1404          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1405
1406   M (SHOW_THREADS, mp);
1407
1408   S (mp);
1409   W (ret);
1410   return ret;
1411 }
1412
1413 static void
1414 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1415 {
1416   u32 sw_if_index = ntohl (mp->sw_if_index);
1417   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1418           mp->mac_ip ? "mac/ip binding" : "address resolution",
1419           ntohl (mp->pid), format_ip4_address, mp->ip,
1420           format_vl_api_mac_address, &mp->mac, sw_if_index);
1421 }
1422
1423 static void
1424 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1425 {
1426   /* JSON output not supported */
1427 }
1428
1429 static void
1430 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1431 {
1432   u32 sw_if_index = ntohl (mp->sw_if_index);
1433   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1434           mp->mac_ip ? "mac/ip binding" : "address resolution",
1435           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1436           format_vl_api_mac_address, mp->mac, sw_if_index);
1437 }
1438
1439 static void
1440 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1441 {
1442   /* JSON output not supported */
1443 }
1444
1445 static void
1446 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1447 {
1448   u32 n_macs = ntohl (mp->n_macs);
1449   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1450           ntohl (mp->pid), mp->client_index, n_macs);
1451   int i;
1452   for (i = 0; i < n_macs; i++)
1453     {
1454       vl_api_mac_entry_t *mac = &mp->mac[i];
1455       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1456               i + 1, ntohl (mac->sw_if_index),
1457               format_ethernet_address, mac->mac_addr, mac->action);
1458       if (i == 1000)
1459         break;
1460     }
1461 }
1462
1463 static void
1464 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1465 {
1466   /* JSON output not supported */
1467 }
1468
1469 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1470 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1471
1472 /*
1473  * Special-case: build the bridge domain table, maintain
1474  * the next bd id vbl.
1475  */
1476 static void vl_api_bridge_domain_details_t_handler
1477   (vl_api_bridge_domain_details_t * mp)
1478 {
1479   vat_main_t *vam = &vat_main;
1480   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1481   int i;
1482
1483   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1484          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1485
1486   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1487          ntohl (mp->bd_id), mp->learn, mp->forward,
1488          mp->flood, ntohl (mp->bvi_sw_if_index),
1489          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1490
1491   if (n_sw_ifs)
1492     {
1493       vl_api_bridge_domain_sw_if_t *sw_ifs;
1494       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1495              "Interface Name");
1496
1497       sw_ifs = mp->sw_if_details;
1498       for (i = 0; i < n_sw_ifs; i++)
1499         {
1500           u8 *sw_if_name = 0;
1501           u32 sw_if_index;
1502           hash_pair_t *p;
1503
1504           sw_if_index = ntohl (sw_ifs->sw_if_index);
1505
1506           /* *INDENT-OFF* */
1507           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1508                              ({
1509                                if ((u32) p->value[0] == sw_if_index)
1510                                  {
1511                                    sw_if_name = (u8 *)(p->key);
1512                                    break;
1513                                  }
1514                              }));
1515           /* *INDENT-ON* */
1516           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1517                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1518                  "sw_if_index not found!");
1519
1520           sw_ifs++;
1521         }
1522     }
1523 }
1524
1525 static void vl_api_bridge_domain_details_t_handler_json
1526   (vl_api_bridge_domain_details_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   vat_json_node_t *node, *array = NULL;
1530   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1531
1532   if (VAT_JSON_ARRAY != vam->json_tree.type)
1533     {
1534       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1535       vat_json_init_array (&vam->json_tree);
1536     }
1537   node = vat_json_array_add (&vam->json_tree);
1538
1539   vat_json_init_object (node);
1540   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1541   vat_json_object_add_uint (node, "flood", mp->flood);
1542   vat_json_object_add_uint (node, "forward", mp->forward);
1543   vat_json_object_add_uint (node, "learn", mp->learn);
1544   vat_json_object_add_uint (node, "bvi_sw_if_index",
1545                             ntohl (mp->bvi_sw_if_index));
1546   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1547   array = vat_json_object_add (node, "sw_if");
1548   vat_json_init_array (array);
1549
1550
1551
1552   if (n_sw_ifs)
1553     {
1554       vl_api_bridge_domain_sw_if_t *sw_ifs;
1555       int i;
1556
1557       sw_ifs = mp->sw_if_details;
1558       for (i = 0; i < n_sw_ifs; i++)
1559         {
1560           node = vat_json_array_add (array);
1561           vat_json_init_object (node);
1562           vat_json_object_add_uint (node, "sw_if_index",
1563                                     ntohl (sw_ifs->sw_if_index));
1564           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1565           sw_ifs++;
1566         }
1567     }
1568 }
1569
1570 static void vl_api_control_ping_reply_t_handler
1571   (vl_api_control_ping_reply_t * mp)
1572 {
1573   vat_main_t *vam = &vat_main;
1574   i32 retval = ntohl (mp->retval);
1575   if (vam->async_mode)
1576     {
1577       vam->async_errors += (retval < 0);
1578     }
1579   else
1580     {
1581       vam->retval = retval;
1582       vam->result_ready = 1;
1583     }
1584   if (vam->socket_client_main)
1585     vam->socket_client_main->control_pings_outstanding--;
1586 }
1587
1588 static void vl_api_control_ping_reply_t_handler_json
1589   (vl_api_control_ping_reply_t * mp)
1590 {
1591   vat_main_t *vam = &vat_main;
1592   i32 retval = ntohl (mp->retval);
1593
1594   if (VAT_JSON_NONE != vam->json_tree.type)
1595     {
1596       vat_json_print (vam->ofp, &vam->json_tree);
1597       vat_json_free (&vam->json_tree);
1598       vam->json_tree.type = VAT_JSON_NONE;
1599     }
1600   else
1601     {
1602       /* just print [] */
1603       vat_json_init_array (&vam->json_tree);
1604       vat_json_print (vam->ofp, &vam->json_tree);
1605       vam->json_tree.type = VAT_JSON_NONE;
1606     }
1607
1608   vam->retval = retval;
1609   vam->result_ready = 1;
1610 }
1611
1612 static void
1613   vl_api_bridge_domain_set_mac_age_reply_t_handler
1614   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->result_ready = 1;
1626     }
1627 }
1628
1629 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1630   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   vat_json_node_t node;
1634
1635   vat_json_init_object (&node);
1636   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1637
1638   vat_json_print (vam->ofp, &node);
1639   vat_json_free (&node);
1640
1641   vam->retval = ntohl (mp->retval);
1642   vam->result_ready = 1;
1643 }
1644
1645 static void
1646 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   i32 retval = ntohl (mp->retval);
1650   if (vam->async_mode)
1651     {
1652       vam->async_errors += (retval < 0);
1653     }
1654   else
1655     {
1656       vam->retval = retval;
1657       vam->result_ready = 1;
1658     }
1659 }
1660
1661 static void vl_api_l2_flags_reply_t_handler_json
1662   (vl_api_l2_flags_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   vat_json_node_t node;
1666
1667   vat_json_init_object (&node);
1668   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1669   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1670                             ntohl (mp->resulting_feature_bitmap));
1671
1672   vat_json_print (vam->ofp, &node);
1673   vat_json_free (&node);
1674
1675   vam->retval = ntohl (mp->retval);
1676   vam->result_ready = 1;
1677 }
1678
1679 static void vl_api_bridge_flags_reply_t_handler
1680   (vl_api_bridge_flags_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   i32 retval = ntohl (mp->retval);
1684   if (vam->async_mode)
1685     {
1686       vam->async_errors += (retval < 0);
1687     }
1688   else
1689     {
1690       vam->retval = retval;
1691       vam->result_ready = 1;
1692     }
1693 }
1694
1695 static void vl_api_bridge_flags_reply_t_handler_json
1696   (vl_api_bridge_flags_reply_t * mp)
1697 {
1698   vat_main_t *vam = &vat_main;
1699   vat_json_node_t node;
1700
1701   vat_json_init_object (&node);
1702   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1703   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1704                             ntohl (mp->resulting_feature_bitmap));
1705
1706   vat_json_print (vam->ofp, &node);
1707   vat_json_free (&node);
1708
1709   vam->retval = ntohl (mp->retval);
1710   vam->result_ready = 1;
1711 }
1712
1713 static void
1714 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   i32 retval = ntohl (mp->retval);
1718   if (vam->async_mode)
1719     {
1720       vam->async_errors += (retval < 0);
1721     }
1722   else
1723     {
1724       vam->retval = retval;
1725       vam->sw_if_index = ntohl (mp->sw_if_index);
1726       vam->result_ready = 1;
1727     }
1728
1729 }
1730
1731 static void vl_api_tap_create_v2_reply_t_handler_json
1732   (vl_api_tap_create_v2_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   vat_json_node_t node;
1736
1737   vat_json_init_object (&node);
1738   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1739   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1740
1741   vat_json_print (vam->ofp, &node);
1742   vat_json_free (&node);
1743
1744   vam->retval = ntohl (mp->retval);
1745   vam->result_ready = 1;
1746
1747 }
1748
1749 static void
1750 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   i32 retval = ntohl (mp->retval);
1754   if (vam->async_mode)
1755     {
1756       vam->async_errors += (retval < 0);
1757     }
1758   else
1759     {
1760       vam->retval = retval;
1761       vam->result_ready = 1;
1762     }
1763 }
1764
1765 static void vl_api_tap_delete_v2_reply_t_handler_json
1766   (vl_api_tap_delete_v2_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   vat_json_node_t node;
1770
1771   vat_json_init_object (&node);
1772   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1773
1774   vat_json_print (vam->ofp, &node);
1775   vat_json_free (&node);
1776
1777   vam->retval = ntohl (mp->retval);
1778   vam->result_ready = 1;
1779 }
1780
1781 static void
1782 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1783                                           mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   i32 retval = ntohl (mp->retval);
1787   if (vam->async_mode)
1788     {
1789       vam->async_errors += (retval < 0);
1790     }
1791   else
1792     {
1793       vam->retval = retval;
1794       vam->sw_if_index = ntohl (mp->sw_if_index);
1795       vam->result_ready = 1;
1796     }
1797 }
1798
1799 static void vl_api_virtio_pci_create_reply_t_handler_json
1800   (vl_api_virtio_pci_create_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   vat_json_node_t node;
1804
1805   vat_json_init_object (&node);
1806   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1807   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1808
1809   vat_json_print (vam->ofp, &node);
1810   vat_json_free (&node);
1811
1812   vam->retval = ntohl (mp->retval);
1813   vam->result_ready = 1;
1814
1815 }
1816
1817 static void
1818 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1819                                           mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822   i32 retval = ntohl (mp->retval);
1823   if (vam->async_mode)
1824     {
1825       vam->async_errors += (retval < 0);
1826     }
1827   else
1828     {
1829       vam->retval = retval;
1830       vam->result_ready = 1;
1831     }
1832 }
1833
1834 static void vl_api_virtio_pci_delete_reply_t_handler_json
1835   (vl_api_virtio_pci_delete_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   vat_json_node_t node;
1839
1840   vat_json_init_object (&node);
1841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1842
1843   vat_json_print (vam->ofp, &node);
1844   vat_json_free (&node);
1845
1846   vam->retval = ntohl (mp->retval);
1847   vam->result_ready = 1;
1848 }
1849
1850 static void
1851 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1852 {
1853   vat_main_t *vam = &vat_main;
1854   i32 retval = ntohl (mp->retval);
1855
1856   if (vam->async_mode)
1857     {
1858       vam->async_errors += (retval < 0);
1859     }
1860   else
1861     {
1862       vam->retval = retval;
1863       vam->sw_if_index = ntohl (mp->sw_if_index);
1864       vam->result_ready = 1;
1865     }
1866 }
1867
1868 static void vl_api_bond_create_reply_t_handler_json
1869   (vl_api_bond_create_reply_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   vat_json_node_t node;
1873
1874   vat_json_init_object (&node);
1875   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1876   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1877
1878   vat_json_print (vam->ofp, &node);
1879   vat_json_free (&node);
1880
1881   vam->retval = ntohl (mp->retval);
1882   vam->result_ready = 1;
1883 }
1884
1885 static void
1886 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1887 {
1888   vat_main_t *vam = &vat_main;
1889   i32 retval = ntohl (mp->retval);
1890
1891   if (vam->async_mode)
1892     {
1893       vam->async_errors += (retval < 0);
1894     }
1895   else
1896     {
1897       vam->retval = retval;
1898       vam->result_ready = 1;
1899     }
1900 }
1901
1902 static void vl_api_bond_delete_reply_t_handler_json
1903   (vl_api_bond_delete_reply_t * mp)
1904 {
1905   vat_main_t *vam = &vat_main;
1906   vat_json_node_t node;
1907
1908   vat_json_init_object (&node);
1909   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1910
1911   vat_json_print (vam->ofp, &node);
1912   vat_json_free (&node);
1913
1914   vam->retval = ntohl (mp->retval);
1915   vam->result_ready = 1;
1916 }
1917
1918 static void
1919 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1920 {
1921   vat_main_t *vam = &vat_main;
1922   i32 retval = ntohl (mp->retval);
1923
1924   if (vam->async_mode)
1925     {
1926       vam->async_errors += (retval < 0);
1927     }
1928   else
1929     {
1930       vam->retval = retval;
1931       vam->result_ready = 1;
1932     }
1933 }
1934
1935 static void vl_api_bond_enslave_reply_t_handler_json
1936   (vl_api_bond_enslave_reply_t * mp)
1937 {
1938   vat_main_t *vam = &vat_main;
1939   vat_json_node_t node;
1940
1941   vat_json_init_object (&node);
1942   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1943
1944   vat_json_print (vam->ofp, &node);
1945   vat_json_free (&node);
1946
1947   vam->retval = ntohl (mp->retval);
1948   vam->result_ready = 1;
1949 }
1950
1951 static void
1952 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1953                                           mp)
1954 {
1955   vat_main_t *vam = &vat_main;
1956   i32 retval = ntohl (mp->retval);
1957
1958   if (vam->async_mode)
1959     {
1960       vam->async_errors += (retval < 0);
1961     }
1962   else
1963     {
1964       vam->retval = retval;
1965       vam->result_ready = 1;
1966     }
1967 }
1968
1969 static void vl_api_bond_detach_slave_reply_t_handler_json
1970   (vl_api_bond_detach_slave_reply_t * mp)
1971 {
1972   vat_main_t *vam = &vat_main;
1973   vat_json_node_t node;
1974
1975   vat_json_init_object (&node);
1976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1977
1978   vat_json_print (vam->ofp, &node);
1979   vat_json_free (&node);
1980
1981   vam->retval = ntohl (mp->retval);
1982   vam->result_ready = 1;
1983 }
1984
1985 static void vl_api_sw_interface_bond_details_t_handler
1986   (vl_api_sw_interface_bond_details_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989
1990   print (vam->ofp,
1991          "%-16s %-12d %-12U %-13U %-14u %-14u",
1992          mp->interface_name, ntohl (mp->sw_if_index),
1993          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1994          ntohl (mp->active_slaves), ntohl (mp->slaves));
1995 }
1996
1997 static void vl_api_sw_interface_bond_details_t_handler_json
1998   (vl_api_sw_interface_bond_details_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001   vat_json_node_t *node = NULL;
2002
2003   if (VAT_JSON_ARRAY != vam->json_tree.type)
2004     {
2005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2006       vat_json_init_array (&vam->json_tree);
2007     }
2008   node = vat_json_array_add (&vam->json_tree);
2009
2010   vat_json_init_object (node);
2011   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2012   vat_json_object_add_string_copy (node, "interface_name",
2013                                    mp->interface_name);
2014   vat_json_object_add_uint (node, "mode", mp->mode);
2015   vat_json_object_add_uint (node, "load_balance", mp->lb);
2016   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2017   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2018 }
2019
2020 static int
2021 api_sw_interface_bond_dump (vat_main_t * vam)
2022 {
2023   vl_api_sw_interface_bond_dump_t *mp;
2024   vl_api_control_ping_t *mp_ping;
2025   int ret;
2026
2027   print (vam->ofp,
2028          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2029          "interface name", "sw_if_index", "mode", "load balance",
2030          "active slaves", "slaves");
2031
2032   /* Get list of bond interfaces */
2033   M (SW_INTERFACE_BOND_DUMP, mp);
2034   S (mp);
2035
2036   /* Use a control ping for synchronization */
2037   MPING (CONTROL_PING, mp_ping);
2038   S (mp_ping);
2039
2040   W (ret);
2041   return ret;
2042 }
2043
2044 static void vl_api_sw_interface_slave_details_t_handler
2045   (vl_api_sw_interface_slave_details_t * mp)
2046 {
2047   vat_main_t *vam = &vat_main;
2048
2049   print (vam->ofp,
2050          "%-25s %-12d %-12d %d", mp->interface_name,
2051          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2052 }
2053
2054 static void vl_api_sw_interface_slave_details_t_handler_json
2055   (vl_api_sw_interface_slave_details_t * mp)
2056 {
2057   vat_main_t *vam = &vat_main;
2058   vat_json_node_t *node = NULL;
2059
2060   if (VAT_JSON_ARRAY != vam->json_tree.type)
2061     {
2062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2063       vat_json_init_array (&vam->json_tree);
2064     }
2065   node = vat_json_array_add (&vam->json_tree);
2066
2067   vat_json_init_object (node);
2068   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2069   vat_json_object_add_string_copy (node, "interface_name",
2070                                    mp->interface_name);
2071   vat_json_object_add_uint (node, "passive", mp->is_passive);
2072   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2073 }
2074
2075 static int
2076 api_sw_interface_slave_dump (vat_main_t * vam)
2077 {
2078   unformat_input_t *i = vam->input;
2079   vl_api_sw_interface_slave_dump_t *mp;
2080   vl_api_control_ping_t *mp_ping;
2081   u32 sw_if_index = ~0;
2082   u8 sw_if_index_set = 0;
2083   int ret;
2084
2085   /* Parse args required to build the message */
2086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2087     {
2088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2089         sw_if_index_set = 1;
2090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2091         sw_if_index_set = 1;
2092       else
2093         break;
2094     }
2095
2096   if (sw_if_index_set == 0)
2097     {
2098       errmsg ("missing vpp interface name. ");
2099       return -99;
2100     }
2101
2102   print (vam->ofp,
2103          "\n%-25s %-12s %-12s %s",
2104          "slave interface name", "sw_if_index", "passive", "long_timeout");
2105
2106   /* Get list of bond interfaces */
2107   M (SW_INTERFACE_SLAVE_DUMP, mp);
2108   mp->sw_if_index = ntohl (sw_if_index);
2109   S (mp);
2110
2111   /* Use a control ping for synchronization */
2112   MPING (CONTROL_PING, mp_ping);
2113   S (mp_ping);
2114
2115   W (ret);
2116   return ret;
2117 }
2118
2119 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2120   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   i32 retval = ntohl (mp->retval);
2124   if (vam->async_mode)
2125     {
2126       vam->async_errors += (retval < 0);
2127     }
2128   else
2129     {
2130       vam->retval = retval;
2131       vam->sw_if_index = ntohl (mp->sw_if_index);
2132       vam->result_ready = 1;
2133     }
2134   vam->regenerate_interface_table = 1;
2135 }
2136
2137 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2138   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2139 {
2140   vat_main_t *vam = &vat_main;
2141   vat_json_node_t node;
2142
2143   vat_json_init_object (&node);
2144   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2145   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2146                             ntohl (mp->sw_if_index));
2147
2148   vat_json_print (vam->ofp, &node);
2149   vat_json_free (&node);
2150
2151   vam->retval = ntohl (mp->retval);
2152   vam->result_ready = 1;
2153 }
2154
2155 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2156   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2157 {
2158   vat_main_t *vam = &vat_main;
2159   i32 retval = ntohl (mp->retval);
2160   if (vam->async_mode)
2161     {
2162       vam->async_errors += (retval < 0);
2163     }
2164   else
2165     {
2166       vam->retval = retval;
2167       vam->sw_if_index = ntohl (mp->sw_if_index);
2168       vam->result_ready = 1;
2169     }
2170 }
2171
2172 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2173   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2174 {
2175   vat_main_t *vam = &vat_main;
2176   vat_json_node_t node;
2177
2178   vat_json_init_object (&node);
2179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2180   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2181
2182   vat_json_print (vam->ofp, &node);
2183   vat_json_free (&node);
2184
2185   vam->retval = ntohl (mp->retval);
2186   vam->result_ready = 1;
2187 }
2188
2189 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2190   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2191 {
2192   vat_main_t *vam = &vat_main;
2193   i32 retval = ntohl (mp->retval);
2194   if (vam->async_mode)
2195     {
2196       vam->async_errors += (retval < 0);
2197     }
2198   else
2199     {
2200       vam->retval = retval;
2201       vam->result_ready = 1;
2202     }
2203 }
2204
2205 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2206   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2207 {
2208   vat_main_t *vam = &vat_main;
2209   vat_json_node_t node;
2210
2211   vat_json_init_object (&node);
2212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2213   vat_json_object_add_uint (&node, "fwd_entry_index",
2214                             clib_net_to_host_u32 (mp->fwd_entry_index));
2215
2216   vat_json_print (vam->ofp, &node);
2217   vat_json_free (&node);
2218
2219   vam->retval = ntohl (mp->retval);
2220   vam->result_ready = 1;
2221 }
2222
2223 u8 *
2224 format_lisp_transport_protocol (u8 * s, va_list * args)
2225 {
2226   u32 proto = va_arg (*args, u32);
2227
2228   switch (proto)
2229     {
2230     case 1:
2231       return format (s, "udp");
2232     case 2:
2233       return format (s, "api");
2234     default:
2235       return 0;
2236     }
2237   return 0;
2238 }
2239
2240 static void vl_api_one_get_transport_protocol_reply_t_handler
2241   (vl_api_one_get_transport_protocol_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   i32 retval = ntohl (mp->retval);
2245   if (vam->async_mode)
2246     {
2247       vam->async_errors += (retval < 0);
2248     }
2249   else
2250     {
2251       u32 proto = mp->protocol;
2252       print (vam->ofp, "Transport protocol: %U",
2253              format_lisp_transport_protocol, proto);
2254       vam->retval = retval;
2255       vam->result_ready = 1;
2256     }
2257 }
2258
2259 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2260   (vl_api_one_get_transport_protocol_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   vat_json_node_t node;
2264   u8 *s;
2265
2266   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2267   vec_add1 (s, 0);
2268
2269   vat_json_init_object (&node);
2270   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2271   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2272
2273   vec_free (s);
2274   vat_json_print (vam->ofp, &node);
2275   vat_json_free (&node);
2276
2277   vam->retval = ntohl (mp->retval);
2278   vam->result_ready = 1;
2279 }
2280
2281 static void vl_api_one_add_del_locator_set_reply_t_handler
2282   (vl_api_one_add_del_locator_set_reply_t * mp)
2283 {
2284   vat_main_t *vam = &vat_main;
2285   i32 retval = ntohl (mp->retval);
2286   if (vam->async_mode)
2287     {
2288       vam->async_errors += (retval < 0);
2289     }
2290   else
2291     {
2292       vam->retval = retval;
2293       vam->result_ready = 1;
2294     }
2295 }
2296
2297 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2298   (vl_api_one_add_del_locator_set_reply_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301   vat_json_node_t node;
2302
2303   vat_json_init_object (&node);
2304   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2305   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2306
2307   vat_json_print (vam->ofp, &node);
2308   vat_json_free (&node);
2309
2310   vam->retval = ntohl (mp->retval);
2311   vam->result_ready = 1;
2312 }
2313
2314 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2315   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   i32 retval = ntohl (mp->retval);
2319   if (vam->async_mode)
2320     {
2321       vam->async_errors += (retval < 0);
2322     }
2323   else
2324     {
2325       vam->retval = retval;
2326       vam->sw_if_index = ntohl (mp->sw_if_index);
2327       vam->result_ready = 1;
2328     }
2329   vam->regenerate_interface_table = 1;
2330 }
2331
2332 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2333   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2334 {
2335   vat_main_t *vam = &vat_main;
2336   vat_json_node_t node;
2337
2338   vat_json_init_object (&node);
2339   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2340   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2341
2342   vat_json_print (vam->ofp, &node);
2343   vat_json_free (&node);
2344
2345   vam->retval = ntohl (mp->retval);
2346   vam->result_ready = 1;
2347 }
2348
2349 static void vl_api_vxlan_offload_rx_reply_t_handler
2350   (vl_api_vxlan_offload_rx_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   i32 retval = ntohl (mp->retval);
2354   if (vam->async_mode)
2355     {
2356       vam->async_errors += (retval < 0);
2357     }
2358   else
2359     {
2360       vam->retval = retval;
2361       vam->result_ready = 1;
2362     }
2363 }
2364
2365 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2366   (vl_api_vxlan_offload_rx_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373
2374   vat_json_print (vam->ofp, &node);
2375   vat_json_free (&node);
2376
2377   vam->retval = ntohl (mp->retval);
2378   vam->result_ready = 1;
2379 }
2380
2381 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2382   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   i32 retval = ntohl (mp->retval);
2386   if (vam->async_mode)
2387     {
2388       vam->async_errors += (retval < 0);
2389     }
2390   else
2391     {
2392       vam->retval = retval;
2393       vam->sw_if_index = ntohl (mp->sw_if_index);
2394       vam->result_ready = 1;
2395     }
2396 }
2397
2398 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2399   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2407
2408   vat_json_print (vam->ofp, &node);
2409   vat_json_free (&node);
2410
2411   vam->retval = ntohl (mp->retval);
2412   vam->result_ready = 1;
2413 }
2414
2415 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2416   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419   i32 retval = ntohl (mp->retval);
2420   if (vam->async_mode)
2421     {
2422       vam->async_errors += (retval < 0);
2423     }
2424   else
2425     {
2426       vam->retval = retval;
2427       vam->sw_if_index = ntohl (mp->sw_if_index);
2428       vam->result_ready = 1;
2429     }
2430   vam->regenerate_interface_table = 1;
2431 }
2432
2433 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2434   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2435 {
2436   vat_main_t *vam = &vat_main;
2437   vat_json_node_t node;
2438
2439   vat_json_init_object (&node);
2440   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2441   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2442
2443   vat_json_print (vam->ofp, &node);
2444   vat_json_free (&node);
2445
2446   vam->retval = ntohl (mp->retval);
2447   vam->result_ready = 1;
2448 }
2449
2450 static void vl_api_gre_add_del_tunnel_reply_t_handler
2451   (vl_api_gre_add_del_tunnel_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   i32 retval = ntohl (mp->retval);
2455   if (vam->async_mode)
2456     {
2457       vam->async_errors += (retval < 0);
2458     }
2459   else
2460     {
2461       vam->retval = retval;
2462       vam->sw_if_index = ntohl (mp->sw_if_index);
2463       vam->result_ready = 1;
2464     }
2465 }
2466
2467 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2468   (vl_api_gre_add_del_tunnel_reply_t * mp)
2469 {
2470   vat_main_t *vam = &vat_main;
2471   vat_json_node_t node;
2472
2473   vat_json_init_object (&node);
2474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2475   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2476
2477   vat_json_print (vam->ofp, &node);
2478   vat_json_free (&node);
2479
2480   vam->retval = ntohl (mp->retval);
2481   vam->result_ready = 1;
2482 }
2483
2484 static void vl_api_create_vhost_user_if_reply_t_handler
2485   (vl_api_create_vhost_user_if_reply_t * mp)
2486 {
2487   vat_main_t *vam = &vat_main;
2488   i32 retval = ntohl (mp->retval);
2489   if (vam->async_mode)
2490     {
2491       vam->async_errors += (retval < 0);
2492     }
2493   else
2494     {
2495       vam->retval = retval;
2496       vam->sw_if_index = ntohl (mp->sw_if_index);
2497       vam->result_ready = 1;
2498     }
2499   vam->regenerate_interface_table = 1;
2500 }
2501
2502 static void vl_api_create_vhost_user_if_reply_t_handler_json
2503   (vl_api_create_vhost_user_if_reply_t * mp)
2504 {
2505   vat_main_t *vam = &vat_main;
2506   vat_json_node_t node;
2507
2508   vat_json_init_object (&node);
2509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2510   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2511
2512   vat_json_print (vam->ofp, &node);
2513   vat_json_free (&node);
2514
2515   vam->retval = ntohl (mp->retval);
2516   vam->result_ready = 1;
2517 }
2518
2519 static void vl_api_dns_resolve_name_reply_t_handler
2520   (vl_api_dns_resolve_name_reply_t * mp)
2521 {
2522   vat_main_t *vam = &vat_main;
2523   i32 retval = ntohl (mp->retval);
2524   if (vam->async_mode)
2525     {
2526       vam->async_errors += (retval < 0);
2527     }
2528   else
2529     {
2530       vam->retval = retval;
2531       vam->result_ready = 1;
2532
2533       if (retval == 0)
2534         {
2535           if (mp->ip4_set)
2536             clib_warning ("ip4 address %U", format_ip4_address,
2537                           (ip4_address_t *) mp->ip4_address);
2538           if (mp->ip6_set)
2539             clib_warning ("ip6 address %U", format_ip6_address,
2540                           (ip6_address_t *) mp->ip6_address);
2541         }
2542       else
2543         clib_warning ("retval %d", retval);
2544     }
2545 }
2546
2547 static void vl_api_dns_resolve_name_reply_t_handler_json
2548   (vl_api_dns_resolve_name_reply_t * mp)
2549 {
2550   clib_warning ("not implemented");
2551 }
2552
2553 static void vl_api_dns_resolve_ip_reply_t_handler
2554   (vl_api_dns_resolve_ip_reply_t * mp)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   i32 retval = ntohl (mp->retval);
2558   if (vam->async_mode)
2559     {
2560       vam->async_errors += (retval < 0);
2561     }
2562   else
2563     {
2564       vam->retval = retval;
2565       vam->result_ready = 1;
2566
2567       if (retval == 0)
2568         {
2569           clib_warning ("canonical name %s", mp->name);
2570         }
2571       else
2572         clib_warning ("retval %d", retval);
2573     }
2574 }
2575
2576 static void vl_api_dns_resolve_ip_reply_t_handler_json
2577   (vl_api_dns_resolve_ip_reply_t * mp)
2578 {
2579   clib_warning ("not implemented");
2580 }
2581
2582
2583 static void vl_api_ip_address_details_t_handler
2584   (vl_api_ip_address_details_t * mp)
2585 {
2586   vat_main_t *vam = &vat_main;
2587   static ip_address_details_t empty_ip_address_details = { {0} };
2588   ip_address_details_t *address = NULL;
2589   ip_details_t *current_ip_details = NULL;
2590   ip_details_t *details = NULL;
2591
2592   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2593
2594   if (!details || vam->current_sw_if_index >= vec_len (details)
2595       || !details[vam->current_sw_if_index].present)
2596     {
2597       errmsg ("ip address details arrived but not stored");
2598       errmsg ("ip_dump should be called first");
2599       return;
2600     }
2601
2602   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2603
2604 #define addresses (current_ip_details->addr)
2605
2606   vec_validate_init_empty (addresses, vec_len (addresses),
2607                            empty_ip_address_details);
2608
2609   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2610
2611   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2612   address->prefix_length = mp->prefix_length;
2613 #undef addresses
2614 }
2615
2616 static void vl_api_ip_address_details_t_handler_json
2617   (vl_api_ip_address_details_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620   vat_json_node_t *node = NULL;
2621   struct in6_addr ip6;
2622   struct in_addr ip4;
2623
2624   if (VAT_JSON_ARRAY != vam->json_tree.type)
2625     {
2626       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2627       vat_json_init_array (&vam->json_tree);
2628     }
2629   node = vat_json_array_add (&vam->json_tree);
2630
2631   vat_json_init_object (node);
2632   if (vam->is_ipv6)
2633     {
2634       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2635       vat_json_object_add_ip6 (node, "ip", ip6);
2636     }
2637   else
2638     {
2639       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2640       vat_json_object_add_ip4 (node, "ip", ip4);
2641     }
2642   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2643 }
2644
2645 static void
2646 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649   static ip_details_t empty_ip_details = { 0 };
2650   ip_details_t *ip = NULL;
2651   u32 sw_if_index = ~0;
2652
2653   sw_if_index = ntohl (mp->sw_if_index);
2654
2655   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2656                            sw_if_index, empty_ip_details);
2657
2658   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2659                          sw_if_index);
2660
2661   ip->present = 1;
2662 }
2663
2664 static void
2665 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668
2669   if (VAT_JSON_ARRAY != vam->json_tree.type)
2670     {
2671       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2672       vat_json_init_array (&vam->json_tree);
2673     }
2674   vat_json_array_add_uint (&vam->json_tree,
2675                            clib_net_to_host_u32 (mp->sw_if_index));
2676 }
2677
2678 static void
2679 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2680 {
2681   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2682           "router_addr %U host_mac %U",
2683           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2684           mp->lease.hostname,
2685           format_ip4_address, &mp->lease.host_address,
2686           format_ip4_address, &mp->lease.router_address,
2687           format_ethernet_address, mp->lease.host_mac);
2688 }
2689
2690 static void vl_api_dhcp_compl_event_t_handler_json
2691   (vl_api_dhcp_compl_event_t * mp)
2692 {
2693   /* JSON output not supported */
2694 }
2695
2696 static void vl_api_get_first_msg_id_reply_t_handler
2697   (vl_api_get_first_msg_id_reply_t * mp)
2698 {
2699   vat_main_t *vam = &vat_main;
2700   i32 retval = ntohl (mp->retval);
2701
2702   if (vam->async_mode)
2703     {
2704       vam->async_errors += (retval < 0);
2705     }
2706   else
2707     {
2708       vam->retval = retval;
2709       vam->result_ready = 1;
2710     }
2711   if (retval >= 0)
2712     {
2713       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2714     }
2715 }
2716
2717 static void vl_api_get_first_msg_id_reply_t_handler_json
2718   (vl_api_get_first_msg_id_reply_t * mp)
2719 {
2720   vat_main_t *vam = &vat_main;
2721   vat_json_node_t node;
2722
2723   vat_json_init_object (&node);
2724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2725   vat_json_object_add_uint (&node, "first_msg_id",
2726                             (uint) ntohs (mp->first_msg_id));
2727
2728   vat_json_print (vam->ofp, &node);
2729   vat_json_free (&node);
2730
2731   vam->retval = ntohl (mp->retval);
2732   vam->result_ready = 1;
2733 }
2734
2735 static void vl_api_get_node_graph_reply_t_handler
2736   (vl_api_get_node_graph_reply_t * mp)
2737 {
2738   vat_main_t *vam = &vat_main;
2739   api_main_t *am = &api_main;
2740   i32 retval = ntohl (mp->retval);
2741   u8 *pvt_copy, *reply;
2742   void *oldheap;
2743   vlib_node_t *node;
2744   int i;
2745
2746   if (vam->async_mode)
2747     {
2748       vam->async_errors += (retval < 0);
2749     }
2750   else
2751     {
2752       vam->retval = retval;
2753       vam->result_ready = 1;
2754     }
2755
2756   /* "Should never happen..." */
2757   if (retval != 0)
2758     return;
2759
2760   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2761   pvt_copy = vec_dup (reply);
2762
2763   /* Toss the shared-memory original... */
2764   pthread_mutex_lock (&am->vlib_rp->mutex);
2765   oldheap = svm_push_data_heap (am->vlib_rp);
2766
2767   vec_free (reply);
2768
2769   svm_pop_heap (oldheap);
2770   pthread_mutex_unlock (&am->vlib_rp->mutex);
2771
2772   if (vam->graph_nodes)
2773     {
2774       hash_free (vam->graph_node_index_by_name);
2775
2776       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2777         {
2778           node = vam->graph_nodes[0][i];
2779           vec_free (node->name);
2780           vec_free (node->next_nodes);
2781           vec_free (node);
2782         }
2783       vec_free (vam->graph_nodes[0]);
2784       vec_free (vam->graph_nodes);
2785     }
2786
2787   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2788   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2789   vec_free (pvt_copy);
2790
2791   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2792     {
2793       node = vam->graph_nodes[0][i];
2794       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2795     }
2796 }
2797
2798 static void vl_api_get_node_graph_reply_t_handler_json
2799   (vl_api_get_node_graph_reply_t * mp)
2800 {
2801   vat_main_t *vam = &vat_main;
2802   api_main_t *am = &api_main;
2803   void *oldheap;
2804   vat_json_node_t node;
2805   u8 *reply;
2806
2807   /* $$$$ make this real? */
2808   vat_json_init_object (&node);
2809   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2810   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2811
2812   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2813
2814   /* Toss the shared-memory original... */
2815   pthread_mutex_lock (&am->vlib_rp->mutex);
2816   oldheap = svm_push_data_heap (am->vlib_rp);
2817
2818   vec_free (reply);
2819
2820   svm_pop_heap (oldheap);
2821   pthread_mutex_unlock (&am->vlib_rp->mutex);
2822
2823   vat_json_print (vam->ofp, &node);
2824   vat_json_free (&node);
2825
2826   vam->retval = ntohl (mp->retval);
2827   vam->result_ready = 1;
2828 }
2829
2830 static void
2831 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2832 {
2833   vat_main_t *vam = &vat_main;
2834   u8 *s = 0;
2835
2836   if (mp->local)
2837     {
2838       s = format (s, "%=16d%=16d%=16d",
2839                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2840     }
2841   else
2842     {
2843       s = format (s, "%=16U%=16d%=16d",
2844                   mp->is_ipv6 ? format_ip6_address :
2845                   format_ip4_address,
2846                   mp->ip_address, mp->priority, mp->weight);
2847     }
2848
2849   print (vam->ofp, "%v", s);
2850   vec_free (s);
2851 }
2852
2853 static void
2854 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   vat_json_node_t *node = NULL;
2858   struct in6_addr ip6;
2859   struct in_addr ip4;
2860
2861   if (VAT_JSON_ARRAY != vam->json_tree.type)
2862     {
2863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2864       vat_json_init_array (&vam->json_tree);
2865     }
2866   node = vat_json_array_add (&vam->json_tree);
2867   vat_json_init_object (node);
2868
2869   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2870   vat_json_object_add_uint (node, "priority", mp->priority);
2871   vat_json_object_add_uint (node, "weight", mp->weight);
2872
2873   if (mp->local)
2874     vat_json_object_add_uint (node, "sw_if_index",
2875                               clib_net_to_host_u32 (mp->sw_if_index));
2876   else
2877     {
2878       if (mp->is_ipv6)
2879         {
2880           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2881           vat_json_object_add_ip6 (node, "address", ip6);
2882         }
2883       else
2884         {
2885           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2886           vat_json_object_add_ip4 (node, "address", ip4);
2887         }
2888     }
2889 }
2890
2891 static void
2892 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2893                                           mp)
2894 {
2895   vat_main_t *vam = &vat_main;
2896   u8 *ls_name = 0;
2897
2898   ls_name = format (0, "%s", mp->ls_name);
2899
2900   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2901          ls_name);
2902   vec_free (ls_name);
2903 }
2904
2905 static void
2906   vl_api_one_locator_set_details_t_handler_json
2907   (vl_api_one_locator_set_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910   vat_json_node_t *node = 0;
2911   u8 *ls_name = 0;
2912
2913   ls_name = format (0, "%s", mp->ls_name);
2914   vec_add1 (ls_name, 0);
2915
2916   if (VAT_JSON_ARRAY != vam->json_tree.type)
2917     {
2918       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2919       vat_json_init_array (&vam->json_tree);
2920     }
2921   node = vat_json_array_add (&vam->json_tree);
2922
2923   vat_json_init_object (node);
2924   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2925   vat_json_object_add_uint (node, "ls_index",
2926                             clib_net_to_host_u32 (mp->ls_index));
2927   vec_free (ls_name);
2928 }
2929
2930 typedef struct
2931 {
2932   u32 spi;
2933   u8 si;
2934 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2935
2936 uword
2937 unformat_nsh_address (unformat_input_t * input, va_list * args)
2938 {
2939   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2940   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2941 }
2942
2943 u8 *
2944 format_nsh_address_vat (u8 * s, va_list * args)
2945 {
2946   nsh_t *a = va_arg (*args, nsh_t *);
2947   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2948 }
2949
2950 static u8 *
2951 format_lisp_flat_eid (u8 * s, va_list * args)
2952 {
2953   u32 type = va_arg (*args, u32);
2954   u8 *eid = va_arg (*args, u8 *);
2955   u32 eid_len = va_arg (*args, u32);
2956
2957   switch (type)
2958     {
2959     case 0:
2960       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2961     case 1:
2962       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2963     case 2:
2964       return format (s, "%U", format_ethernet_address, eid);
2965     case 3:
2966       return format (s, "%U", format_nsh_address_vat, eid);
2967     }
2968   return 0;
2969 }
2970
2971 static u8 *
2972 format_lisp_eid_vat (u8 * s, va_list * args)
2973 {
2974   u32 type = va_arg (*args, u32);
2975   u8 *eid = va_arg (*args, u8 *);
2976   u32 eid_len = va_arg (*args, u32);
2977   u8 *seid = va_arg (*args, u8 *);
2978   u32 seid_len = va_arg (*args, u32);
2979   u32 is_src_dst = va_arg (*args, u32);
2980
2981   if (is_src_dst)
2982     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2983
2984   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2985
2986   return s;
2987 }
2988
2989 static void
2990 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   u8 *s = 0, *eid = 0;
2994
2995   if (~0 == mp->locator_set_index)
2996     s = format (0, "action: %d", mp->action);
2997   else
2998     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2999
3000   eid = format (0, "%U", format_lisp_eid_vat,
3001                 mp->eid_type,
3002                 mp->eid,
3003                 mp->eid_prefix_len,
3004                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3005   vec_add1 (eid, 0);
3006
3007   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3008          clib_net_to_host_u32 (mp->vni),
3009          eid,
3010          mp->is_local ? "local" : "remote",
3011          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3012          clib_net_to_host_u16 (mp->key_id), mp->key);
3013
3014   vec_free (s);
3015   vec_free (eid);
3016 }
3017
3018 static void
3019 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3020                                              * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   vat_json_node_t *node = 0;
3024   u8 *eid = 0;
3025
3026   if (VAT_JSON_ARRAY != vam->json_tree.type)
3027     {
3028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3029       vat_json_init_array (&vam->json_tree);
3030     }
3031   node = vat_json_array_add (&vam->json_tree);
3032
3033   vat_json_init_object (node);
3034   if (~0 == mp->locator_set_index)
3035     vat_json_object_add_uint (node, "action", mp->action);
3036   else
3037     vat_json_object_add_uint (node, "locator_set_index",
3038                               clib_net_to_host_u32 (mp->locator_set_index));
3039
3040   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3041   if (mp->eid_type == 3)
3042     {
3043       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3044       vat_json_init_object (nsh_json);
3045       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3046       vat_json_object_add_uint (nsh_json, "spi",
3047                                 clib_net_to_host_u32 (nsh->spi));
3048       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3049     }
3050   else
3051     {
3052       eid = format (0, "%U", format_lisp_eid_vat,
3053                     mp->eid_type,
3054                     mp->eid,
3055                     mp->eid_prefix_len,
3056                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3057       vec_add1 (eid, 0);
3058       vat_json_object_add_string_copy (node, "eid", eid);
3059       vec_free (eid);
3060     }
3061   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3062   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3063   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3064
3065   if (mp->key_id)
3066     {
3067       vat_json_object_add_uint (node, "key_id",
3068                                 clib_net_to_host_u16 (mp->key_id));
3069       vat_json_object_add_string_copy (node, "key", mp->key);
3070     }
3071 }
3072
3073 static void
3074 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3075 {
3076   vat_main_t *vam = &vat_main;
3077   u8 *seid = 0, *deid = 0;
3078   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3079
3080   deid = format (0, "%U", format_lisp_eid_vat,
3081                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3082
3083   seid = format (0, "%U", format_lisp_eid_vat,
3084                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3085
3086   vec_add1 (deid, 0);
3087   vec_add1 (seid, 0);
3088
3089   if (mp->is_ip4)
3090     format_ip_address_fcn = format_ip4_address;
3091   else
3092     format_ip_address_fcn = format_ip6_address;
3093
3094
3095   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3096          clib_net_to_host_u32 (mp->vni),
3097          seid, deid,
3098          format_ip_address_fcn, mp->lloc,
3099          format_ip_address_fcn, mp->rloc,
3100          clib_net_to_host_u32 (mp->pkt_count),
3101          clib_net_to_host_u32 (mp->bytes));
3102
3103   vec_free (deid);
3104   vec_free (seid);
3105 }
3106
3107 static void
3108 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3109 {
3110   struct in6_addr ip6;
3111   struct in_addr ip4;
3112   vat_main_t *vam = &vat_main;
3113   vat_json_node_t *node = 0;
3114   u8 *deid = 0, *seid = 0;
3115
3116   if (VAT_JSON_ARRAY != vam->json_tree.type)
3117     {
3118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3119       vat_json_init_array (&vam->json_tree);
3120     }
3121   node = vat_json_array_add (&vam->json_tree);
3122
3123   vat_json_init_object (node);
3124   deid = format (0, "%U", format_lisp_eid_vat,
3125                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3126
3127   seid = format (0, "%U", format_lisp_eid_vat,
3128                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3129
3130   vec_add1 (deid, 0);
3131   vec_add1 (seid, 0);
3132
3133   vat_json_object_add_string_copy (node, "seid", seid);
3134   vat_json_object_add_string_copy (node, "deid", deid);
3135   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3136
3137   if (mp->is_ip4)
3138     {
3139       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3140       vat_json_object_add_ip4 (node, "lloc", ip4);
3141       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3142       vat_json_object_add_ip4 (node, "rloc", ip4);
3143     }
3144   else
3145     {
3146       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3147       vat_json_object_add_ip6 (node, "lloc", ip6);
3148       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3149       vat_json_object_add_ip6 (node, "rloc", ip6);
3150     }
3151   vat_json_object_add_uint (node, "pkt_count",
3152                             clib_net_to_host_u32 (mp->pkt_count));
3153   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3154
3155   vec_free (deid);
3156   vec_free (seid);
3157 }
3158
3159 static void
3160   vl_api_one_eid_table_map_details_t_handler
3161   (vl_api_one_eid_table_map_details_t * mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164
3165   u8 *line = format (0, "%=10d%=10d",
3166                      clib_net_to_host_u32 (mp->vni),
3167                      clib_net_to_host_u32 (mp->dp_table));
3168   print (vam->ofp, "%v", line);
3169   vec_free (line);
3170 }
3171
3172 static void
3173   vl_api_one_eid_table_map_details_t_handler_json
3174   (vl_api_one_eid_table_map_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *node = NULL;
3178
3179   if (VAT_JSON_ARRAY != vam->json_tree.type)
3180     {
3181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3182       vat_json_init_array (&vam->json_tree);
3183     }
3184   node = vat_json_array_add (&vam->json_tree);
3185   vat_json_init_object (node);
3186   vat_json_object_add_uint (node, "dp_table",
3187                             clib_net_to_host_u32 (mp->dp_table));
3188   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3189 }
3190
3191 static void
3192   vl_api_one_eid_table_vni_details_t_handler
3193   (vl_api_one_eid_table_vni_details_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196
3197   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3198   print (vam->ofp, "%v", line);
3199   vec_free (line);
3200 }
3201
3202 static void
3203   vl_api_one_eid_table_vni_details_t_handler_json
3204   (vl_api_one_eid_table_vni_details_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t *node = NULL;
3208
3209   if (VAT_JSON_ARRAY != vam->json_tree.type)
3210     {
3211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3212       vat_json_init_array (&vam->json_tree);
3213     }
3214   node = vat_json_array_add (&vam->json_tree);
3215   vat_json_init_object (node);
3216   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3217 }
3218
3219 static void
3220   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3221   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   int retval = clib_net_to_host_u32 (mp->retval);
3225
3226   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3227   print (vam->ofp, "fallback threshold value: %d", mp->value);
3228
3229   vam->retval = retval;
3230   vam->result_ready = 1;
3231 }
3232
3233 static void
3234   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3235   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3236 {
3237   vat_main_t *vam = &vat_main;
3238   vat_json_node_t _node, *node = &_node;
3239   int retval = clib_net_to_host_u32 (mp->retval);
3240
3241   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3242   vat_json_init_object (node);
3243   vat_json_object_add_uint (node, "value", mp->value);
3244
3245   vat_json_print (vam->ofp, node);
3246   vat_json_free (node);
3247
3248   vam->retval = retval;
3249   vam->result_ready = 1;
3250 }
3251
3252 static void
3253   vl_api_show_one_map_register_state_reply_t_handler
3254   (vl_api_show_one_map_register_state_reply_t * mp)
3255 {
3256   vat_main_t *vam = &vat_main;
3257   int retval = clib_net_to_host_u32 (mp->retval);
3258
3259   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3260
3261   vam->retval = retval;
3262   vam->result_ready = 1;
3263 }
3264
3265 static void
3266   vl_api_show_one_map_register_state_reply_t_handler_json
3267   (vl_api_show_one_map_register_state_reply_t * mp)
3268 {
3269   vat_main_t *vam = &vat_main;
3270   vat_json_node_t _node, *node = &_node;
3271   int retval = clib_net_to_host_u32 (mp->retval);
3272
3273   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3274
3275   vat_json_init_object (node);
3276   vat_json_object_add_string_copy (node, "state", s);
3277
3278   vat_json_print (vam->ofp, node);
3279   vat_json_free (node);
3280
3281   vam->retval = retval;
3282   vam->result_ready = 1;
3283   vec_free (s);
3284 }
3285
3286 static void
3287   vl_api_show_one_rloc_probe_state_reply_t_handler
3288   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   int retval = clib_net_to_host_u32 (mp->retval);
3292
3293   if (retval)
3294     goto end;
3295
3296   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3297 end:
3298   vam->retval = retval;
3299   vam->result_ready = 1;
3300 }
3301
3302 static void
3303   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3304   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307   vat_json_node_t _node, *node = &_node;
3308   int retval = clib_net_to_host_u32 (mp->retval);
3309
3310   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3311   vat_json_init_object (node);
3312   vat_json_object_add_string_copy (node, "state", s);
3313
3314   vat_json_print (vam->ofp, node);
3315   vat_json_free (node);
3316
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319   vec_free (s);
3320 }
3321
3322 static void
3323   vl_api_show_one_stats_enable_disable_reply_t_handler
3324   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3325 {
3326   vat_main_t *vam = &vat_main;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   if (retval)
3330     goto end;
3331
3332   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3333 end:
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3340   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t _node, *node = &_node;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3347   vat_json_init_object (node);
3348   vat_json_object_add_string_copy (node, "state", s);
3349
3350   vat_json_print (vam->ofp, node);
3351   vat_json_free (node);
3352
3353   vam->retval = retval;
3354   vam->result_ready = 1;
3355   vec_free (s);
3356 }
3357
3358 static void
3359 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3360 {
3361   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3362   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3363   e->vni = clib_net_to_host_u32 (e->vni);
3364 }
3365
3366 static void
3367   gpe_fwd_entries_get_reply_t_net_to_host
3368   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3369 {
3370   u32 i;
3371
3372   mp->count = clib_net_to_host_u32 (mp->count);
3373   for (i = 0; i < mp->count; i++)
3374     {
3375       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3376     }
3377 }
3378
3379 static u8 *
3380 format_gpe_encap_mode (u8 * s, va_list * args)
3381 {
3382   u32 mode = va_arg (*args, u32);
3383
3384   switch (mode)
3385     {
3386     case 0:
3387       return format (s, "lisp");
3388     case 1:
3389       return format (s, "vxlan");
3390     }
3391   return 0;
3392 }
3393
3394 static void
3395   vl_api_gpe_get_encap_mode_reply_t_handler
3396   (vl_api_gpe_get_encap_mode_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399
3400   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3401   vam->retval = ntohl (mp->retval);
3402   vam->result_ready = 1;
3403 }
3404
3405 static void
3406   vl_api_gpe_get_encap_mode_reply_t_handler_json
3407   (vl_api_gpe_get_encap_mode_reply_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   vat_json_node_t node;
3411
3412   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3413   vec_add1 (encap_mode, 0);
3414
3415   vat_json_init_object (&node);
3416   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3417
3418   vec_free (encap_mode);
3419   vat_json_print (vam->ofp, &node);
3420   vat_json_free (&node);
3421
3422   vam->retval = ntohl (mp->retval);
3423   vam->result_ready = 1;
3424 }
3425
3426 static void
3427   vl_api_gpe_fwd_entry_path_details_t_handler
3428   (vl_api_gpe_fwd_entry_path_details_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3432
3433   if (mp->lcl_loc.is_ip4)
3434     format_ip_address_fcn = format_ip4_address;
3435   else
3436     format_ip_address_fcn = format_ip6_address;
3437
3438   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3439          format_ip_address_fcn, &mp->lcl_loc,
3440          format_ip_address_fcn, &mp->rmt_loc);
3441 }
3442
3443 static void
3444 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3445 {
3446   struct in6_addr ip6;
3447   struct in_addr ip4;
3448
3449   if (loc->is_ip4)
3450     {
3451       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3452       vat_json_object_add_ip4 (n, "address", ip4);
3453     }
3454   else
3455     {
3456       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3457       vat_json_object_add_ip6 (n, "address", ip6);
3458     }
3459   vat_json_object_add_uint (n, "weight", loc->weight);
3460 }
3461
3462 static void
3463   vl_api_gpe_fwd_entry_path_details_t_handler_json
3464   (vl_api_gpe_fwd_entry_path_details_t * mp)
3465 {
3466   vat_main_t *vam = &vat_main;
3467   vat_json_node_t *node = NULL;
3468   vat_json_node_t *loc_node;
3469
3470   if (VAT_JSON_ARRAY != vam->json_tree.type)
3471     {
3472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3473       vat_json_init_array (&vam->json_tree);
3474     }
3475   node = vat_json_array_add (&vam->json_tree);
3476   vat_json_init_object (node);
3477
3478   loc_node = vat_json_object_add (node, "local_locator");
3479   vat_json_init_object (loc_node);
3480   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3481
3482   loc_node = vat_json_object_add (node, "remote_locator");
3483   vat_json_init_object (loc_node);
3484   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3485 }
3486
3487 static void
3488   vl_api_gpe_fwd_entries_get_reply_t_handler
3489   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3490 {
3491   vat_main_t *vam = &vat_main;
3492   u32 i;
3493   int retval = clib_net_to_host_u32 (mp->retval);
3494   vl_api_gpe_fwd_entry_t *e;
3495
3496   if (retval)
3497     goto end;
3498
3499   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3500
3501   for (i = 0; i < mp->count; i++)
3502     {
3503       e = &mp->entries[i];
3504       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3505              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3506              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3507     }
3508
3509 end:
3510   vam->retval = retval;
3511   vam->result_ready = 1;
3512 }
3513
3514 static void
3515   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3516   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3517 {
3518   u8 *s = 0;
3519   vat_main_t *vam = &vat_main;
3520   vat_json_node_t *e = 0, root;
3521   u32 i;
3522   int retval = clib_net_to_host_u32 (mp->retval);
3523   vl_api_gpe_fwd_entry_t *fwd;
3524
3525   if (retval)
3526     goto end;
3527
3528   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3529   vat_json_init_array (&root);
3530
3531   for (i = 0; i < mp->count; i++)
3532     {
3533       e = vat_json_array_add (&root);
3534       fwd = &mp->entries[i];
3535
3536       vat_json_init_object (e);
3537       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3538       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3539       vat_json_object_add_int (e, "vni", fwd->vni);
3540       vat_json_object_add_int (e, "action", fwd->action);
3541
3542       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3543                   fwd->leid_prefix_len);
3544       vec_add1 (s, 0);
3545       vat_json_object_add_string_copy (e, "leid", s);
3546       vec_free (s);
3547
3548       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3549                   fwd->reid_prefix_len);
3550       vec_add1 (s, 0);
3551       vat_json_object_add_string_copy (e, "reid", s);
3552       vec_free (s);
3553     }
3554
3555   vat_json_print (vam->ofp, &root);
3556   vat_json_free (&root);
3557
3558 end:
3559   vam->retval = retval;
3560   vam->result_ready = 1;
3561 }
3562
3563 static void
3564   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3565   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3566 {
3567   vat_main_t *vam = &vat_main;
3568   u32 i, n;
3569   int retval = clib_net_to_host_u32 (mp->retval);
3570   vl_api_gpe_native_fwd_rpath_t *r;
3571
3572   if (retval)
3573     goto end;
3574
3575   n = clib_net_to_host_u32 (mp->count);
3576
3577   for (i = 0; i < n; i++)
3578     {
3579       r = &mp->entries[i];
3580       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3581              clib_net_to_host_u32 (r->fib_index),
3582              clib_net_to_host_u32 (r->nh_sw_if_index),
3583              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3584     }
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_json
3593   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   vat_json_node_t root, *e;
3597   u32 i, n;
3598   int retval = clib_net_to_host_u32 (mp->retval);
3599   vl_api_gpe_native_fwd_rpath_t *r;
3600   u8 *s;
3601
3602   if (retval)
3603     goto end;
3604
3605   n = clib_net_to_host_u32 (mp->count);
3606   vat_json_init_array (&root);
3607
3608   for (i = 0; i < n; i++)
3609     {
3610       e = vat_json_array_add (&root);
3611       vat_json_init_object (e);
3612       r = &mp->entries[i];
3613       s =
3614         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3615                 r->nh_addr);
3616       vec_add1 (s, 0);
3617       vat_json_object_add_string_copy (e, "ip4", s);
3618       vec_free (s);
3619
3620       vat_json_object_add_uint (e, "fib_index",
3621                                 clib_net_to_host_u32 (r->fib_index));
3622       vat_json_object_add_uint (e, "nh_sw_if_index",
3623                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3624     }
3625
3626   vat_json_print (vam->ofp, &root);
3627   vat_json_free (&root);
3628
3629 end:
3630   vam->retval = retval;
3631   vam->result_ready = 1;
3632 }
3633
3634 static void
3635   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3636   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3637 {
3638   vat_main_t *vam = &vat_main;
3639   u32 i, n;
3640   int retval = clib_net_to_host_u32 (mp->retval);
3641
3642   if (retval)
3643     goto end;
3644
3645   n = clib_net_to_host_u32 (mp->count);
3646
3647   for (i = 0; i < n; i++)
3648     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3649
3650 end:
3651   vam->retval = retval;
3652   vam->result_ready = 1;
3653 }
3654
3655 static void
3656   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3657   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   vat_json_node_t root;
3661   u32 i, n;
3662   int retval = clib_net_to_host_u32 (mp->retval);
3663
3664   if (retval)
3665     goto end;
3666
3667   n = clib_net_to_host_u32 (mp->count);
3668   vat_json_init_array (&root);
3669
3670   for (i = 0; i < n; i++)
3671     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3672
3673   vat_json_print (vam->ofp, &root);
3674   vat_json_free (&root);
3675
3676 end:
3677   vam->retval = retval;
3678   vam->result_ready = 1;
3679 }
3680
3681 static void
3682   vl_api_one_ndp_entries_get_reply_t_handler
3683   (vl_api_one_ndp_entries_get_reply_t * mp)
3684 {
3685   vat_main_t *vam = &vat_main;
3686   u32 i, n;
3687   int retval = clib_net_to_host_u32 (mp->retval);
3688
3689   if (retval)
3690     goto end;
3691
3692   n = clib_net_to_host_u32 (mp->count);
3693
3694   for (i = 0; i < n; i++)
3695     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3696            format_ethernet_address, mp->entries[i].mac);
3697
3698 end:
3699   vam->retval = retval;
3700   vam->result_ready = 1;
3701 }
3702
3703 static void
3704   vl_api_one_ndp_entries_get_reply_t_handler_json
3705   (vl_api_one_ndp_entries_get_reply_t * mp)
3706 {
3707   u8 *s = 0;
3708   vat_main_t *vam = &vat_main;
3709   vat_json_node_t *e = 0, root;
3710   u32 i, n;
3711   int retval = clib_net_to_host_u32 (mp->retval);
3712   vl_api_one_ndp_entry_t *arp_entry;
3713
3714   if (retval)
3715     goto end;
3716
3717   n = clib_net_to_host_u32 (mp->count);
3718   vat_json_init_array (&root);
3719
3720   for (i = 0; i < n; i++)
3721     {
3722       e = vat_json_array_add (&root);
3723       arp_entry = &mp->entries[i];
3724
3725       vat_json_init_object (e);
3726       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3727       vec_add1 (s, 0);
3728
3729       vat_json_object_add_string_copy (e, "mac", s);
3730       vec_free (s);
3731
3732       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3733       vec_add1 (s, 0);
3734       vat_json_object_add_string_copy (e, "ip6", s);
3735       vec_free (s);
3736     }
3737
3738   vat_json_print (vam->ofp, &root);
3739   vat_json_free (&root);
3740
3741 end:
3742   vam->retval = retval;
3743   vam->result_ready = 1;
3744 }
3745
3746 static void
3747   vl_api_one_l2_arp_entries_get_reply_t_handler
3748   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3749 {
3750   vat_main_t *vam = &vat_main;
3751   u32 i, n;
3752   int retval = clib_net_to_host_u32 (mp->retval);
3753
3754   if (retval)
3755     goto end;
3756
3757   n = clib_net_to_host_u32 (mp->count);
3758
3759   for (i = 0; i < n; i++)
3760     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3761            format_ethernet_address, mp->entries[i].mac);
3762
3763 end:
3764   vam->retval = retval;
3765   vam->result_ready = 1;
3766 }
3767
3768 static void
3769   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3770   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3771 {
3772   u8 *s = 0;
3773   vat_main_t *vam = &vat_main;
3774   vat_json_node_t *e = 0, root;
3775   u32 i, n;
3776   int retval = clib_net_to_host_u32 (mp->retval);
3777   vl_api_one_l2_arp_entry_t *arp_entry;
3778
3779   if (retval)
3780     goto end;
3781
3782   n = clib_net_to_host_u32 (mp->count);
3783   vat_json_init_array (&root);
3784
3785   for (i = 0; i < n; i++)
3786     {
3787       e = vat_json_array_add (&root);
3788       arp_entry = &mp->entries[i];
3789
3790       vat_json_init_object (e);
3791       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3792       vec_add1 (s, 0);
3793
3794       vat_json_object_add_string_copy (e, "mac", s);
3795       vec_free (s);
3796
3797       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3798       vec_add1 (s, 0);
3799       vat_json_object_add_string_copy (e, "ip4", s);
3800       vec_free (s);
3801     }
3802
3803   vat_json_print (vam->ofp, &root);
3804   vat_json_free (&root);
3805
3806 end:
3807   vam->retval = retval;
3808   vam->result_ready = 1;
3809 }
3810
3811 static void
3812 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3813 {
3814   vat_main_t *vam = &vat_main;
3815   u32 i, n;
3816   int retval = clib_net_to_host_u32 (mp->retval);
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822
3823   for (i = 0; i < n; i++)
3824     {
3825       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3826     }
3827
3828 end:
3829   vam->retval = retval;
3830   vam->result_ready = 1;
3831 }
3832
3833 static void
3834   vl_api_one_ndp_bd_get_reply_t_handler_json
3835   (vl_api_one_ndp_bd_get_reply_t * mp)
3836 {
3837   vat_main_t *vam = &vat_main;
3838   vat_json_node_t root;
3839   u32 i, n;
3840   int retval = clib_net_to_host_u32 (mp->retval);
3841
3842   if (retval)
3843     goto end;
3844
3845   n = clib_net_to_host_u32 (mp->count);
3846   vat_json_init_array (&root);
3847
3848   for (i = 0; i < n; i++)
3849     {
3850       vat_json_array_add_uint (&root,
3851                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3852     }
3853
3854   vat_json_print (vam->ofp, &root);
3855   vat_json_free (&root);
3856
3857 end:
3858   vam->retval = retval;
3859   vam->result_ready = 1;
3860 }
3861
3862 static void
3863   vl_api_one_l2_arp_bd_get_reply_t_handler
3864   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
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
3875   for (i = 0; i < n; i++)
3876     {
3877       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3878     }
3879
3880 end:
3881   vam->retval = retval;
3882   vam->result_ready = 1;
3883 }
3884
3885 static void
3886   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3887   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3888 {
3889   vat_main_t *vam = &vat_main;
3890   vat_json_node_t root;
3891   u32 i, n;
3892   int retval = clib_net_to_host_u32 (mp->retval);
3893
3894   if (retval)
3895     goto end;
3896
3897   n = clib_net_to_host_u32 (mp->count);
3898   vat_json_init_array (&root);
3899
3900   for (i = 0; i < n; i++)
3901     {
3902       vat_json_array_add_uint (&root,
3903                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3904     }
3905
3906   vat_json_print (vam->ofp, &root);
3907   vat_json_free (&root);
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915   vl_api_one_adjacencies_get_reply_t_handler
3916   (vl_api_one_adjacencies_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921   vl_api_one_adjacency_t *a;
3922
3923   if (retval)
3924     goto end;
3925
3926   n = clib_net_to_host_u32 (mp->count);
3927
3928   for (i = 0; i < n; i++)
3929     {
3930       a = &mp->adjacencies[i];
3931       print (vam->ofp, "%U %40U",
3932              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3933              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3934     }
3935
3936 end:
3937   vam->retval = retval;
3938   vam->result_ready = 1;
3939 }
3940
3941 static void
3942   vl_api_one_adjacencies_get_reply_t_handler_json
3943   (vl_api_one_adjacencies_get_reply_t * mp)
3944 {
3945   u8 *s = 0;
3946   vat_main_t *vam = &vat_main;
3947   vat_json_node_t *e = 0, root;
3948   u32 i, n;
3949   int retval = clib_net_to_host_u32 (mp->retval);
3950   vl_api_one_adjacency_t *a;
3951
3952   if (retval)
3953     goto end;
3954
3955   n = clib_net_to_host_u32 (mp->count);
3956   vat_json_init_array (&root);
3957
3958   for (i = 0; i < n; i++)
3959     {
3960       e = vat_json_array_add (&root);
3961       a = &mp->adjacencies[i];
3962
3963       vat_json_init_object (e);
3964       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3965                   a->leid_prefix_len);
3966       vec_add1 (s, 0);
3967       vat_json_object_add_string_copy (e, "leid", s);
3968       vec_free (s);
3969
3970       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3971                   a->reid_prefix_len);
3972       vec_add1 (s, 0);
3973       vat_json_object_add_string_copy (e, "reid", s);
3974       vec_free (s);
3975     }
3976
3977   vat_json_print (vam->ofp, &root);
3978   vat_json_free (&root);
3979
3980 end:
3981   vam->retval = retval;
3982   vam->result_ready = 1;
3983 }
3984
3985 static void
3986 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3987 {
3988   vat_main_t *vam = &vat_main;
3989
3990   print (vam->ofp, "%=20U",
3991          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3992          mp->ip_address);
3993 }
3994
3995 static void
3996   vl_api_one_map_server_details_t_handler_json
3997   (vl_api_one_map_server_details_t * mp)
3998 {
3999   vat_main_t *vam = &vat_main;
4000   vat_json_node_t *node = NULL;
4001   struct in6_addr ip6;
4002   struct in_addr ip4;
4003
4004   if (VAT_JSON_ARRAY != vam->json_tree.type)
4005     {
4006       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4007       vat_json_init_array (&vam->json_tree);
4008     }
4009   node = vat_json_array_add (&vam->json_tree);
4010
4011   vat_json_init_object (node);
4012   if (mp->is_ipv6)
4013     {
4014       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4015       vat_json_object_add_ip6 (node, "map-server", ip6);
4016     }
4017   else
4018     {
4019       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4020       vat_json_object_add_ip4 (node, "map-server", ip4);
4021     }
4022 }
4023
4024 static void
4025 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4026                                            * mp)
4027 {
4028   vat_main_t *vam = &vat_main;
4029
4030   print (vam->ofp, "%=20U",
4031          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4032          mp->ip_address);
4033 }
4034
4035 static void
4036   vl_api_one_map_resolver_details_t_handler_json
4037   (vl_api_one_map_resolver_details_t * mp)
4038 {
4039   vat_main_t *vam = &vat_main;
4040   vat_json_node_t *node = NULL;
4041   struct in6_addr ip6;
4042   struct in_addr ip4;
4043
4044   if (VAT_JSON_ARRAY != vam->json_tree.type)
4045     {
4046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4047       vat_json_init_array (&vam->json_tree);
4048     }
4049   node = vat_json_array_add (&vam->json_tree);
4050
4051   vat_json_init_object (node);
4052   if (mp->is_ipv6)
4053     {
4054       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4055       vat_json_object_add_ip6 (node, "map resolver", ip6);
4056     }
4057   else
4058     {
4059       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4060       vat_json_object_add_ip4 (node, "map resolver", ip4);
4061     }
4062 }
4063
4064 static void
4065 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4066 {
4067   vat_main_t *vam = &vat_main;
4068   i32 retval = ntohl (mp->retval);
4069
4070   if (0 <= retval)
4071     {
4072       print (vam->ofp, "feature: %s\ngpe: %s",
4073              mp->feature_status ? "enabled" : "disabled",
4074              mp->gpe_status ? "enabled" : "disabled");
4075     }
4076
4077   vam->retval = retval;
4078   vam->result_ready = 1;
4079 }
4080
4081 static void
4082   vl_api_show_one_status_reply_t_handler_json
4083   (vl_api_show_one_status_reply_t * mp)
4084 {
4085   vat_main_t *vam = &vat_main;
4086   vat_json_node_t node;
4087   u8 *gpe_status = NULL;
4088   u8 *feature_status = NULL;
4089
4090   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4091   feature_status = format (0, "%s",
4092                            mp->feature_status ? "enabled" : "disabled");
4093   vec_add1 (gpe_status, 0);
4094   vec_add1 (feature_status, 0);
4095
4096   vat_json_init_object (&node);
4097   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4098   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4099
4100   vec_free (gpe_status);
4101   vec_free (feature_status);
4102
4103   vat_json_print (vam->ofp, &node);
4104   vat_json_free (&node);
4105
4106   vam->retval = ntohl (mp->retval);
4107   vam->result_ready = 1;
4108 }
4109
4110 static void
4111   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4112   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4113 {
4114   vat_main_t *vam = &vat_main;
4115   i32 retval = ntohl (mp->retval);
4116
4117   if (retval >= 0)
4118     {
4119       print (vam->ofp, "%=20s", mp->locator_set_name);
4120     }
4121
4122   vam->retval = retval;
4123   vam->result_ready = 1;
4124 }
4125
4126 static void
4127   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4128   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4129 {
4130   vat_main_t *vam = &vat_main;
4131   vat_json_node_t *node = NULL;
4132
4133   if (VAT_JSON_ARRAY != vam->json_tree.type)
4134     {
4135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4136       vat_json_init_array (&vam->json_tree);
4137     }
4138   node = vat_json_array_add (&vam->json_tree);
4139
4140   vat_json_init_object (node);
4141   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4142
4143   vat_json_print (vam->ofp, node);
4144   vat_json_free (node);
4145
4146   vam->retval = ntohl (mp->retval);
4147   vam->result_ready = 1;
4148 }
4149
4150 static u8 *
4151 format_lisp_map_request_mode (u8 * s, va_list * args)
4152 {
4153   u32 mode = va_arg (*args, u32);
4154
4155   switch (mode)
4156     {
4157     case 0:
4158       return format (0, "dst-only");
4159     case 1:
4160       return format (0, "src-dst");
4161     }
4162   return 0;
4163 }
4164
4165 static void
4166   vl_api_show_one_map_request_mode_reply_t_handler
4167   (vl_api_show_one_map_request_mode_reply_t * mp)
4168 {
4169   vat_main_t *vam = &vat_main;
4170   i32 retval = ntohl (mp->retval);
4171
4172   if (0 <= retval)
4173     {
4174       u32 mode = mp->mode;
4175       print (vam->ofp, "map_request_mode: %U",
4176              format_lisp_map_request_mode, mode);
4177     }
4178
4179   vam->retval = retval;
4180   vam->result_ready = 1;
4181 }
4182
4183 static void
4184   vl_api_show_one_map_request_mode_reply_t_handler_json
4185   (vl_api_show_one_map_request_mode_reply_t * mp)
4186 {
4187   vat_main_t *vam = &vat_main;
4188   vat_json_node_t node;
4189   u8 *s = 0;
4190   u32 mode;
4191
4192   mode = mp->mode;
4193   s = format (0, "%U", format_lisp_map_request_mode, mode);
4194   vec_add1 (s, 0);
4195
4196   vat_json_init_object (&node);
4197   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4198   vat_json_print (vam->ofp, &node);
4199   vat_json_free (&node);
4200
4201   vec_free (s);
4202   vam->retval = ntohl (mp->retval);
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207   vl_api_one_show_xtr_mode_reply_t_handler
4208   (vl_api_one_show_xtr_mode_reply_t * mp)
4209 {
4210   vat_main_t *vam = &vat_main;
4211   i32 retval = ntohl (mp->retval);
4212
4213   if (0 <= retval)
4214     {
4215       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4216     }
4217
4218   vam->retval = retval;
4219   vam->result_ready = 1;
4220 }
4221
4222 static void
4223   vl_api_one_show_xtr_mode_reply_t_handler_json
4224   (vl_api_one_show_xtr_mode_reply_t * mp)
4225 {
4226   vat_main_t *vam = &vat_main;
4227   vat_json_node_t node;
4228   u8 *status = 0;
4229
4230   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4231   vec_add1 (status, 0);
4232
4233   vat_json_init_object (&node);
4234   vat_json_object_add_string_copy (&node, "status", status);
4235
4236   vec_free (status);
4237
4238   vat_json_print (vam->ofp, &node);
4239   vat_json_free (&node);
4240
4241   vam->retval = ntohl (mp->retval);
4242   vam->result_ready = 1;
4243 }
4244
4245 static void
4246   vl_api_one_show_pitr_mode_reply_t_handler
4247   (vl_api_one_show_pitr_mode_reply_t * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250   i32 retval = ntohl (mp->retval);
4251
4252   if (0 <= retval)
4253     {
4254       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4255     }
4256
4257   vam->retval = retval;
4258   vam->result_ready = 1;
4259 }
4260
4261 static void
4262   vl_api_one_show_pitr_mode_reply_t_handler_json
4263   (vl_api_one_show_pitr_mode_reply_t * mp)
4264 {
4265   vat_main_t *vam = &vat_main;
4266   vat_json_node_t node;
4267   u8 *status = 0;
4268
4269   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4270   vec_add1 (status, 0);
4271
4272   vat_json_init_object (&node);
4273   vat_json_object_add_string_copy (&node, "status", status);
4274
4275   vec_free (status);
4276
4277   vat_json_print (vam->ofp, &node);
4278   vat_json_free (&node);
4279
4280   vam->retval = ntohl (mp->retval);
4281   vam->result_ready = 1;
4282 }
4283
4284 static void
4285   vl_api_one_show_petr_mode_reply_t_handler
4286   (vl_api_one_show_petr_mode_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4294     }
4295
4296   vam->retval = retval;
4297   vam->result_ready = 1;
4298 }
4299
4300 static void
4301   vl_api_one_show_petr_mode_reply_t_handler_json
4302   (vl_api_one_show_petr_mode_reply_t * mp)
4303 {
4304   vat_main_t *vam = &vat_main;
4305   vat_json_node_t node;
4306   u8 *status = 0;
4307
4308   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4309   vec_add1 (status, 0);
4310
4311   vat_json_init_object (&node);
4312   vat_json_object_add_string_copy (&node, "status", status);
4313
4314   vec_free (status);
4315
4316   vat_json_print (vam->ofp, &node);
4317   vat_json_free (&node);
4318
4319   vam->retval = ntohl (mp->retval);
4320   vam->result_ready = 1;
4321 }
4322
4323 static void
4324   vl_api_show_one_use_petr_reply_t_handler
4325   (vl_api_show_one_use_petr_reply_t * mp)
4326 {
4327   vat_main_t *vam = &vat_main;
4328   i32 retval = ntohl (mp->retval);
4329
4330   if (0 <= retval)
4331     {
4332       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4333       if (mp->status)
4334         {
4335           print (vam->ofp, "Proxy-ETR address; %U",
4336                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4337                  mp->address);
4338         }
4339     }
4340
4341   vam->retval = retval;
4342   vam->result_ready = 1;
4343 }
4344
4345 static void
4346   vl_api_show_one_use_petr_reply_t_handler_json
4347   (vl_api_show_one_use_petr_reply_t * mp)
4348 {
4349   vat_main_t *vam = &vat_main;
4350   vat_json_node_t node;
4351   u8 *status = 0;
4352   struct in_addr ip4;
4353   struct in6_addr ip6;
4354
4355   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4356   vec_add1 (status, 0);
4357
4358   vat_json_init_object (&node);
4359   vat_json_object_add_string_copy (&node, "status", status);
4360   if (mp->status)
4361     {
4362       if (mp->is_ip4)
4363         {
4364           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4365           vat_json_object_add_ip6 (&node, "address", ip6);
4366         }
4367       else
4368         {
4369           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4370           vat_json_object_add_ip4 (&node, "address", ip4);
4371         }
4372     }
4373
4374   vec_free (status);
4375
4376   vat_json_print (vam->ofp, &node);
4377   vat_json_free (&node);
4378
4379   vam->retval = ntohl (mp->retval);
4380   vam->result_ready = 1;
4381 }
4382
4383 static void
4384   vl_api_show_one_nsh_mapping_reply_t_handler
4385   (vl_api_show_one_nsh_mapping_reply_t * mp)
4386 {
4387   vat_main_t *vam = &vat_main;
4388   i32 retval = ntohl (mp->retval);
4389
4390   if (0 <= retval)
4391     {
4392       print (vam->ofp, "%-20s%-16s",
4393              mp->is_set ? "set" : "not-set",
4394              mp->is_set ? (char *) mp->locator_set_name : "");
4395     }
4396
4397   vam->retval = retval;
4398   vam->result_ready = 1;
4399 }
4400
4401 static void
4402   vl_api_show_one_nsh_mapping_reply_t_handler_json
4403   (vl_api_show_one_nsh_mapping_reply_t * mp)
4404 {
4405   vat_main_t *vam = &vat_main;
4406   vat_json_node_t node;
4407   u8 *status = 0;
4408
4409   status = format (0, "%s", mp->is_set ? "yes" : "no");
4410   vec_add1 (status, 0);
4411
4412   vat_json_init_object (&node);
4413   vat_json_object_add_string_copy (&node, "is_set", status);
4414   if (mp->is_set)
4415     {
4416       vat_json_object_add_string_copy (&node, "locator_set",
4417                                        mp->locator_set_name);
4418     }
4419
4420   vec_free (status);
4421
4422   vat_json_print (vam->ofp, &node);
4423   vat_json_free (&node);
4424
4425   vam->retval = ntohl (mp->retval);
4426   vam->result_ready = 1;
4427 }
4428
4429 static void
4430   vl_api_show_one_map_register_ttl_reply_t_handler
4431   (vl_api_show_one_map_register_ttl_reply_t * mp)
4432 {
4433   vat_main_t *vam = &vat_main;
4434   i32 retval = ntohl (mp->retval);
4435
4436   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4437
4438   if (0 <= retval)
4439     {
4440       print (vam->ofp, "ttl: %u", mp->ttl);
4441     }
4442
4443   vam->retval = retval;
4444   vam->result_ready = 1;
4445 }
4446
4447 static void
4448   vl_api_show_one_map_register_ttl_reply_t_handler_json
4449   (vl_api_show_one_map_register_ttl_reply_t * mp)
4450 {
4451   vat_main_t *vam = &vat_main;
4452   vat_json_node_t node;
4453
4454   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4455   vat_json_init_object (&node);
4456   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4457
4458   vat_json_print (vam->ofp, &node);
4459   vat_json_free (&node);
4460
4461   vam->retval = ntohl (mp->retval);
4462   vam->result_ready = 1;
4463 }
4464
4465 static void
4466 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   i32 retval = ntohl (mp->retval);
4470
4471   if (0 <= retval)
4472     {
4473       print (vam->ofp, "%-20s%-16s",
4474              mp->status ? "enabled" : "disabled",
4475              mp->status ? (char *) mp->locator_set_name : "");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   vat_json_node_t node;
4487   u8 *status = 0;
4488
4489   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4490   vec_add1 (status, 0);
4491
4492   vat_json_init_object (&node);
4493   vat_json_object_add_string_copy (&node, "status", status);
4494   if (mp->status)
4495     {
4496       vat_json_object_add_string_copy (&node, "locator_set",
4497                                        mp->locator_set_name);
4498     }
4499
4500   vec_free (status);
4501
4502   vat_json_print (vam->ofp, &node);
4503   vat_json_free (&node);
4504
4505   vam->retval = ntohl (mp->retval);
4506   vam->result_ready = 1;
4507 }
4508
4509 static u8 *
4510 format_policer_type (u8 * s, va_list * va)
4511 {
4512   u32 i = va_arg (*va, u32);
4513
4514   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4515     s = format (s, "1r2c");
4516   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4517     s = format (s, "1r3c");
4518   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4519     s = format (s, "2r3c-2698");
4520   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4521     s = format (s, "2r3c-4115");
4522   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4523     s = format (s, "2r3c-mef5cf1");
4524   else
4525     s = format (s, "ILLEGAL");
4526   return s;
4527 }
4528
4529 static u8 *
4530 format_policer_rate_type (u8 * s, va_list * va)
4531 {
4532   u32 i = va_arg (*va, u32);
4533
4534   if (i == SSE2_QOS_RATE_KBPS)
4535     s = format (s, "kbps");
4536   else if (i == SSE2_QOS_RATE_PPS)
4537     s = format (s, "pps");
4538   else
4539     s = format (s, "ILLEGAL");
4540   return s;
4541 }
4542
4543 static u8 *
4544 format_policer_round_type (u8 * s, va_list * va)
4545 {
4546   u32 i = va_arg (*va, u32);
4547
4548   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4549     s = format (s, "closest");
4550   else if (i == SSE2_QOS_ROUND_TO_UP)
4551     s = format (s, "up");
4552   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4553     s = format (s, "down");
4554   else
4555     s = format (s, "ILLEGAL");
4556   return s;
4557 }
4558
4559 static u8 *
4560 format_policer_action_type (u8 * s, va_list * va)
4561 {
4562   u32 i = va_arg (*va, u32);
4563
4564   if (i == SSE2_QOS_ACTION_DROP)
4565     s = format (s, "drop");
4566   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4567     s = format (s, "transmit");
4568   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4569     s = format (s, "mark-and-transmit");
4570   else
4571     s = format (s, "ILLEGAL");
4572   return s;
4573 }
4574
4575 static u8 *
4576 format_dscp (u8 * s, va_list * va)
4577 {
4578   u32 i = va_arg (*va, u32);
4579   char *t = 0;
4580
4581   switch (i)
4582     {
4583 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4584       foreach_vnet_dscp
4585 #undef _
4586     default:
4587       return format (s, "ILLEGAL");
4588     }
4589   s = format (s, "%s", t);
4590   return s;
4591 }
4592
4593 static void
4594 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4595 {
4596   vat_main_t *vam = &vat_main;
4597   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4598
4599   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4600     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4601   else
4602     conform_dscp_str = format (0, "");
4603
4604   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4605     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4606   else
4607     exceed_dscp_str = format (0, "");
4608
4609   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4610     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4611   else
4612     violate_dscp_str = format (0, "");
4613
4614   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4615          "rate type %U, round type %U, %s rate, %s color-aware, "
4616          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4617          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4618          "conform action %U%s, exceed action %U%s, violate action %U%s",
4619          mp->name,
4620          format_policer_type, mp->type,
4621          ntohl (mp->cir),
4622          ntohl (mp->eir),
4623          clib_net_to_host_u64 (mp->cb),
4624          clib_net_to_host_u64 (mp->eb),
4625          format_policer_rate_type, mp->rate_type,
4626          format_policer_round_type, mp->round_type,
4627          mp->single_rate ? "single" : "dual",
4628          mp->color_aware ? "is" : "not",
4629          ntohl (mp->cir_tokens_per_period),
4630          ntohl (mp->pir_tokens_per_period),
4631          ntohl (mp->scale),
4632          ntohl (mp->current_limit),
4633          ntohl (mp->current_bucket),
4634          ntohl (mp->extended_limit),
4635          ntohl (mp->extended_bucket),
4636          clib_net_to_host_u64 (mp->last_update_time),
4637          format_policer_action_type, mp->conform_action_type,
4638          conform_dscp_str,
4639          format_policer_action_type, mp->exceed_action_type,
4640          exceed_dscp_str,
4641          format_policer_action_type, mp->violate_action_type,
4642          violate_dscp_str);
4643
4644   vec_free (conform_dscp_str);
4645   vec_free (exceed_dscp_str);
4646   vec_free (violate_dscp_str);
4647 }
4648
4649 static void vl_api_policer_details_t_handler_json
4650   (vl_api_policer_details_t * mp)
4651 {
4652   vat_main_t *vam = &vat_main;
4653   vat_json_node_t *node;
4654   u8 *rate_type_str, *round_type_str, *type_str;
4655   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4656
4657   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4658   round_type_str =
4659     format (0, "%U", format_policer_round_type, mp->round_type);
4660   type_str = format (0, "%U", format_policer_type, mp->type);
4661   conform_action_str = format (0, "%U", format_policer_action_type,
4662                                mp->conform_action_type);
4663   exceed_action_str = format (0, "%U", format_policer_action_type,
4664                               mp->exceed_action_type);
4665   violate_action_str = format (0, "%U", format_policer_action_type,
4666                                mp->violate_action_type);
4667
4668   if (VAT_JSON_ARRAY != vam->json_tree.type)
4669     {
4670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4671       vat_json_init_array (&vam->json_tree);
4672     }
4673   node = vat_json_array_add (&vam->json_tree);
4674
4675   vat_json_init_object (node);
4676   vat_json_object_add_string_copy (node, "name", mp->name);
4677   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4678   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4679   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4680   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4681   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4682   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4683   vat_json_object_add_string_copy (node, "type", type_str);
4684   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4685   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4686   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4687   vat_json_object_add_uint (node, "cir_tokens_per_period",
4688                             ntohl (mp->cir_tokens_per_period));
4689   vat_json_object_add_uint (node, "eir_tokens_per_period",
4690                             ntohl (mp->pir_tokens_per_period));
4691   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4692   vat_json_object_add_uint (node, "current_bucket",
4693                             ntohl (mp->current_bucket));
4694   vat_json_object_add_uint (node, "extended_limit",
4695                             ntohl (mp->extended_limit));
4696   vat_json_object_add_uint (node, "extended_bucket",
4697                             ntohl (mp->extended_bucket));
4698   vat_json_object_add_uint (node, "last_update_time",
4699                             ntohl (mp->last_update_time));
4700   vat_json_object_add_string_copy (node, "conform_action",
4701                                    conform_action_str);
4702   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4703     {
4704       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4705       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4706       vec_free (dscp_str);
4707     }
4708   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4709   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4710     {
4711       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4712       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4713       vec_free (dscp_str);
4714     }
4715   vat_json_object_add_string_copy (node, "violate_action",
4716                                    violate_action_str);
4717   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4718     {
4719       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4720       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4721       vec_free (dscp_str);
4722     }
4723
4724   vec_free (rate_type_str);
4725   vec_free (round_type_str);
4726   vec_free (type_str);
4727   vec_free (conform_action_str);
4728   vec_free (exceed_action_str);
4729   vec_free (violate_action_str);
4730 }
4731
4732 static void
4733 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4734                                            mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   int i, count = ntohl (mp->count);
4738
4739   if (count > 0)
4740     print (vam->ofp, "classify table ids (%d) : ", count);
4741   for (i = 0; i < count; i++)
4742     {
4743       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4744       print (vam->ofp, (i < count - 1) ? "," : "");
4745     }
4746   vam->retval = ntohl (mp->retval);
4747   vam->result_ready = 1;
4748 }
4749
4750 static void
4751   vl_api_classify_table_ids_reply_t_handler_json
4752   (vl_api_classify_table_ids_reply_t * mp)
4753 {
4754   vat_main_t *vam = &vat_main;
4755   int i, count = ntohl (mp->count);
4756
4757   if (count > 0)
4758     {
4759       vat_json_node_t node;
4760
4761       vat_json_init_object (&node);
4762       for (i = 0; i < count; i++)
4763         {
4764           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4765         }
4766       vat_json_print (vam->ofp, &node);
4767       vat_json_free (&node);
4768     }
4769   vam->retval = ntohl (mp->retval);
4770   vam->result_ready = 1;
4771 }
4772
4773 static void
4774   vl_api_classify_table_by_interface_reply_t_handler
4775   (vl_api_classify_table_by_interface_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   u32 table_id;
4779
4780   table_id = ntohl (mp->l2_table_id);
4781   if (table_id != ~0)
4782     print (vam->ofp, "l2 table id : %d", table_id);
4783   else
4784     print (vam->ofp, "l2 table id : No input ACL tables configured");
4785   table_id = ntohl (mp->ip4_table_id);
4786   if (table_id != ~0)
4787     print (vam->ofp, "ip4 table id : %d", table_id);
4788   else
4789     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4790   table_id = ntohl (mp->ip6_table_id);
4791   if (table_id != ~0)
4792     print (vam->ofp, "ip6 table id : %d", table_id);
4793   else
4794     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4795   vam->retval = ntohl (mp->retval);
4796   vam->result_ready = 1;
4797 }
4798
4799 static void
4800   vl_api_classify_table_by_interface_reply_t_handler_json
4801   (vl_api_classify_table_by_interface_reply_t * mp)
4802 {
4803   vat_main_t *vam = &vat_main;
4804   vat_json_node_t node;
4805
4806   vat_json_init_object (&node);
4807
4808   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4809   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4810   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4811
4812   vat_json_print (vam->ofp, &node);
4813   vat_json_free (&node);
4814
4815   vam->retval = ntohl (mp->retval);
4816   vam->result_ready = 1;
4817 }
4818
4819 static void vl_api_policer_add_del_reply_t_handler
4820   (vl_api_policer_add_del_reply_t * mp)
4821 {
4822   vat_main_t *vam = &vat_main;
4823   i32 retval = ntohl (mp->retval);
4824   if (vam->async_mode)
4825     {
4826       vam->async_errors += (retval < 0);
4827     }
4828   else
4829     {
4830       vam->retval = retval;
4831       vam->result_ready = 1;
4832       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4833         /*
4834          * Note: this is just barely thread-safe, depends on
4835          * the main thread spinning waiting for an answer...
4836          */
4837         errmsg ("policer index %d", ntohl (mp->policer_index));
4838     }
4839 }
4840
4841 static void vl_api_policer_add_del_reply_t_handler_json
4842   (vl_api_policer_add_del_reply_t * mp)
4843 {
4844   vat_main_t *vam = &vat_main;
4845   vat_json_node_t node;
4846
4847   vat_json_init_object (&node);
4848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4849   vat_json_object_add_uint (&node, "policer_index",
4850                             ntohl (mp->policer_index));
4851
4852   vat_json_print (vam->ofp, &node);
4853   vat_json_free (&node);
4854
4855   vam->retval = ntohl (mp->retval);
4856   vam->result_ready = 1;
4857 }
4858
4859 /* Format hex dump. */
4860 u8 *
4861 format_hex_bytes (u8 * s, va_list * va)
4862 {
4863   u8 *bytes = va_arg (*va, u8 *);
4864   int n_bytes = va_arg (*va, int);
4865   uword i;
4866
4867   /* Print short or long form depending on byte count. */
4868   uword short_form = n_bytes <= 32;
4869   u32 indent = format_get_indent (s);
4870
4871   if (n_bytes == 0)
4872     return s;
4873
4874   for (i = 0; i < n_bytes; i++)
4875     {
4876       if (!short_form && (i % 32) == 0)
4877         s = format (s, "%08x: ", i);
4878       s = format (s, "%02x", bytes[i]);
4879       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4880         s = format (s, "\n%U", format_white_space, indent);
4881     }
4882
4883   return s;
4884 }
4885
4886 static void
4887 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4888                                             * mp)
4889 {
4890   vat_main_t *vam = &vat_main;
4891   i32 retval = ntohl (mp->retval);
4892   if (retval == 0)
4893     {
4894       print (vam->ofp, "classify table info :");
4895       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4896              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4897              ntohl (mp->miss_next_index));
4898       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4899              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4900              ntohl (mp->match_n_vectors));
4901       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4902              ntohl (mp->mask_length));
4903     }
4904   vam->retval = retval;
4905   vam->result_ready = 1;
4906 }
4907
4908 static void
4909   vl_api_classify_table_info_reply_t_handler_json
4910   (vl_api_classify_table_info_reply_t * mp)
4911 {
4912   vat_main_t *vam = &vat_main;
4913   vat_json_node_t node;
4914
4915   i32 retval = ntohl (mp->retval);
4916   if (retval == 0)
4917     {
4918       vat_json_init_object (&node);
4919
4920       vat_json_object_add_int (&node, "sessions",
4921                                ntohl (mp->active_sessions));
4922       vat_json_object_add_int (&node, "nexttbl",
4923                                ntohl (mp->next_table_index));
4924       vat_json_object_add_int (&node, "nextnode",
4925                                ntohl (mp->miss_next_index));
4926       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4927       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4928       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4929       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4930                       ntohl (mp->mask_length), 0);
4931       vat_json_object_add_string_copy (&node, "mask", s);
4932
4933       vat_json_print (vam->ofp, &node);
4934       vat_json_free (&node);
4935     }
4936   vam->retval = ntohl (mp->retval);
4937   vam->result_ready = 1;
4938 }
4939
4940 static void
4941 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4942                                            mp)
4943 {
4944   vat_main_t *vam = &vat_main;
4945
4946   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4947          ntohl (mp->hit_next_index), ntohl (mp->advance),
4948          ntohl (mp->opaque_index));
4949   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4950          ntohl (mp->match_length));
4951 }
4952
4953 static void
4954   vl_api_classify_session_details_t_handler_json
4955   (vl_api_classify_session_details_t * mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   vat_json_node_t *node = NULL;
4959
4960   if (VAT_JSON_ARRAY != vam->json_tree.type)
4961     {
4962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4963       vat_json_init_array (&vam->json_tree);
4964     }
4965   node = vat_json_array_add (&vam->json_tree);
4966
4967   vat_json_init_object (node);
4968   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4969   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4970   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4971   u8 *s =
4972     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4973             0);
4974   vat_json_object_add_string_copy (node, "match", s);
4975 }
4976
4977 static void vl_api_pg_create_interface_reply_t_handler
4978   (vl_api_pg_create_interface_reply_t * mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981
4982   vam->retval = ntohl (mp->retval);
4983   vam->result_ready = 1;
4984 }
4985
4986 static void vl_api_pg_create_interface_reply_t_handler_json
4987   (vl_api_pg_create_interface_reply_t * mp)
4988 {
4989   vat_main_t *vam = &vat_main;
4990   vat_json_node_t node;
4991
4992   i32 retval = ntohl (mp->retval);
4993   if (retval == 0)
4994     {
4995       vat_json_init_object (&node);
4996
4997       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4998
4999       vat_json_print (vam->ofp, &node);
5000       vat_json_free (&node);
5001     }
5002   vam->retval = ntohl (mp->retval);
5003   vam->result_ready = 1;
5004 }
5005
5006 static void vl_api_policer_classify_details_t_handler
5007   (vl_api_policer_classify_details_t * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010
5011   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5012          ntohl (mp->table_index));
5013 }
5014
5015 static void vl_api_policer_classify_details_t_handler_json
5016   (vl_api_policer_classify_details_t * mp)
5017 {
5018   vat_main_t *vam = &vat_main;
5019   vat_json_node_t *node;
5020
5021   if (VAT_JSON_ARRAY != vam->json_tree.type)
5022     {
5023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5024       vat_json_init_array (&vam->json_tree);
5025     }
5026   node = vat_json_array_add (&vam->json_tree);
5027
5028   vat_json_init_object (node);
5029   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5030   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5031 }
5032
5033 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5034   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5035 {
5036   vat_main_t *vam = &vat_main;
5037   i32 retval = ntohl (mp->retval);
5038   if (vam->async_mode)
5039     {
5040       vam->async_errors += (retval < 0);
5041     }
5042   else
5043     {
5044       vam->retval = retval;
5045       vam->sw_if_index = ntohl (mp->sw_if_index);
5046       vam->result_ready = 1;
5047     }
5048   vam->regenerate_interface_table = 1;
5049 }
5050
5051 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5052   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5053 {
5054   vat_main_t *vam = &vat_main;
5055   vat_json_node_t node;
5056
5057   vat_json_init_object (&node);
5058   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5059   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5060
5061   vat_json_print (vam->ofp, &node);
5062   vat_json_free (&node);
5063
5064   vam->retval = ntohl (mp->retval);
5065   vam->result_ready = 1;
5066 }
5067
5068 static void vl_api_flow_classify_details_t_handler
5069   (vl_api_flow_classify_details_t * mp)
5070 {
5071   vat_main_t *vam = &vat_main;
5072
5073   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5074          ntohl (mp->table_index));
5075 }
5076
5077 static void vl_api_flow_classify_details_t_handler_json
5078   (vl_api_flow_classify_details_t * mp)
5079 {
5080   vat_main_t *vam = &vat_main;
5081   vat_json_node_t *node;
5082
5083   if (VAT_JSON_ARRAY != vam->json_tree.type)
5084     {
5085       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5086       vat_json_init_array (&vam->json_tree);
5087     }
5088   node = vat_json_array_add (&vam->json_tree);
5089
5090   vat_json_init_object (node);
5091   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5092   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5093 }
5094
5095 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5096 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5097 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5098 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5099 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5100 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5101 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5102 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5103 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5104 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5105
5106 /*
5107  * Generate boilerplate reply handlers, which
5108  * dig the return value out of the xxx_reply_t API message,
5109  * stick it into vam->retval, and set vam->result_ready
5110  *
5111  * Could also do this by pointing N message decode slots at
5112  * a single function, but that could break in subtle ways.
5113  */
5114
5115 #define foreach_standard_reply_retval_handler           \
5116 _(sw_interface_set_flags_reply)                         \
5117 _(sw_interface_add_del_address_reply)                   \
5118 _(sw_interface_set_rx_mode_reply)                       \
5119 _(sw_interface_set_rx_placement_reply)                  \
5120 _(sw_interface_set_table_reply)                         \
5121 _(sw_interface_set_mpls_enable_reply)                   \
5122 _(sw_interface_set_vpath_reply)                         \
5123 _(sw_interface_set_vxlan_bypass_reply)                  \
5124 _(sw_interface_set_geneve_bypass_reply)                 \
5125 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5126 _(sw_interface_set_l2_bridge_reply)                     \
5127 _(bridge_domain_add_del_reply)                          \
5128 _(sw_interface_set_l2_xconnect_reply)                   \
5129 _(l2fib_add_del_reply)                                  \
5130 _(l2fib_flush_int_reply)                                \
5131 _(l2fib_flush_bd_reply)                                 \
5132 _(ip_add_del_route_reply)                               \
5133 _(ip_table_add_del_reply)                               \
5134 _(ip_mroute_add_del_reply)                              \
5135 _(mpls_route_add_del_reply)                             \
5136 _(mpls_table_add_del_reply)                             \
5137 _(mpls_ip_bind_unbind_reply)                            \
5138 _(bier_route_add_del_reply)                             \
5139 _(bier_table_add_del_reply)                             \
5140 _(proxy_arp_add_del_reply)                              \
5141 _(proxy_arp_intfc_enable_disable_reply)                 \
5142 _(sw_interface_set_unnumbered_reply)                    \
5143 _(ip_neighbor_add_del_reply)                            \
5144 _(oam_add_del_reply)                                    \
5145 _(reset_fib_reply)                                      \
5146 _(dhcp_proxy_config_reply)                              \
5147 _(dhcp_proxy_set_vss_reply)                             \
5148 _(dhcp_client_config_reply)                             \
5149 _(set_ip_flow_hash_reply)                               \
5150 _(sw_interface_ip6_enable_disable_reply)                \
5151 _(ip6nd_proxy_add_del_reply)                            \
5152 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5153 _(sw_interface_ip6nd_ra_config_reply)                   \
5154 _(set_arp_neighbor_limit_reply)                         \
5155 _(l2_patch_add_del_reply)                               \
5156 _(sr_mpls_policy_add_reply)                             \
5157 _(sr_mpls_policy_mod_reply)                             \
5158 _(sr_mpls_policy_del_reply)                             \
5159 _(sr_policy_add_reply)                                  \
5160 _(sr_policy_mod_reply)                                  \
5161 _(sr_policy_del_reply)                                  \
5162 _(sr_localsid_add_del_reply)                            \
5163 _(sr_steering_add_del_reply)                            \
5164 _(classify_add_del_session_reply)                       \
5165 _(classify_set_interface_ip_table_reply)                \
5166 _(classify_set_interface_l2_tables_reply)               \
5167 _(l2tpv3_set_tunnel_cookies_reply)                      \
5168 _(l2tpv3_interface_enable_disable_reply)                \
5169 _(l2tpv3_set_lookup_key_reply)                          \
5170 _(l2_fib_clear_table_reply)                             \
5171 _(l2_interface_efp_filter_reply)                        \
5172 _(l2_interface_vlan_tag_rewrite_reply)                  \
5173 _(modify_vhost_user_if_reply)                           \
5174 _(delete_vhost_user_if_reply)                           \
5175 _(ip_probe_neighbor_reply)                              \
5176 _(ip_scan_neighbor_enable_disable_reply)                \
5177 _(want_ip4_arp_events_reply)                            \
5178 _(want_ip6_nd_events_reply)                             \
5179 _(want_l2_macs_events_reply)                            \
5180 _(input_acl_set_interface_reply)                        \
5181 _(ipsec_spd_add_del_reply)                              \
5182 _(ipsec_interface_add_del_spd_reply)                    \
5183 _(ipsec_spd_entry_add_del_reply)                        \
5184 _(ipsec_sad_entry_add_del_reply)                        \
5185 _(ipsec_sa_set_key_reply)                               \
5186 _(ipsec_tunnel_if_add_del_reply)                        \
5187 _(ipsec_tunnel_if_set_key_reply)                        \
5188 _(ipsec_tunnel_if_set_sa_reply)                         \
5189 _(delete_loopback_reply)                                \
5190 _(bd_ip_mac_add_del_reply)                              \
5191 _(bd_ip_mac_flush_reply)                                \
5192 _(want_interface_events_reply)                          \
5193 _(cop_interface_enable_disable_reply)                   \
5194 _(cop_whitelist_enable_disable_reply)                   \
5195 _(sw_interface_clear_stats_reply)                       \
5196 _(ioam_enable_reply)                                    \
5197 _(ioam_disable_reply)                                   \
5198 _(one_add_del_locator_reply)                            \
5199 _(one_add_del_local_eid_reply)                          \
5200 _(one_add_del_remote_mapping_reply)                     \
5201 _(one_add_del_adjacency_reply)                          \
5202 _(one_add_del_map_resolver_reply)                       \
5203 _(one_add_del_map_server_reply)                         \
5204 _(one_enable_disable_reply)                             \
5205 _(one_rloc_probe_enable_disable_reply)                  \
5206 _(one_map_register_enable_disable_reply)                \
5207 _(one_map_register_set_ttl_reply)                       \
5208 _(one_set_transport_protocol_reply)                     \
5209 _(one_map_register_fallback_threshold_reply)            \
5210 _(one_pitr_set_locator_set_reply)                       \
5211 _(one_map_request_mode_reply)                           \
5212 _(one_add_del_map_request_itr_rlocs_reply)              \
5213 _(one_eid_table_add_del_map_reply)                      \
5214 _(one_use_petr_reply)                                   \
5215 _(one_stats_enable_disable_reply)                       \
5216 _(one_add_del_l2_arp_entry_reply)                       \
5217 _(one_add_del_ndp_entry_reply)                          \
5218 _(one_stats_flush_reply)                                \
5219 _(one_enable_disable_xtr_mode_reply)                    \
5220 _(one_enable_disable_pitr_mode_reply)                   \
5221 _(one_enable_disable_petr_mode_reply)                   \
5222 _(gpe_enable_disable_reply)                             \
5223 _(gpe_set_encap_mode_reply)                             \
5224 _(gpe_add_del_iface_reply)                              \
5225 _(gpe_add_del_native_fwd_rpath_reply)                   \
5226 _(af_packet_delete_reply)                               \
5227 _(policer_classify_set_interface_reply)                 \
5228 _(netmap_create_reply)                                  \
5229 _(netmap_delete_reply)                                  \
5230 _(set_ipfix_exporter_reply)                             \
5231 _(set_ipfix_classify_stream_reply)                      \
5232 _(ipfix_classify_table_add_del_reply)                   \
5233 _(flow_classify_set_interface_reply)                    \
5234 _(sw_interface_span_enable_disable_reply)               \
5235 _(pg_capture_reply)                                     \
5236 _(pg_enable_disable_reply)                              \
5237 _(ip_source_and_port_range_check_add_del_reply)         \
5238 _(ip_source_and_port_range_check_interface_add_del_reply)\
5239 _(delete_subif_reply)                                   \
5240 _(l2_interface_pbb_tag_rewrite_reply)                   \
5241 _(set_punt_reply)                                       \
5242 _(feature_enable_disable_reply)                         \
5243 _(sw_interface_tag_add_del_reply)                       \
5244 _(hw_interface_set_mtu_reply)                           \
5245 _(p2p_ethernet_add_reply)                               \
5246 _(p2p_ethernet_del_reply)                               \
5247 _(lldp_config_reply)                                    \
5248 _(sw_interface_set_lldp_reply)                          \
5249 _(tcp_configure_src_addresses_reply)                    \
5250 _(dns_enable_disable_reply)                             \
5251 _(dns_name_server_add_del_reply)                        \
5252 _(session_rule_add_del_reply)                           \
5253 _(ip_container_proxy_add_del_reply)                     \
5254 _(output_acl_set_interface_reply)                       \
5255 _(qos_record_enable_disable_reply)
5256
5257 #define _(n)                                    \
5258     static void vl_api_##n##_t_handler          \
5259     (vl_api_##n##_t * mp)                       \
5260     {                                           \
5261         vat_main_t * vam = &vat_main;           \
5262         i32 retval = ntohl(mp->retval);         \
5263         if (vam->async_mode) {                  \
5264             vam->async_errors += (retval < 0);  \
5265         } else {                                \
5266             vam->retval = retval;               \
5267             vam->result_ready = 1;              \
5268         }                                       \
5269     }
5270 foreach_standard_reply_retval_handler;
5271 #undef _
5272
5273 #define _(n)                                    \
5274     static void vl_api_##n##_t_handler_json     \
5275     (vl_api_##n##_t * mp)                       \
5276     {                                           \
5277         vat_main_t * vam = &vat_main;           \
5278         vat_json_node_t node;                   \
5279         vat_json_init_object(&node);            \
5280         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5281         vat_json_print(vam->ofp, &node);        \
5282         vam->retval = ntohl(mp->retval);        \
5283         vam->result_ready = 1;                  \
5284     }
5285 foreach_standard_reply_retval_handler;
5286 #undef _
5287
5288 /*
5289  * Table of message reply handlers, must include boilerplate handlers
5290  * we just generated
5291  */
5292
5293 #define foreach_vpe_api_reply_msg                                       \
5294 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5295 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5296 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5297 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5298 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5299 _(CLI_REPLY, cli_reply)                                                 \
5300 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5301 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5302   sw_interface_add_del_address_reply)                                   \
5303 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5304 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5305 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5306 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5307 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5308 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5309 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5310 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5311 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5312 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5313   sw_interface_set_l2_xconnect_reply)                                   \
5314 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5315   sw_interface_set_l2_bridge_reply)                                     \
5316 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5317 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5318 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5319 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5320 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5321 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5322 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5323 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5324 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5325 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5326 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5327 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5328 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5329 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5330 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5331 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5332 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5333 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5334 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5335 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5336 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5337 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5338 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5339 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5340 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5341 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5342 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5343 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5344 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5345 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5346   proxy_arp_intfc_enable_disable_reply)                                 \
5347 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5348 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5349   sw_interface_set_unnumbered_reply)                                    \
5350 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5351 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5352 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5353 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5354 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5355 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5356 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5357 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5358 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5359 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5360 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5361   sw_interface_ip6_enable_disable_reply)                                \
5362 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5363 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5364 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5365   sw_interface_ip6nd_ra_prefix_reply)                                   \
5366 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5367   sw_interface_ip6nd_ra_config_reply)                                   \
5368 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5369 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5370 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5371 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5372 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5373 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5374 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5375 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5376 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5377 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5378 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5379 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5380 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5381 classify_set_interface_ip_table_reply)                                  \
5382 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5383   classify_set_interface_l2_tables_reply)                               \
5384 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5385 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5386 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5387 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5388 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5389   l2tpv3_interface_enable_disable_reply)                                \
5390 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5391 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5392 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5393 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5394 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5395 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5396 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5397 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5398 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5399 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5400 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5401 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5402 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5403 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5404 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5405 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5406 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5407 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5408 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5409 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5410 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5411 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5412 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5413 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5414 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5415 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5416 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5417 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5418 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5419 _(L2_MACS_EVENT, l2_macs_event)                                         \
5420 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5421 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5422 _(IP_DETAILS, ip_details)                                               \
5423 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5424 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5425 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5426 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5427 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5428 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5429 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5430 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5431 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5432 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5433 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5434 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5435 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5436 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5437 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5438 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5439 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5440 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5441 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5442 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5443 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5444 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5445 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5446 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5447 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5448 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5449 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5450 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5451 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5452 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5453 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5454   one_map_register_enable_disable_reply)                                \
5455 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5456 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5457 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5458 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5459   one_map_register_fallback_threshold_reply)                            \
5460 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5461   one_rloc_probe_enable_disable_reply)                                  \
5462 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5463 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5464 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5465 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5466 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5467 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5468 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5469 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5470 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5471 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5472 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5473 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5474 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5475 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5476 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5477 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5478   show_one_stats_enable_disable_reply)                                  \
5479 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5480 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5481 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5482 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5483 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5484 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5485 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5486 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5487   one_enable_disable_pitr_mode_reply)                                   \
5488 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5489   one_enable_disable_petr_mode_reply)                                   \
5490 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5491 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5492 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5493 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5494 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5495 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5496 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5497 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5498 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5499 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5500 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5501 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5502   gpe_add_del_native_fwd_rpath_reply)                                   \
5503 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5504   gpe_fwd_entry_path_details)                                           \
5505 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5506 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5507   one_add_del_map_request_itr_rlocs_reply)                              \
5508 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5509   one_get_map_request_itr_rlocs_reply)                                  \
5510 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5511 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5512 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5513 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5514 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5515 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5516   show_one_map_register_state_reply)                                    \
5517 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5518 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5519   show_one_map_register_fallback_threshold_reply)                       \
5520 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5521 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5522 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5523 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5524 _(POLICER_DETAILS, policer_details)                                     \
5525 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5526 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5527 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5528 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5529 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5530 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5531 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5532 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5533 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5534 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5535 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5536 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5537 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5538 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5539 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5540 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5541 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5542 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5543 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5544 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5545 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5546 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5547 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5548 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5549 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5550  ip_source_and_port_range_check_add_del_reply)                          \
5551 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5552  ip_source_and_port_range_check_interface_add_del_reply)                \
5553 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5554 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5555 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5556 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5557 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5558 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5559 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5560 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5561 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5562 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5563 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5564 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5565 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5566 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5567 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5568 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5569 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5570 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5571 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5572 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5573 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5574 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5575 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5576 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5577 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5578 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5579 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5580 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5581
5582 #define foreach_standalone_reply_msg                                    \
5583 _(SW_INTERFACE_EVENT, sw_interface_event)
5584
5585 typedef struct
5586 {
5587   u8 *name;
5588   u32 value;
5589 } name_sort_t;
5590
5591 #define STR_VTR_OP_CASE(op)     \
5592     case L2_VTR_ ## op:         \
5593         return "" # op;
5594
5595 static const char *
5596 str_vtr_op (u32 vtr_op)
5597 {
5598   switch (vtr_op)
5599     {
5600       STR_VTR_OP_CASE (DISABLED);
5601       STR_VTR_OP_CASE (PUSH_1);
5602       STR_VTR_OP_CASE (PUSH_2);
5603       STR_VTR_OP_CASE (POP_1);
5604       STR_VTR_OP_CASE (POP_2);
5605       STR_VTR_OP_CASE (TRANSLATE_1_1);
5606       STR_VTR_OP_CASE (TRANSLATE_1_2);
5607       STR_VTR_OP_CASE (TRANSLATE_2_1);
5608       STR_VTR_OP_CASE (TRANSLATE_2_2);
5609     }
5610
5611   return "UNKNOWN";
5612 }
5613
5614 static int
5615 dump_sub_interface_table (vat_main_t * vam)
5616 {
5617   const sw_interface_subif_t *sub = NULL;
5618
5619   if (vam->json_output)
5620     {
5621       clib_warning
5622         ("JSON output supported only for VPE API calls and dump_stats_table");
5623       return -99;
5624     }
5625
5626   print (vam->ofp,
5627          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5628          "Interface", "sw_if_index",
5629          "sub id", "dot1ad", "tags", "outer id",
5630          "inner id", "exact", "default", "outer any", "inner any");
5631
5632   vec_foreach (sub, vam->sw_if_subif_table)
5633   {
5634     print (vam->ofp,
5635            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5636            sub->interface_name,
5637            sub->sw_if_index,
5638            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5639            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5640            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5641            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5642     if (sub->vtr_op != L2_VTR_DISABLED)
5643       {
5644         print (vam->ofp,
5645                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5646                "tag1: %d tag2: %d ]",
5647                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5648                sub->vtr_tag1, sub->vtr_tag2);
5649       }
5650   }
5651
5652   return 0;
5653 }
5654
5655 static int
5656 name_sort_cmp (void *a1, void *a2)
5657 {
5658   name_sort_t *n1 = a1;
5659   name_sort_t *n2 = a2;
5660
5661   return strcmp ((char *) n1->name, (char *) n2->name);
5662 }
5663
5664 static int
5665 dump_interface_table (vat_main_t * vam)
5666 {
5667   hash_pair_t *p;
5668   name_sort_t *nses = 0, *ns;
5669
5670   if (vam->json_output)
5671     {
5672       clib_warning
5673         ("JSON output supported only for VPE API calls and dump_stats_table");
5674       return -99;
5675     }
5676
5677   /* *INDENT-OFF* */
5678   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5679   ({
5680     vec_add2 (nses, ns, 1);
5681     ns->name = (u8 *)(p->key);
5682     ns->value = (u32) p->value[0];
5683   }));
5684   /* *INDENT-ON* */
5685
5686   vec_sort_with_function (nses, name_sort_cmp);
5687
5688   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5689   vec_foreach (ns, nses)
5690   {
5691     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5692   }
5693   vec_free (nses);
5694   return 0;
5695 }
5696
5697 static int
5698 dump_ip_table (vat_main_t * vam, int is_ipv6)
5699 {
5700   const ip_details_t *det = NULL;
5701   const ip_address_details_t *address = NULL;
5702   u32 i = ~0;
5703
5704   print (vam->ofp, "%-12s", "sw_if_index");
5705
5706   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5707   {
5708     i++;
5709     if (!det->present)
5710       {
5711         continue;
5712       }
5713     print (vam->ofp, "%-12d", i);
5714     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5715     if (!det->addr)
5716       {
5717         continue;
5718       }
5719     vec_foreach (address, det->addr)
5720     {
5721       print (vam->ofp,
5722              "            %-30U%-13d",
5723              is_ipv6 ? format_ip6_address : format_ip4_address,
5724              address->ip, address->prefix_length);
5725     }
5726   }
5727
5728   return 0;
5729 }
5730
5731 static int
5732 dump_ipv4_table (vat_main_t * vam)
5733 {
5734   if (vam->json_output)
5735     {
5736       clib_warning
5737         ("JSON output supported only for VPE API calls and dump_stats_table");
5738       return -99;
5739     }
5740
5741   return dump_ip_table (vam, 0);
5742 }
5743
5744 static int
5745 dump_ipv6_table (vat_main_t * vam)
5746 {
5747   if (vam->json_output)
5748     {
5749       clib_warning
5750         ("JSON output supported only for VPE API calls and dump_stats_table");
5751       return -99;
5752     }
5753
5754   return dump_ip_table (vam, 1);
5755 }
5756
5757 /*
5758  * Pass CLI buffers directly in the CLI_INBAND API message,
5759  * instead of an additional shared memory area.
5760  */
5761 static int
5762 exec_inband (vat_main_t * vam)
5763 {
5764   vl_api_cli_inband_t *mp;
5765   unformat_input_t *i = vam->input;
5766   int ret;
5767
5768   if (vec_len (i->buffer) == 0)
5769     return -1;
5770
5771   if (vam->exec_mode == 0 && unformat (i, "mode"))
5772     {
5773       vam->exec_mode = 1;
5774       return 0;
5775     }
5776   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5777     {
5778       vam->exec_mode = 0;
5779       return 0;
5780     }
5781
5782   /*
5783    * In order for the CLI command to work, it
5784    * must be a vector ending in \n, not a C-string ending
5785    * in \n\0.
5786    */
5787   u32 len = vec_len (vam->input->buffer);
5788   M2 (CLI_INBAND, mp, len);
5789   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5790
5791   S (mp);
5792   W (ret);
5793   /* json responses may or may not include a useful reply... */
5794   if (vec_len (vam->cmd_reply))
5795     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5796   return ret;
5797 }
5798
5799 int
5800 exec (vat_main_t * vam)
5801 {
5802   return exec_inband (vam);
5803 }
5804
5805 static int
5806 api_create_loopback (vat_main_t * vam)
5807 {
5808   unformat_input_t *i = vam->input;
5809   vl_api_create_loopback_t *mp;
5810   vl_api_create_loopback_instance_t *mp_lbi;
5811   u8 mac_address[6];
5812   u8 mac_set = 0;
5813   u8 is_specified = 0;
5814   u32 user_instance = 0;
5815   int ret;
5816
5817   clib_memset (mac_address, 0, sizeof (mac_address));
5818
5819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5820     {
5821       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5822         mac_set = 1;
5823       if (unformat (i, "instance %d", &user_instance))
5824         is_specified = 1;
5825       else
5826         break;
5827     }
5828
5829   if (is_specified)
5830     {
5831       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5832       mp_lbi->is_specified = is_specified;
5833       if (is_specified)
5834         mp_lbi->user_instance = htonl (user_instance);
5835       if (mac_set)
5836         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5837       S (mp_lbi);
5838     }
5839   else
5840     {
5841       /* Construct the API message */
5842       M (CREATE_LOOPBACK, mp);
5843       if (mac_set)
5844         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5845       S (mp);
5846     }
5847
5848   W (ret);
5849   return ret;
5850 }
5851
5852 static int
5853 api_delete_loopback (vat_main_t * vam)
5854 {
5855   unformat_input_t *i = vam->input;
5856   vl_api_delete_loopback_t *mp;
5857   u32 sw_if_index = ~0;
5858   int ret;
5859
5860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5861     {
5862       if (unformat (i, "sw_if_index %d", &sw_if_index))
5863         ;
5864       else
5865         break;
5866     }
5867
5868   if (sw_if_index == ~0)
5869     {
5870       errmsg ("missing sw_if_index");
5871       return -99;
5872     }
5873
5874   /* Construct the API message */
5875   M (DELETE_LOOPBACK, mp);
5876   mp->sw_if_index = ntohl (sw_if_index);
5877
5878   S (mp);
5879   W (ret);
5880   return ret;
5881 }
5882
5883 static int
5884 api_want_interface_events (vat_main_t * vam)
5885 {
5886   unformat_input_t *i = vam->input;
5887   vl_api_want_interface_events_t *mp;
5888   int enable = -1;
5889   int ret;
5890
5891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5892     {
5893       if (unformat (i, "enable"))
5894         enable = 1;
5895       else if (unformat (i, "disable"))
5896         enable = 0;
5897       else
5898         break;
5899     }
5900
5901   if (enable == -1)
5902     {
5903       errmsg ("missing enable|disable");
5904       return -99;
5905     }
5906
5907   M (WANT_INTERFACE_EVENTS, mp);
5908   mp->enable_disable = enable;
5909
5910   vam->interface_event_display = enable;
5911
5912   S (mp);
5913   W (ret);
5914   return ret;
5915 }
5916
5917
5918 /* Note: non-static, called once to set up the initial intfc table */
5919 int
5920 api_sw_interface_dump (vat_main_t * vam)
5921 {
5922   vl_api_sw_interface_dump_t *mp;
5923   vl_api_control_ping_t *mp_ping;
5924   hash_pair_t *p;
5925   name_sort_t *nses = 0, *ns;
5926   sw_interface_subif_t *sub = NULL;
5927   int ret;
5928
5929   /* Toss the old name table */
5930   /* *INDENT-OFF* */
5931   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5932   ({
5933     vec_add2 (nses, ns, 1);
5934     ns->name = (u8 *)(p->key);
5935     ns->value = (u32) p->value[0];
5936   }));
5937   /* *INDENT-ON* */
5938
5939   hash_free (vam->sw_if_index_by_interface_name);
5940
5941   vec_foreach (ns, nses) vec_free (ns->name);
5942
5943   vec_free (nses);
5944
5945   vec_foreach (sub, vam->sw_if_subif_table)
5946   {
5947     vec_free (sub->interface_name);
5948   }
5949   vec_free (vam->sw_if_subif_table);
5950
5951   /* recreate the interface name hash table */
5952   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5953
5954   /*
5955    * Ask for all interface names. Otherwise, the epic catalog of
5956    * name filters becomes ridiculously long, and vat ends up needing
5957    * to be taught about new interface types.
5958    */
5959   M (SW_INTERFACE_DUMP, mp);
5960   S (mp);
5961
5962   /* Use a control ping for synchronization */
5963   MPING (CONTROL_PING, mp_ping);
5964   S (mp_ping);
5965
5966   W (ret);
5967   return ret;
5968 }
5969
5970 static int
5971 api_sw_interface_set_flags (vat_main_t * vam)
5972 {
5973   unformat_input_t *i = vam->input;
5974   vl_api_sw_interface_set_flags_t *mp;
5975   u32 sw_if_index;
5976   u8 sw_if_index_set = 0;
5977   u8 admin_up = 0;
5978   int ret;
5979
5980   /* Parse args required to build the message */
5981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5982     {
5983       if (unformat (i, "admin-up"))
5984         admin_up = 1;
5985       else if (unformat (i, "admin-down"))
5986         admin_up = 0;
5987       else
5988         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5989         sw_if_index_set = 1;
5990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5991         sw_if_index_set = 1;
5992       else
5993         break;
5994     }
5995
5996   if (sw_if_index_set == 0)
5997     {
5998       errmsg ("missing interface name or sw_if_index");
5999       return -99;
6000     }
6001
6002   /* Construct the API message */
6003   M (SW_INTERFACE_SET_FLAGS, mp);
6004   mp->sw_if_index = ntohl (sw_if_index);
6005   mp->admin_up_down = admin_up;
6006
6007   /* send it... */
6008   S (mp);
6009
6010   /* Wait for a reply, return the good/bad news... */
6011   W (ret);
6012   return ret;
6013 }
6014
6015 static int
6016 api_sw_interface_set_rx_mode (vat_main_t * vam)
6017 {
6018   unformat_input_t *i = vam->input;
6019   vl_api_sw_interface_set_rx_mode_t *mp;
6020   u32 sw_if_index;
6021   u8 sw_if_index_set = 0;
6022   int ret;
6023   u8 queue_id_valid = 0;
6024   u32 queue_id;
6025   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6026
6027   /* Parse args required to build the message */
6028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6029     {
6030       if (unformat (i, "queue %d", &queue_id))
6031         queue_id_valid = 1;
6032       else if (unformat (i, "polling"))
6033         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6034       else if (unformat (i, "interrupt"))
6035         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6036       else if (unformat (i, "adaptive"))
6037         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6038       else
6039         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6040         sw_if_index_set = 1;
6041       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6042         sw_if_index_set = 1;
6043       else
6044         break;
6045     }
6046
6047   if (sw_if_index_set == 0)
6048     {
6049       errmsg ("missing interface name or sw_if_index");
6050       return -99;
6051     }
6052   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6053     {
6054       errmsg ("missing rx-mode");
6055       return -99;
6056     }
6057
6058   /* Construct the API message */
6059   M (SW_INTERFACE_SET_RX_MODE, mp);
6060   mp->sw_if_index = ntohl (sw_if_index);
6061   mp->mode = mode;
6062   mp->queue_id_valid = queue_id_valid;
6063   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6064
6065   /* send it... */
6066   S (mp);
6067
6068   /* Wait for a reply, return the good/bad news... */
6069   W (ret);
6070   return ret;
6071 }
6072
6073 static int
6074 api_sw_interface_set_rx_placement (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_sw_interface_set_rx_placement_t *mp;
6078   u32 sw_if_index;
6079   u8 sw_if_index_set = 0;
6080   int ret;
6081   u8 is_main = 0;
6082   u32 queue_id, thread_index;
6083
6084   /* Parse args required to build the message */
6085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6086     {
6087       if (unformat (i, "queue %d", &queue_id))
6088         ;
6089       else if (unformat (i, "main"))
6090         is_main = 1;
6091       else if (unformat (i, "worker %d", &thread_index))
6092         ;
6093       else
6094         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6095         sw_if_index_set = 1;
6096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6097         sw_if_index_set = 1;
6098       else
6099         break;
6100     }
6101
6102   if (sw_if_index_set == 0)
6103     {
6104       errmsg ("missing interface name or sw_if_index");
6105       return -99;
6106     }
6107
6108   if (is_main)
6109     thread_index = 0;
6110   /* Construct the API message */
6111   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6112   mp->sw_if_index = ntohl (sw_if_index);
6113   mp->worker_id = ntohl (thread_index);
6114   mp->queue_id = ntohl (queue_id);
6115   mp->is_main = is_main;
6116
6117   /* send it... */
6118   S (mp);
6119   /* Wait for a reply, return the good/bad news... */
6120   W (ret);
6121   return ret;
6122 }
6123
6124 static void vl_api_sw_interface_rx_placement_details_t_handler
6125   (vl_api_sw_interface_rx_placement_details_t * mp)
6126 {
6127   vat_main_t *vam = &vat_main;
6128   u32 worker_id = ntohl (mp->worker_id);
6129
6130   print (vam->ofp,
6131          "\n%-11d %-11s %-6d %-5d %-9s",
6132          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6133          worker_id, ntohl (mp->queue_id),
6134          (mp->mode ==
6135           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6136 }
6137
6138 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6139   (vl_api_sw_interface_rx_placement_details_t * mp)
6140 {
6141   vat_main_t *vam = &vat_main;
6142   vat_json_node_t *node = NULL;
6143
6144   if (VAT_JSON_ARRAY != vam->json_tree.type)
6145     {
6146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6147       vat_json_init_array (&vam->json_tree);
6148     }
6149   node = vat_json_array_add (&vam->json_tree);
6150
6151   vat_json_init_object (node);
6152   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6153   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6154   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6155   vat_json_object_add_uint (node, "mode", mp->mode);
6156 }
6157
6158 static int
6159 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6160 {
6161   unformat_input_t *i = vam->input;
6162   vl_api_sw_interface_rx_placement_dump_t *mp;
6163   vl_api_control_ping_t *mp_ping;
6164   int ret;
6165   u32 sw_if_index;
6166   u8 sw_if_index_set = 0;
6167
6168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6169     {
6170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6171         sw_if_index_set++;
6172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6173         sw_if_index_set++;
6174       else
6175         break;
6176     }
6177
6178   print (vam->ofp,
6179          "\n%-11s %-11s %-6s %-5s %-4s",
6180          "sw_if_index", "main/worker", "thread", "queue", "mode");
6181
6182   /* Dump Interface rx placement */
6183   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6184
6185   if (sw_if_index_set)
6186     mp->sw_if_index = htonl (sw_if_index);
6187   else
6188     mp->sw_if_index = ~0;
6189
6190   S (mp);
6191
6192   /* Use a control ping for synchronization */
6193   MPING (CONTROL_PING, mp_ping);
6194   S (mp_ping);
6195
6196   W (ret);
6197   return ret;
6198 }
6199
6200 static int
6201 api_sw_interface_clear_stats (vat_main_t * vam)
6202 {
6203   unformat_input_t *i = vam->input;
6204   vl_api_sw_interface_clear_stats_t *mp;
6205   u32 sw_if_index;
6206   u8 sw_if_index_set = 0;
6207   int ret;
6208
6209   /* Parse args required to build the message */
6210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6211     {
6212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6213         sw_if_index_set = 1;
6214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6215         sw_if_index_set = 1;
6216       else
6217         break;
6218     }
6219
6220   /* Construct the API message */
6221   M (SW_INTERFACE_CLEAR_STATS, mp);
6222
6223   if (sw_if_index_set == 1)
6224     mp->sw_if_index = ntohl (sw_if_index);
6225   else
6226     mp->sw_if_index = ~0;
6227
6228   /* send it... */
6229   S (mp);
6230
6231   /* Wait for a reply, return the good/bad news... */
6232   W (ret);
6233   return ret;
6234 }
6235
6236 static int
6237 api_sw_interface_add_del_address (vat_main_t * vam)
6238 {
6239   unformat_input_t *i = vam->input;
6240   vl_api_sw_interface_add_del_address_t *mp;
6241   u32 sw_if_index;
6242   u8 sw_if_index_set = 0;
6243   u8 is_add = 1, del_all = 0;
6244   u32 address_length = 0;
6245   u8 v4_address_set = 0;
6246   u8 v6_address_set = 0;
6247   ip4_address_t v4address;
6248   ip6_address_t v6address;
6249   int ret;
6250
6251   /* Parse args required to build the message */
6252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6253     {
6254       if (unformat (i, "del-all"))
6255         del_all = 1;
6256       else if (unformat (i, "del"))
6257         is_add = 0;
6258       else
6259         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6260         sw_if_index_set = 1;
6261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "%U/%d",
6264                          unformat_ip4_address, &v4address, &address_length))
6265         v4_address_set = 1;
6266       else if (unformat (i, "%U/%d",
6267                          unformat_ip6_address, &v6address, &address_length))
6268         v6_address_set = 1;
6269       else
6270         break;
6271     }
6272
6273   if (sw_if_index_set == 0)
6274     {
6275       errmsg ("missing interface name or sw_if_index");
6276       return -99;
6277     }
6278   if (v4_address_set && v6_address_set)
6279     {
6280       errmsg ("both v4 and v6 addresses set");
6281       return -99;
6282     }
6283   if (!v4_address_set && !v6_address_set && !del_all)
6284     {
6285       errmsg ("no addresses set");
6286       return -99;
6287     }
6288
6289   /* Construct the API message */
6290   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6291
6292   mp->sw_if_index = ntohl (sw_if_index);
6293   mp->is_add = is_add;
6294   mp->del_all = del_all;
6295   if (v6_address_set)
6296     {
6297       mp->is_ipv6 = 1;
6298       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6299     }
6300   else
6301     {
6302       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6303     }
6304   mp->address_length = address_length;
6305
6306   /* send it... */
6307   S (mp);
6308
6309   /* Wait for a reply, return good/bad news  */
6310   W (ret);
6311   return ret;
6312 }
6313
6314 static int
6315 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6316 {
6317   unformat_input_t *i = vam->input;
6318   vl_api_sw_interface_set_mpls_enable_t *mp;
6319   u32 sw_if_index;
6320   u8 sw_if_index_set = 0;
6321   u8 enable = 1;
6322   int ret;
6323
6324   /* Parse args required to build the message */
6325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6326     {
6327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6328         sw_if_index_set = 1;
6329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6330         sw_if_index_set = 1;
6331       else if (unformat (i, "disable"))
6332         enable = 0;
6333       else if (unformat (i, "dis"))
6334         enable = 0;
6335       else
6336         break;
6337     }
6338
6339   if (sw_if_index_set == 0)
6340     {
6341       errmsg ("missing interface name or sw_if_index");
6342       return -99;
6343     }
6344
6345   /* Construct the API message */
6346   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6347
6348   mp->sw_if_index = ntohl (sw_if_index);
6349   mp->enable = enable;
6350
6351   /* send it... */
6352   S (mp);
6353
6354   /* Wait for a reply... */
6355   W (ret);
6356   return ret;
6357 }
6358
6359 static int
6360 api_sw_interface_set_table (vat_main_t * vam)
6361 {
6362   unformat_input_t *i = vam->input;
6363   vl_api_sw_interface_set_table_t *mp;
6364   u32 sw_if_index, vrf_id = 0;
6365   u8 sw_if_index_set = 0;
6366   u8 is_ipv6 = 0;
6367   int ret;
6368
6369   /* Parse args required to build the message */
6370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6371     {
6372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6373         sw_if_index_set = 1;
6374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6375         sw_if_index_set = 1;
6376       else if (unformat (i, "vrf %d", &vrf_id))
6377         ;
6378       else if (unformat (i, "ipv6"))
6379         is_ipv6 = 1;
6380       else
6381         break;
6382     }
6383
6384   if (sw_if_index_set == 0)
6385     {
6386       errmsg ("missing interface name or sw_if_index");
6387       return -99;
6388     }
6389
6390   /* Construct the API message */
6391   M (SW_INTERFACE_SET_TABLE, mp);
6392
6393   mp->sw_if_index = ntohl (sw_if_index);
6394   mp->is_ipv6 = is_ipv6;
6395   mp->vrf_id = ntohl (vrf_id);
6396
6397   /* send it... */
6398   S (mp);
6399
6400   /* Wait for a reply... */
6401   W (ret);
6402   return ret;
6403 }
6404
6405 static void vl_api_sw_interface_get_table_reply_t_handler
6406   (vl_api_sw_interface_get_table_reply_t * mp)
6407 {
6408   vat_main_t *vam = &vat_main;
6409
6410   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6411
6412   vam->retval = ntohl (mp->retval);
6413   vam->result_ready = 1;
6414
6415 }
6416
6417 static void vl_api_sw_interface_get_table_reply_t_handler_json
6418   (vl_api_sw_interface_get_table_reply_t * mp)
6419 {
6420   vat_main_t *vam = &vat_main;
6421   vat_json_node_t node;
6422
6423   vat_json_init_object (&node);
6424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6425   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6426
6427   vat_json_print (vam->ofp, &node);
6428   vat_json_free (&node);
6429
6430   vam->retval = ntohl (mp->retval);
6431   vam->result_ready = 1;
6432 }
6433
6434 static int
6435 api_sw_interface_get_table (vat_main_t * vam)
6436 {
6437   unformat_input_t *i = vam->input;
6438   vl_api_sw_interface_get_table_t *mp;
6439   u32 sw_if_index;
6440   u8 sw_if_index_set = 0;
6441   u8 is_ipv6 = 0;
6442   int ret;
6443
6444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6445     {
6446       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6447         sw_if_index_set = 1;
6448       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6449         sw_if_index_set = 1;
6450       else if (unformat (i, "ipv6"))
6451         is_ipv6 = 1;
6452       else
6453         break;
6454     }
6455
6456   if (sw_if_index_set == 0)
6457     {
6458       errmsg ("missing interface name or sw_if_index");
6459       return -99;
6460     }
6461
6462   M (SW_INTERFACE_GET_TABLE, mp);
6463   mp->sw_if_index = htonl (sw_if_index);
6464   mp->is_ipv6 = is_ipv6;
6465
6466   S (mp);
6467   W (ret);
6468   return ret;
6469 }
6470
6471 static int
6472 api_sw_interface_set_vpath (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_sw_interface_set_vpath_t *mp;
6476   u32 sw_if_index = 0;
6477   u8 sw_if_index_set = 0;
6478   u8 is_enable = 0;
6479   int ret;
6480
6481   /* Parse args required to build the message */
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6485         sw_if_index_set = 1;
6486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6487         sw_if_index_set = 1;
6488       else if (unformat (i, "enable"))
6489         is_enable = 1;
6490       else if (unformat (i, "disable"))
6491         is_enable = 0;
6492       else
6493         break;
6494     }
6495
6496   if (sw_if_index_set == 0)
6497     {
6498       errmsg ("missing interface name or sw_if_index");
6499       return -99;
6500     }
6501
6502   /* Construct the API message */
6503   M (SW_INTERFACE_SET_VPATH, mp);
6504
6505   mp->sw_if_index = ntohl (sw_if_index);
6506   mp->enable = is_enable;
6507
6508   /* send it... */
6509   S (mp);
6510
6511   /* Wait for a reply... */
6512   W (ret);
6513   return ret;
6514 }
6515
6516 static int
6517 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6518 {
6519   unformat_input_t *i = vam->input;
6520   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6521   u32 sw_if_index = 0;
6522   u8 sw_if_index_set = 0;
6523   u8 is_enable = 1;
6524   u8 is_ipv6 = 0;
6525   int ret;
6526
6527   /* Parse args required to build the message */
6528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6529     {
6530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6531         sw_if_index_set = 1;
6532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6533         sw_if_index_set = 1;
6534       else if (unformat (i, "enable"))
6535         is_enable = 1;
6536       else if (unformat (i, "disable"))
6537         is_enable = 0;
6538       else if (unformat (i, "ip4"))
6539         is_ipv6 = 0;
6540       else if (unformat (i, "ip6"))
6541         is_ipv6 = 1;
6542       else
6543         break;
6544     }
6545
6546   if (sw_if_index_set == 0)
6547     {
6548       errmsg ("missing interface name or sw_if_index");
6549       return -99;
6550     }
6551
6552   /* Construct the API message */
6553   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6554
6555   mp->sw_if_index = ntohl (sw_if_index);
6556   mp->enable = is_enable;
6557   mp->is_ipv6 = is_ipv6;
6558
6559   /* send it... */
6560   S (mp);
6561
6562   /* Wait for a reply... */
6563   W (ret);
6564   return ret;
6565 }
6566
6567 static int
6568 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6569 {
6570   unformat_input_t *i = vam->input;
6571   vl_api_sw_interface_set_geneve_bypass_t *mp;
6572   u32 sw_if_index = 0;
6573   u8 sw_if_index_set = 0;
6574   u8 is_enable = 1;
6575   u8 is_ipv6 = 0;
6576   int ret;
6577
6578   /* Parse args required to build the message */
6579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6580     {
6581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "enable"))
6586         is_enable = 1;
6587       else if (unformat (i, "disable"))
6588         is_enable = 0;
6589       else if (unformat (i, "ip4"))
6590         is_ipv6 = 0;
6591       else if (unformat (i, "ip6"))
6592         is_ipv6 = 1;
6593       else
6594         break;
6595     }
6596
6597   if (sw_if_index_set == 0)
6598     {
6599       errmsg ("missing interface name or sw_if_index");
6600       return -99;
6601     }
6602
6603   /* Construct the API message */
6604   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6605
6606   mp->sw_if_index = ntohl (sw_if_index);
6607   mp->enable = is_enable;
6608   mp->is_ipv6 = is_ipv6;
6609
6610   /* send it... */
6611   S (mp);
6612
6613   /* Wait for a reply... */
6614   W (ret);
6615   return ret;
6616 }
6617
6618 static int
6619 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6620 {
6621   unformat_input_t *i = vam->input;
6622   vl_api_sw_interface_set_l2_xconnect_t *mp;
6623   u32 rx_sw_if_index;
6624   u8 rx_sw_if_index_set = 0;
6625   u32 tx_sw_if_index;
6626   u8 tx_sw_if_index_set = 0;
6627   u8 enable = 1;
6628   int ret;
6629
6630   /* Parse args required to build the message */
6631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6632     {
6633       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6634         rx_sw_if_index_set = 1;
6635       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6636         tx_sw_if_index_set = 1;
6637       else if (unformat (i, "rx"))
6638         {
6639           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640             {
6641               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6642                             &rx_sw_if_index))
6643                 rx_sw_if_index_set = 1;
6644             }
6645           else
6646             break;
6647         }
6648       else if (unformat (i, "tx"))
6649         {
6650           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6651             {
6652               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6653                             &tx_sw_if_index))
6654                 tx_sw_if_index_set = 1;
6655             }
6656           else
6657             break;
6658         }
6659       else if (unformat (i, "enable"))
6660         enable = 1;
6661       else if (unformat (i, "disable"))
6662         enable = 0;
6663       else
6664         break;
6665     }
6666
6667   if (rx_sw_if_index_set == 0)
6668     {
6669       errmsg ("missing rx interface name or rx_sw_if_index");
6670       return -99;
6671     }
6672
6673   if (enable && (tx_sw_if_index_set == 0))
6674     {
6675       errmsg ("missing tx interface name or tx_sw_if_index");
6676       return -99;
6677     }
6678
6679   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6680
6681   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6682   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6683   mp->enable = enable;
6684
6685   S (mp);
6686   W (ret);
6687   return ret;
6688 }
6689
6690 static int
6691 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6692 {
6693   unformat_input_t *i = vam->input;
6694   vl_api_sw_interface_set_l2_bridge_t *mp;
6695   vl_api_l2_port_type_t port_type;
6696   u32 rx_sw_if_index;
6697   u8 rx_sw_if_index_set = 0;
6698   u32 bd_id;
6699   u8 bd_id_set = 0;
6700   u32 shg = 0;
6701   u8 enable = 1;
6702   int ret;
6703
6704   port_type = L2_API_PORT_TYPE_NORMAL;
6705
6706   /* Parse args required to build the message */
6707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6708     {
6709       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6710         rx_sw_if_index_set = 1;
6711       else if (unformat (i, "bd_id %d", &bd_id))
6712         bd_id_set = 1;
6713       else
6714         if (unformat
6715             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6716         rx_sw_if_index_set = 1;
6717       else if (unformat (i, "shg %d", &shg))
6718         ;
6719       else if (unformat (i, "bvi"))
6720         port_type = L2_API_PORT_TYPE_BVI;
6721       else if (unformat (i, "uu-fwd"))
6722         port_type = L2_API_PORT_TYPE_UU_FWD;
6723       else if (unformat (i, "enable"))
6724         enable = 1;
6725       else if (unformat (i, "disable"))
6726         enable = 0;
6727       else
6728         break;
6729     }
6730
6731   if (rx_sw_if_index_set == 0)
6732     {
6733       errmsg ("missing rx interface name or sw_if_index");
6734       return -99;
6735     }
6736
6737   if (enable && (bd_id_set == 0))
6738     {
6739       errmsg ("missing bridge domain");
6740       return -99;
6741     }
6742
6743   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6744
6745   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6746   mp->bd_id = ntohl (bd_id);
6747   mp->shg = (u8) shg;
6748   mp->port_type = ntohl (port_type);
6749   mp->enable = enable;
6750
6751   S (mp);
6752   W (ret);
6753   return ret;
6754 }
6755
6756 static int
6757 api_bridge_domain_dump (vat_main_t * vam)
6758 {
6759   unformat_input_t *i = vam->input;
6760   vl_api_bridge_domain_dump_t *mp;
6761   vl_api_control_ping_t *mp_ping;
6762   u32 bd_id = ~0;
6763   int ret;
6764
6765   /* Parse args required to build the message */
6766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6767     {
6768       if (unformat (i, "bd_id %d", &bd_id))
6769         ;
6770       else
6771         break;
6772     }
6773
6774   M (BRIDGE_DOMAIN_DUMP, mp);
6775   mp->bd_id = ntohl (bd_id);
6776   S (mp);
6777
6778   /* Use a control ping for synchronization */
6779   MPING (CONTROL_PING, mp_ping);
6780   S (mp_ping);
6781
6782   W (ret);
6783   return ret;
6784 }
6785
6786 static int
6787 api_bridge_domain_add_del (vat_main_t * vam)
6788 {
6789   unformat_input_t *i = vam->input;
6790   vl_api_bridge_domain_add_del_t *mp;
6791   u32 bd_id = ~0;
6792   u8 is_add = 1;
6793   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6794   u8 *bd_tag = NULL;
6795   u32 mac_age = 0;
6796   int ret;
6797
6798   /* Parse args required to build the message */
6799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6800     {
6801       if (unformat (i, "bd_id %d", &bd_id))
6802         ;
6803       else if (unformat (i, "flood %d", &flood))
6804         ;
6805       else if (unformat (i, "uu-flood %d", &uu_flood))
6806         ;
6807       else if (unformat (i, "forward %d", &forward))
6808         ;
6809       else if (unformat (i, "learn %d", &learn))
6810         ;
6811       else if (unformat (i, "arp-term %d", &arp_term))
6812         ;
6813       else if (unformat (i, "mac-age %d", &mac_age))
6814         ;
6815       else if (unformat (i, "bd-tag %s", &bd_tag))
6816         ;
6817       else if (unformat (i, "del"))
6818         {
6819           is_add = 0;
6820           flood = uu_flood = forward = learn = 0;
6821         }
6822       else
6823         break;
6824     }
6825
6826   if (bd_id == ~0)
6827     {
6828       errmsg ("missing bridge domain");
6829       ret = -99;
6830       goto done;
6831     }
6832
6833   if (mac_age > 255)
6834     {
6835       errmsg ("mac age must be less than 256 ");
6836       ret = -99;
6837       goto done;
6838     }
6839
6840   if ((bd_tag) && (vec_len (bd_tag) > 63))
6841     {
6842       errmsg ("bd-tag cannot be longer than 63");
6843       ret = -99;
6844       goto done;
6845     }
6846
6847   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6848
6849   mp->bd_id = ntohl (bd_id);
6850   mp->flood = flood;
6851   mp->uu_flood = uu_flood;
6852   mp->forward = forward;
6853   mp->learn = learn;
6854   mp->arp_term = arp_term;
6855   mp->is_add = is_add;
6856   mp->mac_age = (u8) mac_age;
6857   if (bd_tag)
6858     {
6859       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6860       mp->bd_tag[vec_len (bd_tag)] = 0;
6861     }
6862   S (mp);
6863   W (ret);
6864
6865 done:
6866   vec_free (bd_tag);
6867   return ret;
6868 }
6869
6870 static int
6871 api_l2fib_flush_bd (vat_main_t * vam)
6872 {
6873   unformat_input_t *i = vam->input;
6874   vl_api_l2fib_flush_bd_t *mp;
6875   u32 bd_id = ~0;
6876   int ret;
6877
6878   /* Parse args required to build the message */
6879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6880     {
6881       if (unformat (i, "bd_id %d", &bd_id));
6882       else
6883         break;
6884     }
6885
6886   if (bd_id == ~0)
6887     {
6888       errmsg ("missing bridge domain");
6889       return -99;
6890     }
6891
6892   M (L2FIB_FLUSH_BD, mp);
6893
6894   mp->bd_id = htonl (bd_id);
6895
6896   S (mp);
6897   W (ret);
6898   return ret;
6899 }
6900
6901 static int
6902 api_l2fib_flush_int (vat_main_t * vam)
6903 {
6904   unformat_input_t *i = vam->input;
6905   vl_api_l2fib_flush_int_t *mp;
6906   u32 sw_if_index = ~0;
6907   int ret;
6908
6909   /* Parse args required to build the message */
6910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6911     {
6912       if (unformat (i, "sw_if_index %d", &sw_if_index));
6913       else
6914         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6915       else
6916         break;
6917     }
6918
6919   if (sw_if_index == ~0)
6920     {
6921       errmsg ("missing interface name or sw_if_index");
6922       return -99;
6923     }
6924
6925   M (L2FIB_FLUSH_INT, mp);
6926
6927   mp->sw_if_index = ntohl (sw_if_index);
6928
6929   S (mp);
6930   W (ret);
6931   return ret;
6932 }
6933
6934 static int
6935 api_l2fib_add_del (vat_main_t * vam)
6936 {
6937   unformat_input_t *i = vam->input;
6938   vl_api_l2fib_add_del_t *mp;
6939   f64 timeout;
6940   u8 mac[6] = { 0 };
6941   u8 mac_set = 0;
6942   u32 bd_id;
6943   u8 bd_id_set = 0;
6944   u32 sw_if_index = 0;
6945   u8 sw_if_index_set = 0;
6946   u8 is_add = 1;
6947   u8 static_mac = 0;
6948   u8 filter_mac = 0;
6949   u8 bvi_mac = 0;
6950   int count = 1;
6951   f64 before = 0;
6952   int j;
6953
6954   /* Parse args required to build the message */
6955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6956     {
6957       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6958         mac_set = 1;
6959       else if (unformat (i, "bd_id %d", &bd_id))
6960         bd_id_set = 1;
6961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6962         sw_if_index_set = 1;
6963       else if (unformat (i, "sw_if"))
6964         {
6965           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6966             {
6967               if (unformat
6968                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6969                 sw_if_index_set = 1;
6970             }
6971           else
6972             break;
6973         }
6974       else if (unformat (i, "static"))
6975         static_mac = 1;
6976       else if (unformat (i, "filter"))
6977         {
6978           filter_mac = 1;
6979           static_mac = 1;
6980         }
6981       else if (unformat (i, "bvi"))
6982         {
6983           bvi_mac = 1;
6984           static_mac = 1;
6985         }
6986       else if (unformat (i, "del"))
6987         is_add = 0;
6988       else if (unformat (i, "count %d", &count))
6989         ;
6990       else
6991         break;
6992     }
6993
6994   if (mac_set == 0)
6995     {
6996       errmsg ("missing mac address");
6997       return -99;
6998     }
6999
7000   if (bd_id_set == 0)
7001     {
7002       errmsg ("missing bridge domain");
7003       return -99;
7004     }
7005
7006   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7007     {
7008       errmsg ("missing interface name or sw_if_index");
7009       return -99;
7010     }
7011
7012   if (count > 1)
7013     {
7014       /* Turn on async mode */
7015       vam->async_mode = 1;
7016       vam->async_errors = 0;
7017       before = vat_time_now (vam);
7018     }
7019
7020   for (j = 0; j < count; j++)
7021     {
7022       M (L2FIB_ADD_DEL, mp);
7023
7024       clib_memcpy (mp->mac, mac, 6);
7025       mp->bd_id = ntohl (bd_id);
7026       mp->is_add = is_add;
7027       mp->sw_if_index = ntohl (sw_if_index);
7028
7029       if (is_add)
7030         {
7031           mp->static_mac = static_mac;
7032           mp->filter_mac = filter_mac;
7033           mp->bvi_mac = bvi_mac;
7034         }
7035       increment_mac_address (mac);
7036       /* send it... */
7037       S (mp);
7038     }
7039
7040   if (count > 1)
7041     {
7042       vl_api_control_ping_t *mp_ping;
7043       f64 after;
7044
7045       /* Shut off async mode */
7046       vam->async_mode = 0;
7047
7048       MPING (CONTROL_PING, mp_ping);
7049       S (mp_ping);
7050
7051       timeout = vat_time_now (vam) + 1.0;
7052       while (vat_time_now (vam) < timeout)
7053         if (vam->result_ready == 1)
7054           goto out;
7055       vam->retval = -99;
7056
7057     out:
7058       if (vam->retval == -99)
7059         errmsg ("timeout");
7060
7061       if (vam->async_errors > 0)
7062         {
7063           errmsg ("%d asynchronous errors", vam->async_errors);
7064           vam->retval = -98;
7065         }
7066       vam->async_errors = 0;
7067       after = vat_time_now (vam);
7068
7069       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7070              count, after - before, count / (after - before));
7071     }
7072   else
7073     {
7074       int ret;
7075
7076       /* Wait for a reply... */
7077       W (ret);
7078       return ret;
7079     }
7080   /* Return the good/bad news */
7081   return (vam->retval);
7082 }
7083
7084 static int
7085 api_bridge_domain_set_mac_age (vat_main_t * vam)
7086 {
7087   unformat_input_t *i = vam->input;
7088   vl_api_bridge_domain_set_mac_age_t *mp;
7089   u32 bd_id = ~0;
7090   u32 mac_age = 0;
7091   int ret;
7092
7093   /* Parse args required to build the message */
7094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7095     {
7096       if (unformat (i, "bd_id %d", &bd_id));
7097       else if (unformat (i, "mac-age %d", &mac_age));
7098       else
7099         break;
7100     }
7101
7102   if (bd_id == ~0)
7103     {
7104       errmsg ("missing bridge domain");
7105       return -99;
7106     }
7107
7108   if (mac_age > 255)
7109     {
7110       errmsg ("mac age must be less than 256 ");
7111       return -99;
7112     }
7113
7114   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7115
7116   mp->bd_id = htonl (bd_id);
7117   mp->mac_age = (u8) mac_age;
7118
7119   S (mp);
7120   W (ret);
7121   return ret;
7122 }
7123
7124 static int
7125 api_l2_flags (vat_main_t * vam)
7126 {
7127   unformat_input_t *i = vam->input;
7128   vl_api_l2_flags_t *mp;
7129   u32 sw_if_index;
7130   u32 flags = 0;
7131   u8 sw_if_index_set = 0;
7132   u8 is_set = 0;
7133   int ret;
7134
7135   /* Parse args required to build the message */
7136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7137     {
7138       if (unformat (i, "sw_if_index %d", &sw_if_index))
7139         sw_if_index_set = 1;
7140       else if (unformat (i, "sw_if"))
7141         {
7142           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7143             {
7144               if (unformat
7145                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7146                 sw_if_index_set = 1;
7147             }
7148           else
7149             break;
7150         }
7151       else if (unformat (i, "learn"))
7152         flags |= L2_LEARN;
7153       else if (unformat (i, "forward"))
7154         flags |= L2_FWD;
7155       else if (unformat (i, "flood"))
7156         flags |= L2_FLOOD;
7157       else if (unformat (i, "uu-flood"))
7158         flags |= L2_UU_FLOOD;
7159       else if (unformat (i, "arp-term"))
7160         flags |= L2_ARP_TERM;
7161       else if (unformat (i, "off"))
7162         is_set = 0;
7163       else if (unformat (i, "disable"))
7164         is_set = 0;
7165       else
7166         break;
7167     }
7168
7169   if (sw_if_index_set == 0)
7170     {
7171       errmsg ("missing interface name or sw_if_index");
7172       return -99;
7173     }
7174
7175   M (L2_FLAGS, mp);
7176
7177   mp->sw_if_index = ntohl (sw_if_index);
7178   mp->feature_bitmap = ntohl (flags);
7179   mp->is_set = is_set;
7180
7181   S (mp);
7182   W (ret);
7183   return ret;
7184 }
7185
7186 static int
7187 api_bridge_flags (vat_main_t * vam)
7188 {
7189   unformat_input_t *i = vam->input;
7190   vl_api_bridge_flags_t *mp;
7191   u32 bd_id;
7192   u8 bd_id_set = 0;
7193   u8 is_set = 1;
7194   bd_flags_t flags = 0;
7195   int ret;
7196
7197   /* Parse args required to build the message */
7198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7199     {
7200       if (unformat (i, "bd_id %d", &bd_id))
7201         bd_id_set = 1;
7202       else if (unformat (i, "learn"))
7203         flags |= BRIDGE_API_FLAG_LEARN;
7204       else if (unformat (i, "forward"))
7205         flags |= BRIDGE_API_FLAG_FWD;
7206       else if (unformat (i, "flood"))
7207         flags |= BRIDGE_API_FLAG_FLOOD;
7208       else if (unformat (i, "uu-flood"))
7209         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7210       else if (unformat (i, "arp-term"))
7211         flags |= BRIDGE_API_FLAG_ARP_TERM;
7212       else if (unformat (i, "off"))
7213         is_set = 0;
7214       else if (unformat (i, "disable"))
7215         is_set = 0;
7216       else
7217         break;
7218     }
7219
7220   if (bd_id_set == 0)
7221     {
7222       errmsg ("missing bridge domain");
7223       return -99;
7224     }
7225
7226   M (BRIDGE_FLAGS, mp);
7227
7228   mp->bd_id = ntohl (bd_id);
7229   mp->flags = ntohl (flags);
7230   mp->is_set = is_set;
7231
7232   S (mp);
7233   W (ret);
7234   return ret;
7235 }
7236
7237 static int
7238 api_bd_ip_mac_add_del (vat_main_t * vam)
7239 {
7240   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7241   vl_api_mac_address_t mac = { 0 };
7242   unformat_input_t *i = vam->input;
7243   vl_api_bd_ip_mac_add_del_t *mp;
7244   ip46_type_t type;
7245   u32 bd_id;
7246   u8 is_ipv6 = 0;
7247   u8 is_add = 1;
7248   u8 bd_id_set = 0;
7249   u8 ip_set = 0;
7250   u8 mac_set = 0;
7251   u8 macaddr[6];
7252   int ret;
7253
7254
7255   /* Parse args required to build the message */
7256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7257     {
7258       if (unformat (i, "bd_id %d", &bd_id))
7259         {
7260           bd_id_set++;
7261         }
7262       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7263         {
7264           ip_set++;
7265         }
7266       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7267         {
7268           mac_set++;
7269         }
7270       else if (unformat (i, "del"))
7271         is_add = 0;
7272       else
7273         break;
7274     }
7275
7276   if (bd_id_set == 0)
7277     {
7278       errmsg ("missing bridge domain");
7279       return -99;
7280     }
7281   else if (ip_set == 0)
7282     {
7283       errmsg ("missing IP address");
7284       return -99;
7285     }
7286   else if (mac_set == 0)
7287     {
7288       errmsg ("missing MAC address");
7289       return -99;
7290     }
7291
7292   M (BD_IP_MAC_ADD_DEL, mp);
7293
7294   mp->bd_id = ntohl (bd_id);
7295   mp->is_add = is_add;
7296
7297   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7298   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7299
7300   S (mp);
7301   W (ret);
7302   return ret;
7303 }
7304
7305 static int
7306 api_bd_ip_mac_flush (vat_main_t * vam)
7307 {
7308   unformat_input_t *i = vam->input;
7309   vl_api_bd_ip_mac_flush_t *mp;
7310   u32 bd_id;
7311   u8 bd_id_set = 0;
7312   int ret;
7313
7314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7315     {
7316       if (unformat (i, "bd_id %d", &bd_id))
7317         {
7318           bd_id_set++;
7319         }
7320       else
7321         break;
7322     }
7323
7324   if (bd_id_set == 0)
7325     {
7326       errmsg ("missing bridge domain");
7327       return -99;
7328     }
7329
7330   M (BD_IP_MAC_FLUSH, mp);
7331
7332   mp->bd_id = ntohl (bd_id);
7333
7334   S (mp);
7335   W (ret);
7336   return ret;
7337 }
7338
7339 static void vl_api_bd_ip_mac_details_t_handler
7340   (vl_api_bd_ip_mac_details_t * mp)
7341 {
7342   vat_main_t *vam = &vat_main;
7343   u8 *ip = 0;
7344
7345   if (!mp->is_ipv6)
7346     ip =
7347       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7348   else
7349     ip =
7350       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7351
7352   print (vam->ofp,
7353          "\n%-5d %-7s %-20U %-30s",
7354          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7355          format_ethernet_address, mp->mac_address, ip);
7356
7357   vec_free (ip);
7358 }
7359
7360 static void vl_api_bd_ip_mac_details_t_handler_json
7361   (vl_api_bd_ip_mac_details_t * mp)
7362 {
7363   vat_main_t *vam = &vat_main;
7364   vat_json_node_t *node = NULL;
7365
7366   if (VAT_JSON_ARRAY != vam->json_tree.type)
7367     {
7368       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7369       vat_json_init_array (&vam->json_tree);
7370     }
7371   node = vat_json_array_add (&vam->json_tree);
7372
7373   vat_json_init_object (node);
7374   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7375   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7376   vat_json_object_add_string_copy (node, "mac_address",
7377                                    format (0, "%U", format_ethernet_address,
7378                                            &mp->mac_address));
7379   u8 *ip = 0;
7380
7381   if (!mp->is_ipv6)
7382     ip =
7383       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7384   else
7385     ip =
7386       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7387   vat_json_object_add_string_copy (node, "ip_address", ip);
7388   vec_free (ip);
7389 }
7390
7391 static int
7392 api_bd_ip_mac_dump (vat_main_t * vam)
7393 {
7394   unformat_input_t *i = vam->input;
7395   vl_api_bd_ip_mac_dump_t *mp;
7396   vl_api_control_ping_t *mp_ping;
7397   int ret;
7398   u32 bd_id;
7399   u8 bd_id_set = 0;
7400
7401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7402     {
7403       if (unformat (i, "bd_id %d", &bd_id))
7404         {
7405           bd_id_set++;
7406         }
7407       else
7408         break;
7409     }
7410
7411   print (vam->ofp,
7412          "\n%-5s %-7s %-20s %-30s",
7413          "bd_id", "is_ipv6", "mac_address", "ip_address");
7414
7415   /* Dump Bridge Domain Ip to Mac entries */
7416   M (BD_IP_MAC_DUMP, mp);
7417
7418   if (bd_id_set)
7419     mp->bd_id = htonl (bd_id);
7420   else
7421     mp->bd_id = ~0;
7422
7423   S (mp);
7424
7425   /* Use a control ping for synchronization */
7426   MPING (CONTROL_PING, mp_ping);
7427   S (mp_ping);
7428
7429   W (ret);
7430   return ret;
7431 }
7432
7433 static int
7434 api_tap_create_v2 (vat_main_t * vam)
7435 {
7436   unformat_input_t *i = vam->input;
7437   vl_api_tap_create_v2_t *mp;
7438   u8 mac_address[6];
7439   u8 random_mac = 1;
7440   u32 id = ~0;
7441   u8 *host_if_name = 0;
7442   u8 *host_ns = 0;
7443   u8 host_mac_addr[6];
7444   u8 host_mac_addr_set = 0;
7445   u8 *host_bridge = 0;
7446   ip4_address_t host_ip4_addr;
7447   ip4_address_t host_ip4_gw;
7448   u8 host_ip4_gw_set = 0;
7449   u32 host_ip4_prefix_len = 0;
7450   ip6_address_t host_ip6_addr;
7451   ip6_address_t host_ip6_gw;
7452   u8 host_ip6_gw_set = 0;
7453   u32 host_ip6_prefix_len = 0;
7454   int ret;
7455   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7456
7457   clib_memset (mac_address, 0, sizeof (mac_address));
7458
7459   /* Parse args required to build the message */
7460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7461     {
7462       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7463         {
7464           random_mac = 0;
7465         }
7466       else if (unformat (i, "id %u", &id))
7467         ;
7468       else if (unformat (i, "host-if-name %s", &host_if_name))
7469         ;
7470       else if (unformat (i, "host-ns %s", &host_ns))
7471         ;
7472       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7473                          host_mac_addr))
7474         host_mac_addr_set = 1;
7475       else if (unformat (i, "host-bridge %s", &host_bridge))
7476         ;
7477       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7478                          &host_ip4_addr, &host_ip4_prefix_len))
7479         ;
7480       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7481                          &host_ip6_addr, &host_ip6_prefix_len))
7482         ;
7483       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7484                          &host_ip4_gw))
7485         host_ip4_gw_set = 1;
7486       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7487                          &host_ip6_gw))
7488         host_ip6_gw_set = 1;
7489       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7490         ;
7491       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7492         ;
7493       else
7494         break;
7495     }
7496
7497   if (vec_len (host_if_name) > 63)
7498     {
7499       errmsg ("tap name too long. ");
7500       return -99;
7501     }
7502   if (vec_len (host_ns) > 63)
7503     {
7504       errmsg ("host name space too long. ");
7505       return -99;
7506     }
7507   if (vec_len (host_bridge) > 63)
7508     {
7509       errmsg ("host bridge name too long. ");
7510       return -99;
7511     }
7512   if (host_ip4_prefix_len > 32)
7513     {
7514       errmsg ("host ip4 prefix length not valid. ");
7515       return -99;
7516     }
7517   if (host_ip6_prefix_len > 128)
7518     {
7519       errmsg ("host ip6 prefix length not valid. ");
7520       return -99;
7521     }
7522   if (!is_pow2 (rx_ring_sz))
7523     {
7524       errmsg ("rx ring size must be power of 2. ");
7525       return -99;
7526     }
7527   if (rx_ring_sz > 32768)
7528     {
7529       errmsg ("rx ring size must be 32768 or lower. ");
7530       return -99;
7531     }
7532   if (!is_pow2 (tx_ring_sz))
7533     {
7534       errmsg ("tx ring size must be power of 2. ");
7535       return -99;
7536     }
7537   if (tx_ring_sz > 32768)
7538     {
7539       errmsg ("tx ring size must be 32768 or lower. ");
7540       return -99;
7541     }
7542
7543   /* Construct the API message */
7544   M (TAP_CREATE_V2, mp);
7545
7546   mp->use_random_mac = random_mac;
7547
7548   mp->id = ntohl (id);
7549   mp->host_namespace_set = host_ns != 0;
7550   mp->host_bridge_set = host_bridge != 0;
7551   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7552   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7553   mp->rx_ring_sz = ntohs (rx_ring_sz);
7554   mp->tx_ring_sz = ntohs (tx_ring_sz);
7555
7556   if (random_mac == 0)
7557     clib_memcpy (mp->mac_address, mac_address, 6);
7558   if (host_mac_addr_set)
7559     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7560   if (host_if_name)
7561     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7562   if (host_ns)
7563     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7564   if (host_bridge)
7565     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7566   if (host_ip4_prefix_len)
7567     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7568   if (host_ip6_prefix_len)
7569     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7570   if (host_ip4_gw_set)
7571     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7572   if (host_ip6_gw_set)
7573     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7574
7575   vec_free (host_ns);
7576   vec_free (host_if_name);
7577   vec_free (host_bridge);
7578
7579   /* send it... */
7580   S (mp);
7581
7582   /* Wait for a reply... */
7583   W (ret);
7584   return ret;
7585 }
7586
7587 static int
7588 api_tap_delete_v2 (vat_main_t * vam)
7589 {
7590   unformat_input_t *i = vam->input;
7591   vl_api_tap_delete_v2_t *mp;
7592   u32 sw_if_index = ~0;
7593   u8 sw_if_index_set = 0;
7594   int ret;
7595
7596   /* Parse args required to build the message */
7597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7598     {
7599       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7600         sw_if_index_set = 1;
7601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7602         sw_if_index_set = 1;
7603       else
7604         break;
7605     }
7606
7607   if (sw_if_index_set == 0)
7608     {
7609       errmsg ("missing vpp interface name. ");
7610       return -99;
7611     }
7612
7613   /* Construct the API message */
7614   M (TAP_DELETE_V2, mp);
7615
7616   mp->sw_if_index = ntohl (sw_if_index);
7617
7618   /* send it... */
7619   S (mp);
7620
7621   /* Wait for a reply... */
7622   W (ret);
7623   return ret;
7624 }
7625
7626 uword
7627 unformat_pci_addr (unformat_input_t * input, va_list * args)
7628 {
7629   struct pci_addr_t
7630   {
7631     u16 domain;
7632     u8 bus;
7633     u8 slot:5;
7634     u8 function:3;
7635   } *addr;
7636   addr = va_arg (*args, struct pci_addr_t *);
7637   u32 x[4];
7638
7639   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7640     return 0;
7641
7642   addr->domain = x[0];
7643   addr->bus = x[1];
7644   addr->slot = x[2];
7645   addr->function = x[3];
7646
7647   return 1;
7648 }
7649
7650 static int
7651 api_virtio_pci_create (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_virtio_pci_create_t *mp;
7655   u8 mac_address[6];
7656   u8 random_mac = 1;
7657   u32 pci_addr = 0;
7658   u64 features = (u64) ~ (0ULL);
7659   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7660   int ret;
7661
7662   clib_memset (mac_address, 0, sizeof (mac_address));
7663
7664   /* Parse args required to build the message */
7665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7666     {
7667       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7668         {
7669           random_mac = 0;
7670         }
7671       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7672         ;
7673       else if (unformat (i, "features 0x%llx", &features))
7674         ;
7675       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7676         ;
7677       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7678         ;
7679       else
7680         break;
7681     }
7682
7683   if (pci_addr == 0)
7684     {
7685       errmsg ("pci address must be non zero. ");
7686       return -99;
7687     }
7688   if (!is_pow2 (rx_ring_sz))
7689     {
7690       errmsg ("rx ring size must be power of 2. ");
7691       return -99;
7692     }
7693   if (rx_ring_sz > 32768)
7694     {
7695       errmsg ("rx ring size must be 32768 or lower. ");
7696       return -99;
7697     }
7698   if (!is_pow2 (tx_ring_sz))
7699     {
7700       errmsg ("tx ring size must be power of 2. ");
7701       return -99;
7702     }
7703   if (tx_ring_sz > 32768)
7704     {
7705       errmsg ("tx ring size must be 32768 or lower. ");
7706       return -99;
7707     }
7708
7709   /* Construct the API message */
7710   M (VIRTIO_PCI_CREATE, mp);
7711
7712   mp->use_random_mac = random_mac;
7713
7714   mp->pci_addr = htonl (pci_addr);
7715   mp->features = clib_host_to_net_u64 (features);
7716   mp->rx_ring_sz = htons (rx_ring_sz);
7717   mp->tx_ring_sz = htons (tx_ring_sz);
7718
7719   if (random_mac == 0)
7720     clib_memcpy (mp->mac_address, mac_address, 6);
7721
7722   /* send it... */
7723   S (mp);
7724
7725   /* Wait for a reply... */
7726   W (ret);
7727   return ret;
7728 }
7729
7730 static int
7731 api_virtio_pci_delete (vat_main_t * vam)
7732 {
7733   unformat_input_t *i = vam->input;
7734   vl_api_virtio_pci_delete_t *mp;
7735   u32 sw_if_index = ~0;
7736   u8 sw_if_index_set = 0;
7737   int ret;
7738
7739   /* Parse args required to build the message */
7740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7741     {
7742       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7743         sw_if_index_set = 1;
7744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7745         sw_if_index_set = 1;
7746       else
7747         break;
7748     }
7749
7750   if (sw_if_index_set == 0)
7751     {
7752       errmsg ("missing vpp interface name. ");
7753       return -99;
7754     }
7755
7756   /* Construct the API message */
7757   M (VIRTIO_PCI_DELETE, mp);
7758
7759   mp->sw_if_index = htonl (sw_if_index);
7760
7761   /* send it... */
7762   S (mp);
7763
7764   /* Wait for a reply... */
7765   W (ret);
7766   return ret;
7767 }
7768
7769 static int
7770 api_bond_create (vat_main_t * vam)
7771 {
7772   unformat_input_t *i = vam->input;
7773   vl_api_bond_create_t *mp;
7774   u8 mac_address[6];
7775   u8 custom_mac = 0;
7776   int ret;
7777   u8 mode;
7778   u8 lb;
7779   u8 mode_is_set = 0;
7780   u32 id = ~0;
7781
7782   clib_memset (mac_address, 0, sizeof (mac_address));
7783   lb = BOND_LB_L2;
7784
7785   /* Parse args required to build the message */
7786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7787     {
7788       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7789         mode_is_set = 1;
7790       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7791                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7792         ;
7793       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7794                          mac_address))
7795         custom_mac = 1;
7796       else if (unformat (i, "id %u", &id))
7797         ;
7798       else
7799         break;
7800     }
7801
7802   if (mode_is_set == 0)
7803     {
7804       errmsg ("Missing bond mode. ");
7805       return -99;
7806     }
7807
7808   /* Construct the API message */
7809   M (BOND_CREATE, mp);
7810
7811   mp->use_custom_mac = custom_mac;
7812
7813   mp->mode = mode;
7814   mp->lb = lb;
7815   mp->id = htonl (id);
7816
7817   if (custom_mac)
7818     clib_memcpy (mp->mac_address, mac_address, 6);
7819
7820   /* send it... */
7821   S (mp);
7822
7823   /* Wait for a reply... */
7824   W (ret);
7825   return ret;
7826 }
7827
7828 static int
7829 api_bond_delete (vat_main_t * vam)
7830 {
7831   unformat_input_t *i = vam->input;
7832   vl_api_bond_delete_t *mp;
7833   u32 sw_if_index = ~0;
7834   u8 sw_if_index_set = 0;
7835   int ret;
7836
7837   /* Parse args required to build the message */
7838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7839     {
7840       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7841         sw_if_index_set = 1;
7842       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7843         sw_if_index_set = 1;
7844       else
7845         break;
7846     }
7847
7848   if (sw_if_index_set == 0)
7849     {
7850       errmsg ("missing vpp interface name. ");
7851       return -99;
7852     }
7853
7854   /* Construct the API message */
7855   M (BOND_DELETE, mp);
7856
7857   mp->sw_if_index = ntohl (sw_if_index);
7858
7859   /* send it... */
7860   S (mp);
7861
7862   /* Wait for a reply... */
7863   W (ret);
7864   return ret;
7865 }
7866
7867 static int
7868 api_bond_enslave (vat_main_t * vam)
7869 {
7870   unformat_input_t *i = vam->input;
7871   vl_api_bond_enslave_t *mp;
7872   u32 bond_sw_if_index;
7873   int ret;
7874   u8 is_passive;
7875   u8 is_long_timeout;
7876   u32 bond_sw_if_index_is_set = 0;
7877   u32 sw_if_index;
7878   u8 sw_if_index_is_set = 0;
7879
7880   /* Parse args required to build the message */
7881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7882     {
7883       if (unformat (i, "sw_if_index %d", &sw_if_index))
7884         sw_if_index_is_set = 1;
7885       else if (unformat (i, "bond %u", &bond_sw_if_index))
7886         bond_sw_if_index_is_set = 1;
7887       else if (unformat (i, "passive %d", &is_passive))
7888         ;
7889       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7890         ;
7891       else
7892         break;
7893     }
7894
7895   if (bond_sw_if_index_is_set == 0)
7896     {
7897       errmsg ("Missing bond sw_if_index. ");
7898       return -99;
7899     }
7900   if (sw_if_index_is_set == 0)
7901     {
7902       errmsg ("Missing slave sw_if_index. ");
7903       return -99;
7904     }
7905
7906   /* Construct the API message */
7907   M (BOND_ENSLAVE, mp);
7908
7909   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7910   mp->sw_if_index = ntohl (sw_if_index);
7911   mp->is_long_timeout = is_long_timeout;
7912   mp->is_passive = is_passive;
7913
7914   /* send it... */
7915   S (mp);
7916
7917   /* Wait for a reply... */
7918   W (ret);
7919   return ret;
7920 }
7921
7922 static int
7923 api_bond_detach_slave (vat_main_t * vam)
7924 {
7925   unformat_input_t *i = vam->input;
7926   vl_api_bond_detach_slave_t *mp;
7927   u32 sw_if_index = ~0;
7928   u8 sw_if_index_set = 0;
7929   int ret;
7930
7931   /* Parse args required to build the message */
7932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7933     {
7934       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7935         sw_if_index_set = 1;
7936       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7937         sw_if_index_set = 1;
7938       else
7939         break;
7940     }
7941
7942   if (sw_if_index_set == 0)
7943     {
7944       errmsg ("missing vpp interface name. ");
7945       return -99;
7946     }
7947
7948   /* Construct the API message */
7949   M (BOND_DETACH_SLAVE, mp);
7950
7951   mp->sw_if_index = ntohl (sw_if_index);
7952
7953   /* send it... */
7954   S (mp);
7955
7956   /* Wait for a reply... */
7957   W (ret);
7958   return ret;
7959 }
7960
7961 static int
7962 api_ip_table_add_del (vat_main_t * vam)
7963 {
7964   unformat_input_t *i = vam->input;
7965   vl_api_ip_table_add_del_t *mp;
7966   u32 table_id = ~0;
7967   u8 is_ipv6 = 0;
7968   u8 is_add = 1;
7969   int ret = 0;
7970
7971   /* Parse args required to build the message */
7972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7973     {
7974       if (unformat (i, "ipv6"))
7975         is_ipv6 = 1;
7976       else if (unformat (i, "del"))
7977         is_add = 0;
7978       else if (unformat (i, "add"))
7979         is_add = 1;
7980       else if (unformat (i, "table %d", &table_id))
7981         ;
7982       else
7983         {
7984           clib_warning ("parse error '%U'", format_unformat_error, i);
7985           return -99;
7986         }
7987     }
7988
7989   if (~0 == table_id)
7990     {
7991       errmsg ("missing table-ID");
7992       return -99;
7993     }
7994
7995   /* Construct the API message */
7996   M (IP_TABLE_ADD_DEL, mp);
7997
7998   mp->table_id = ntohl (table_id);
7999   mp->is_ipv6 = is_ipv6;
8000   mp->is_add = is_add;
8001
8002   /* send it... */
8003   S (mp);
8004
8005   /* Wait for a reply... */
8006   W (ret);
8007
8008   return ret;
8009 }
8010
8011 static int
8012 api_ip_add_del_route (vat_main_t * vam)
8013 {
8014   unformat_input_t *i = vam->input;
8015   vl_api_ip_add_del_route_t *mp;
8016   u32 sw_if_index = ~0, vrf_id = 0;
8017   u8 is_ipv6 = 0;
8018   u8 is_local = 0, is_drop = 0;
8019   u8 is_unreach = 0, is_prohibit = 0;
8020   u8 is_add = 1;
8021   u32 next_hop_weight = 1;
8022   u8 is_multipath = 0;
8023   u8 address_set = 0;
8024   u8 address_length_set = 0;
8025   u32 next_hop_table_id = 0;
8026   u32 resolve_attempts = 0;
8027   u32 dst_address_length = 0;
8028   u8 next_hop_set = 0;
8029   ip4_address_t v4_dst_address, v4_next_hop_address;
8030   ip6_address_t v6_dst_address, v6_next_hop_address;
8031   int count = 1;
8032   int j;
8033   f64 before = 0;
8034   u32 random_add_del = 0;
8035   u32 *random_vector = 0;
8036   uword *random_hash;
8037   u32 random_seed = 0xdeaddabe;
8038   u32 classify_table_index = ~0;
8039   u8 is_classify = 0;
8040   u8 resolve_host = 0, resolve_attached = 0;
8041   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8042   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8043   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8044
8045   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8046   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8047   /* Parse args required to build the message */
8048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8049     {
8050       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8051         ;
8052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8053         ;
8054       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8055         {
8056           address_set = 1;
8057           is_ipv6 = 0;
8058         }
8059       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8060         {
8061           address_set = 1;
8062           is_ipv6 = 1;
8063         }
8064       else if (unformat (i, "/%d", &dst_address_length))
8065         {
8066           address_length_set = 1;
8067         }
8068
8069       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8070                                          &v4_next_hop_address))
8071         {
8072           next_hop_set = 1;
8073         }
8074       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8075                                          &v6_next_hop_address))
8076         {
8077           next_hop_set = 1;
8078         }
8079       else
8080         if (unformat
8081             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8082         {
8083           next_hop_set = 1;
8084         }
8085       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8086         {
8087           next_hop_set = 1;
8088         }
8089       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8090         ;
8091       else if (unformat (i, "weight %d", &next_hop_weight))
8092         ;
8093       else if (unformat (i, "drop"))
8094         {
8095           is_drop = 1;
8096         }
8097       else if (unformat (i, "null-send-unreach"))
8098         {
8099           is_unreach = 1;
8100         }
8101       else if (unformat (i, "null-send-prohibit"))
8102         {
8103           is_prohibit = 1;
8104         }
8105       else if (unformat (i, "local"))
8106         {
8107           is_local = 1;
8108         }
8109       else if (unformat (i, "classify %d", &classify_table_index))
8110         {
8111           is_classify = 1;
8112         }
8113       else if (unformat (i, "del"))
8114         is_add = 0;
8115       else if (unformat (i, "add"))
8116         is_add = 1;
8117       else if (unformat (i, "resolve-via-host"))
8118         resolve_host = 1;
8119       else if (unformat (i, "resolve-via-attached"))
8120         resolve_attached = 1;
8121       else if (unformat (i, "multipath"))
8122         is_multipath = 1;
8123       else if (unformat (i, "vrf %d", &vrf_id))
8124         ;
8125       else if (unformat (i, "count %d", &count))
8126         ;
8127       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8128         ;
8129       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8130         ;
8131       else if (unformat (i, "out-label %d", &next_hop_out_label))
8132         {
8133           vl_api_fib_mpls_label_t fib_label = {
8134             .label = ntohl (next_hop_out_label),
8135             .ttl = 64,
8136             .exp = 0,
8137           };
8138           vec_add1 (next_hop_out_label_stack, fib_label);
8139         }
8140       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8141         ;
8142       else if (unformat (i, "random"))
8143         random_add_del = 1;
8144       else if (unformat (i, "seed %d", &random_seed))
8145         ;
8146       else
8147         {
8148           clib_warning ("parse error '%U'", format_unformat_error, i);
8149           return -99;
8150         }
8151     }
8152
8153   if (!next_hop_set && !is_drop && !is_local &&
8154       !is_classify && !is_unreach && !is_prohibit &&
8155       MPLS_LABEL_INVALID == next_hop_via_label)
8156     {
8157       errmsg
8158         ("next hop / local / drop / unreach / prohibit / classify not set");
8159       return -99;
8160     }
8161
8162   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8163     {
8164       errmsg ("next hop and next-hop via label set");
8165       return -99;
8166     }
8167   if (address_set == 0)
8168     {
8169       errmsg ("missing addresses");
8170       return -99;
8171     }
8172
8173   if (address_length_set == 0)
8174     {
8175       errmsg ("missing address length");
8176       return -99;
8177     }
8178
8179   /* Generate a pile of unique, random routes */
8180   if (random_add_del)
8181     {
8182       u32 this_random_address;
8183       random_hash = hash_create (count, sizeof (uword));
8184
8185       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8186       for (j = 0; j <= count; j++)
8187         {
8188           do
8189             {
8190               this_random_address = random_u32 (&random_seed);
8191               this_random_address =
8192                 clib_host_to_net_u32 (this_random_address);
8193             }
8194           while (hash_get (random_hash, this_random_address));
8195           vec_add1 (random_vector, this_random_address);
8196           hash_set (random_hash, this_random_address, 1);
8197         }
8198       hash_free (random_hash);
8199       v4_dst_address.as_u32 = random_vector[0];
8200     }
8201
8202   if (count > 1)
8203     {
8204       /* Turn on async mode */
8205       vam->async_mode = 1;
8206       vam->async_errors = 0;
8207       before = vat_time_now (vam);
8208     }
8209
8210   for (j = 0; j < count; j++)
8211     {
8212       /* Construct the API message */
8213       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8214           vec_len (next_hop_out_label_stack));
8215
8216       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8217       mp->table_id = ntohl (vrf_id);
8218
8219       mp->is_add = is_add;
8220       mp->is_drop = is_drop;
8221       mp->is_unreach = is_unreach;
8222       mp->is_prohibit = is_prohibit;
8223       mp->is_ipv6 = is_ipv6;
8224       mp->is_local = is_local;
8225       mp->is_classify = is_classify;
8226       mp->is_multipath = is_multipath;
8227       mp->is_resolve_host = resolve_host;
8228       mp->is_resolve_attached = resolve_attached;
8229       mp->next_hop_weight = next_hop_weight;
8230       mp->next_hop_preference = 0;
8231       mp->dst_address_length = dst_address_length;
8232       mp->next_hop_table_id = ntohl (next_hop_table_id);
8233       mp->classify_table_index = ntohl (classify_table_index);
8234       mp->next_hop_via_label = ntohl (next_hop_via_label);
8235       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8236       if (0 != mp->next_hop_n_out_labels)
8237         {
8238           memcpy (mp->next_hop_out_label_stack,
8239                   next_hop_out_label_stack,
8240                   (vec_len (next_hop_out_label_stack) *
8241                    sizeof (vl_api_fib_mpls_label_t)));
8242           vec_free (next_hop_out_label_stack);
8243         }
8244
8245       if (is_ipv6)
8246         {
8247           clib_memcpy (mp->dst_address, &v6_dst_address,
8248                        sizeof (v6_dst_address));
8249           if (next_hop_set)
8250             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8251                          sizeof (v6_next_hop_address));
8252           increment_v6_address (&v6_dst_address);
8253         }
8254       else
8255         {
8256           clib_memcpy (mp->dst_address, &v4_dst_address,
8257                        sizeof (v4_dst_address));
8258           if (next_hop_set)
8259             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8260                          sizeof (v4_next_hop_address));
8261           if (random_add_del)
8262             v4_dst_address.as_u32 = random_vector[j + 1];
8263           else
8264             increment_v4_address (&v4_dst_address);
8265         }
8266       /* send it... */
8267       S (mp);
8268       /* If we receive SIGTERM, stop now... */
8269       if (vam->do_exit)
8270         break;
8271     }
8272
8273   /* When testing multiple add/del ops, use a control-ping to sync */
8274   if (count > 1)
8275     {
8276       vl_api_control_ping_t *mp_ping;
8277       f64 after;
8278       f64 timeout;
8279
8280       /* Shut off async mode */
8281       vam->async_mode = 0;
8282
8283       MPING (CONTROL_PING, mp_ping);
8284       S (mp_ping);
8285
8286       timeout = vat_time_now (vam) + 1.0;
8287       while (vat_time_now (vam) < timeout)
8288         if (vam->result_ready == 1)
8289           goto out;
8290       vam->retval = -99;
8291
8292     out:
8293       if (vam->retval == -99)
8294         errmsg ("timeout");
8295
8296       if (vam->async_errors > 0)
8297         {
8298           errmsg ("%d asynchronous errors", vam->async_errors);
8299           vam->retval = -98;
8300         }
8301       vam->async_errors = 0;
8302       after = vat_time_now (vam);
8303
8304       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8305       if (j > 0)
8306         count = j;
8307
8308       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8309              count, after - before, count / (after - before));
8310     }
8311   else
8312     {
8313       int ret;
8314
8315       /* Wait for a reply... */
8316       W (ret);
8317       return ret;
8318     }
8319
8320   /* Return the good/bad news */
8321   return (vam->retval);
8322 }
8323
8324 static int
8325 api_ip_mroute_add_del (vat_main_t * vam)
8326 {
8327   unformat_input_t *i = vam->input;
8328   vl_api_ip_mroute_add_del_t *mp;
8329   u32 sw_if_index = ~0, vrf_id = 0;
8330   u8 is_ipv6 = 0;
8331   u8 is_local = 0;
8332   u8 is_add = 1;
8333   u8 address_set = 0;
8334   u32 grp_address_length = 0;
8335   ip4_address_t v4_grp_address, v4_src_address;
8336   ip6_address_t v6_grp_address, v6_src_address;
8337   mfib_itf_flags_t iflags = 0;
8338   mfib_entry_flags_t eflags = 0;
8339   int ret;
8340
8341   /* Parse args required to build the message */
8342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8343     {
8344       if (unformat (i, "sw_if_index %d", &sw_if_index))
8345         ;
8346       else if (unformat (i, "%U %U",
8347                          unformat_ip4_address, &v4_src_address,
8348                          unformat_ip4_address, &v4_grp_address))
8349         {
8350           grp_address_length = 64;
8351           address_set = 1;
8352           is_ipv6 = 0;
8353         }
8354       else if (unformat (i, "%U %U",
8355                          unformat_ip6_address, &v6_src_address,
8356                          unformat_ip6_address, &v6_grp_address))
8357         {
8358           grp_address_length = 256;
8359           address_set = 1;
8360           is_ipv6 = 1;
8361         }
8362       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8363         {
8364           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8365           grp_address_length = 32;
8366           address_set = 1;
8367           is_ipv6 = 0;
8368         }
8369       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8370         {
8371           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8372           grp_address_length = 128;
8373           address_set = 1;
8374           is_ipv6 = 1;
8375         }
8376       else if (unformat (i, "/%d", &grp_address_length))
8377         ;
8378       else if (unformat (i, "local"))
8379         {
8380           is_local = 1;
8381         }
8382       else if (unformat (i, "del"))
8383         is_add = 0;
8384       else if (unformat (i, "add"))
8385         is_add = 1;
8386       else if (unformat (i, "vrf %d", &vrf_id))
8387         ;
8388       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8389         ;
8390       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8391         ;
8392       else
8393         {
8394           clib_warning ("parse error '%U'", format_unformat_error, i);
8395           return -99;
8396         }
8397     }
8398
8399   if (address_set == 0)
8400     {
8401       errmsg ("missing addresses\n");
8402       return -99;
8403     }
8404
8405   /* Construct the API message */
8406   M (IP_MROUTE_ADD_DEL, mp);
8407
8408   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8409   mp->table_id = ntohl (vrf_id);
8410
8411   mp->is_add = is_add;
8412   mp->is_ipv6 = is_ipv6;
8413   mp->is_local = is_local;
8414   mp->itf_flags = ntohl (iflags);
8415   mp->entry_flags = ntohl (eflags);
8416   mp->grp_address_length = grp_address_length;
8417   mp->grp_address_length = ntohs (mp->grp_address_length);
8418
8419   if (is_ipv6)
8420     {
8421       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8422       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8423     }
8424   else
8425     {
8426       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8427       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8428
8429     }
8430
8431   /* send it... */
8432   S (mp);
8433   /* Wait for a reply... */
8434   W (ret);
8435   return ret;
8436 }
8437
8438 static int
8439 api_mpls_table_add_del (vat_main_t * vam)
8440 {
8441   unformat_input_t *i = vam->input;
8442   vl_api_mpls_table_add_del_t *mp;
8443   u32 table_id = ~0;
8444   u8 is_add = 1;
8445   int ret = 0;
8446
8447   /* Parse args required to build the message */
8448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8449     {
8450       if (unformat (i, "table %d", &table_id))
8451         ;
8452       else if (unformat (i, "del"))
8453         is_add = 0;
8454       else if (unformat (i, "add"))
8455         is_add = 1;
8456       else
8457         {
8458           clib_warning ("parse error '%U'", format_unformat_error, i);
8459           return -99;
8460         }
8461     }
8462
8463   if (~0 == table_id)
8464     {
8465       errmsg ("missing table-ID");
8466       return -99;
8467     }
8468
8469   /* Construct the API message */
8470   M (MPLS_TABLE_ADD_DEL, mp);
8471
8472   mp->mt_table_id = ntohl (table_id);
8473   mp->mt_is_add = is_add;
8474
8475   /* send it... */
8476   S (mp);
8477
8478   /* Wait for a reply... */
8479   W (ret);
8480
8481   return ret;
8482 }
8483
8484 static int
8485 api_mpls_route_add_del (vat_main_t * vam)
8486 {
8487   unformat_input_t *i = vam->input;
8488   vl_api_mpls_route_add_del_t *mp;
8489   u32 sw_if_index = ~0, table_id = 0;
8490   u8 is_add = 1;
8491   u32 next_hop_weight = 1;
8492   u8 is_multipath = 0;
8493   u32 next_hop_table_id = 0;
8494   u8 next_hop_set = 0;
8495   ip4_address_t v4_next_hop_address = {
8496     .as_u32 = 0,
8497   };
8498   ip6_address_t v6_next_hop_address = { {0} };
8499   int count = 1;
8500   int j;
8501   f64 before = 0;
8502   u32 classify_table_index = ~0;
8503   u8 is_classify = 0;
8504   u8 resolve_host = 0, resolve_attached = 0;
8505   u8 is_interface_rx = 0;
8506   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8507   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8508   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8509   mpls_label_t local_label = MPLS_LABEL_INVALID;
8510   u8 is_eos = 0;
8511   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8512
8513   /* Parse args required to build the message */
8514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8515     {
8516       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8517         ;
8518       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8519         ;
8520       else if (unformat (i, "%d", &local_label))
8521         ;
8522       else if (unformat (i, "eos"))
8523         is_eos = 1;
8524       else if (unformat (i, "non-eos"))
8525         is_eos = 0;
8526       else if (unformat (i, "via %U", unformat_ip4_address,
8527                          &v4_next_hop_address))
8528         {
8529           next_hop_set = 1;
8530           next_hop_proto = DPO_PROTO_IP4;
8531         }
8532       else if (unformat (i, "via %U", unformat_ip6_address,
8533                          &v6_next_hop_address))
8534         {
8535           next_hop_set = 1;
8536           next_hop_proto = DPO_PROTO_IP6;
8537         }
8538       else if (unformat (i, "weight %d", &next_hop_weight))
8539         ;
8540       else if (unformat (i, "classify %d", &classify_table_index))
8541         {
8542           is_classify = 1;
8543         }
8544       else if (unformat (i, "del"))
8545         is_add = 0;
8546       else if (unformat (i, "add"))
8547         is_add = 1;
8548       else if (unformat (i, "resolve-via-host"))
8549         resolve_host = 1;
8550       else if (unformat (i, "resolve-via-attached"))
8551         resolve_attached = 1;
8552       else if (unformat (i, "multipath"))
8553         is_multipath = 1;
8554       else if (unformat (i, "count %d", &count))
8555         ;
8556       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8557         {
8558           next_hop_set = 1;
8559           next_hop_proto = DPO_PROTO_IP4;
8560         }
8561       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8562         {
8563           next_hop_set = 1;
8564           next_hop_proto = DPO_PROTO_IP6;
8565         }
8566       else
8567         if (unformat
8568             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8569              &sw_if_index))
8570         {
8571           next_hop_set = 1;
8572           next_hop_proto = DPO_PROTO_ETHERNET;
8573           is_interface_rx = 1;
8574         }
8575       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8576         {
8577           next_hop_set = 1;
8578           next_hop_proto = DPO_PROTO_ETHERNET;
8579           is_interface_rx = 1;
8580         }
8581       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8582         next_hop_set = 1;
8583       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8584         next_hop_set = 1;
8585       else if (unformat (i, "out-label %d", &next_hop_out_label))
8586         {
8587           vl_api_fib_mpls_label_t fib_label = {
8588             .label = ntohl (next_hop_out_label),
8589             .ttl = 64,
8590             .exp = 0,
8591           };
8592           vec_add1 (next_hop_out_label_stack, fib_label);
8593         }
8594       else
8595         {
8596           clib_warning ("parse error '%U'", format_unformat_error, i);
8597           return -99;
8598         }
8599     }
8600
8601   if (!next_hop_set && !is_classify)
8602     {
8603       errmsg ("next hop / classify not set");
8604       return -99;
8605     }
8606
8607   if (MPLS_LABEL_INVALID == local_label)
8608     {
8609       errmsg ("missing label");
8610       return -99;
8611     }
8612
8613   if (count > 1)
8614     {
8615       /* Turn on async mode */
8616       vam->async_mode = 1;
8617       vam->async_errors = 0;
8618       before = vat_time_now (vam);
8619     }
8620
8621   for (j = 0; j < count; j++)
8622     {
8623       /* Construct the API message */
8624       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8625           vec_len (next_hop_out_label_stack));
8626
8627       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8628       mp->mr_table_id = ntohl (table_id);
8629
8630       mp->mr_is_add = is_add;
8631       mp->mr_next_hop_proto = next_hop_proto;
8632       mp->mr_is_classify = is_classify;
8633       mp->mr_is_multipath = is_multipath;
8634       mp->mr_is_resolve_host = resolve_host;
8635       mp->mr_is_resolve_attached = resolve_attached;
8636       mp->mr_is_interface_rx = is_interface_rx;
8637       mp->mr_next_hop_weight = next_hop_weight;
8638       mp->mr_next_hop_preference = 0;
8639       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8640       mp->mr_classify_table_index = ntohl (classify_table_index);
8641       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8642       mp->mr_label = ntohl (local_label);
8643       mp->mr_eos = is_eos;
8644
8645       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8646       if (0 != mp->mr_next_hop_n_out_labels)
8647         {
8648           memcpy (mp->mr_next_hop_out_label_stack,
8649                   next_hop_out_label_stack,
8650                   vec_len (next_hop_out_label_stack) *
8651                   sizeof (vl_api_fib_mpls_label_t));
8652           vec_free (next_hop_out_label_stack);
8653         }
8654
8655       if (next_hop_set)
8656         {
8657           if (DPO_PROTO_IP4 == next_hop_proto)
8658             {
8659               clib_memcpy (mp->mr_next_hop,
8660                            &v4_next_hop_address,
8661                            sizeof (v4_next_hop_address));
8662             }
8663           else if (DPO_PROTO_IP6 == next_hop_proto)
8664
8665             {
8666               clib_memcpy (mp->mr_next_hop,
8667                            &v6_next_hop_address,
8668                            sizeof (v6_next_hop_address));
8669             }
8670         }
8671       local_label++;
8672
8673       /* send it... */
8674       S (mp);
8675       /* If we receive SIGTERM, stop now... */
8676       if (vam->do_exit)
8677         break;
8678     }
8679
8680   /* When testing multiple add/del ops, use a control-ping to sync */
8681   if (count > 1)
8682     {
8683       vl_api_control_ping_t *mp_ping;
8684       f64 after;
8685       f64 timeout;
8686
8687       /* Shut off async mode */
8688       vam->async_mode = 0;
8689
8690       MPING (CONTROL_PING, mp_ping);
8691       S (mp_ping);
8692
8693       timeout = vat_time_now (vam) + 1.0;
8694       while (vat_time_now (vam) < timeout)
8695         if (vam->result_ready == 1)
8696           goto out;
8697       vam->retval = -99;
8698
8699     out:
8700       if (vam->retval == -99)
8701         errmsg ("timeout");
8702
8703       if (vam->async_errors > 0)
8704         {
8705           errmsg ("%d asynchronous errors", vam->async_errors);
8706           vam->retval = -98;
8707         }
8708       vam->async_errors = 0;
8709       after = vat_time_now (vam);
8710
8711       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8712       if (j > 0)
8713         count = j;
8714
8715       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8716              count, after - before, count / (after - before));
8717     }
8718   else
8719     {
8720       int ret;
8721
8722       /* Wait for a reply... */
8723       W (ret);
8724       return ret;
8725     }
8726
8727   /* Return the good/bad news */
8728   return (vam->retval);
8729 }
8730
8731 static int
8732 api_mpls_ip_bind_unbind (vat_main_t * vam)
8733 {
8734   unformat_input_t *i = vam->input;
8735   vl_api_mpls_ip_bind_unbind_t *mp;
8736   u32 ip_table_id = 0;
8737   u8 is_bind = 1;
8738   u8 is_ip4 = 1;
8739   ip4_address_t v4_address;
8740   ip6_address_t v6_address;
8741   u32 address_length;
8742   u8 address_set = 0;
8743   mpls_label_t local_label = MPLS_LABEL_INVALID;
8744   int ret;
8745
8746   /* Parse args required to build the message */
8747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8748     {
8749       if (unformat (i, "%U/%d", unformat_ip4_address,
8750                     &v4_address, &address_length))
8751         {
8752           is_ip4 = 1;
8753           address_set = 1;
8754         }
8755       else if (unformat (i, "%U/%d", unformat_ip6_address,
8756                          &v6_address, &address_length))
8757         {
8758           is_ip4 = 0;
8759           address_set = 1;
8760         }
8761       else if (unformat (i, "%d", &local_label))
8762         ;
8763       else if (unformat (i, "table-id %d", &ip_table_id))
8764         ;
8765       else if (unformat (i, "unbind"))
8766         is_bind = 0;
8767       else if (unformat (i, "bind"))
8768         is_bind = 1;
8769       else
8770         {
8771           clib_warning ("parse error '%U'", format_unformat_error, i);
8772           return -99;
8773         }
8774     }
8775
8776   if (!address_set)
8777     {
8778       errmsg ("IP address not set");
8779       return -99;
8780     }
8781
8782   if (MPLS_LABEL_INVALID == local_label)
8783     {
8784       errmsg ("missing label");
8785       return -99;
8786     }
8787
8788   /* Construct the API message */
8789   M (MPLS_IP_BIND_UNBIND, mp);
8790
8791   mp->mb_is_bind = is_bind;
8792   mp->mb_is_ip4 = is_ip4;
8793   mp->mb_ip_table_id = ntohl (ip_table_id);
8794   mp->mb_mpls_table_id = 0;
8795   mp->mb_label = ntohl (local_label);
8796   mp->mb_address_length = address_length;
8797
8798   if (is_ip4)
8799     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8800   else
8801     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8802
8803   /* send it... */
8804   S (mp);
8805
8806   /* Wait for a reply... */
8807   W (ret);
8808   return ret;
8809 }
8810
8811 static int
8812 api_sr_mpls_policy_add (vat_main_t * vam)
8813 {
8814   unformat_input_t *i = vam->input;
8815   vl_api_sr_mpls_policy_add_t *mp;
8816   u32 bsid = 0;
8817   u32 weight = 1;
8818   u8 type = 0;
8819   u8 n_segments = 0;
8820   u32 sid;
8821   u32 *segments = NULL;
8822   int ret;
8823
8824   /* Parse args required to build the message */
8825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8826     {
8827       if (unformat (i, "bsid %d", &bsid))
8828         ;
8829       else if (unformat (i, "weight %d", &weight))
8830         ;
8831       else if (unformat (i, "spray"))
8832         type = 1;
8833       else if (unformat (i, "next %d", &sid))
8834         {
8835           n_segments += 1;
8836           vec_add1 (segments, htonl (sid));
8837         }
8838       else
8839         {
8840           clib_warning ("parse error '%U'", format_unformat_error, i);
8841           return -99;
8842         }
8843     }
8844
8845   if (bsid == 0)
8846     {
8847       errmsg ("bsid not set");
8848       return -99;
8849     }
8850
8851   if (n_segments == 0)
8852     {
8853       errmsg ("no sid in segment stack");
8854       return -99;
8855     }
8856
8857   /* Construct the API message */
8858   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8859
8860   mp->bsid = htonl (bsid);
8861   mp->weight = htonl (weight);
8862   mp->type = type;
8863   mp->n_segments = n_segments;
8864   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8865   vec_free (segments);
8866
8867   /* send it... */
8868   S (mp);
8869
8870   /* Wait for a reply... */
8871   W (ret);
8872   return ret;
8873 }
8874
8875 static int
8876 api_sr_mpls_policy_del (vat_main_t * vam)
8877 {
8878   unformat_input_t *i = vam->input;
8879   vl_api_sr_mpls_policy_del_t *mp;
8880   u32 bsid = 0;
8881   int ret;
8882
8883   /* Parse args required to build the message */
8884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8885     {
8886       if (unformat (i, "bsid %d", &bsid))
8887         ;
8888       else
8889         {
8890           clib_warning ("parse error '%U'", format_unformat_error, i);
8891           return -99;
8892         }
8893     }
8894
8895   if (bsid == 0)
8896     {
8897       errmsg ("bsid not set");
8898       return -99;
8899     }
8900
8901   /* Construct the API message */
8902   M (SR_MPLS_POLICY_DEL, mp);
8903
8904   mp->bsid = htonl (bsid);
8905
8906   /* send it... */
8907   S (mp);
8908
8909   /* Wait for a reply... */
8910   W (ret);
8911   return ret;
8912 }
8913
8914 static int
8915 api_bier_table_add_del (vat_main_t * vam)
8916 {
8917   unformat_input_t *i = vam->input;
8918   vl_api_bier_table_add_del_t *mp;
8919   u8 is_add = 1;
8920   u32 set = 0, sub_domain = 0, hdr_len = 3;
8921   mpls_label_t local_label = MPLS_LABEL_INVALID;
8922   int ret;
8923
8924   /* Parse args required to build the message */
8925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8926     {
8927       if (unformat (i, "sub-domain %d", &sub_domain))
8928         ;
8929       else if (unformat (i, "set %d", &set))
8930         ;
8931       else if (unformat (i, "label %d", &local_label))
8932         ;
8933       else if (unformat (i, "hdr-len %d", &hdr_len))
8934         ;
8935       else if (unformat (i, "add"))
8936         is_add = 1;
8937       else if (unformat (i, "del"))
8938         is_add = 0;
8939       else
8940         {
8941           clib_warning ("parse error '%U'", format_unformat_error, i);
8942           return -99;
8943         }
8944     }
8945
8946   if (MPLS_LABEL_INVALID == local_label)
8947     {
8948       errmsg ("missing label\n");
8949       return -99;
8950     }
8951
8952   /* Construct the API message */
8953   M (BIER_TABLE_ADD_DEL, mp);
8954
8955   mp->bt_is_add = is_add;
8956   mp->bt_label = ntohl (local_label);
8957   mp->bt_tbl_id.bt_set = set;
8958   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8959   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8960
8961   /* send it... */
8962   S (mp);
8963
8964   /* Wait for a reply... */
8965   W (ret);
8966
8967   return (ret);
8968 }
8969
8970 static int
8971 api_bier_route_add_del (vat_main_t * vam)
8972 {
8973   unformat_input_t *i = vam->input;
8974   vl_api_bier_route_add_del_t *mp;
8975   u8 is_add = 1;
8976   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8977   ip4_address_t v4_next_hop_address;
8978   ip6_address_t v6_next_hop_address;
8979   u8 next_hop_set = 0;
8980   u8 next_hop_proto_is_ip4 = 1;
8981   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8982   int ret;
8983
8984   /* Parse args required to build the message */
8985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8986     {
8987       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8988         {
8989           next_hop_proto_is_ip4 = 1;
8990           next_hop_set = 1;
8991         }
8992       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8993         {
8994           next_hop_proto_is_ip4 = 0;
8995           next_hop_set = 1;
8996         }
8997       if (unformat (i, "sub-domain %d", &sub_domain))
8998         ;
8999       else if (unformat (i, "set %d", &set))
9000         ;
9001       else if (unformat (i, "hdr-len %d", &hdr_len))
9002         ;
9003       else if (unformat (i, "bp %d", &bp))
9004         ;
9005       else if (unformat (i, "add"))
9006         is_add = 1;
9007       else if (unformat (i, "del"))
9008         is_add = 0;
9009       else if (unformat (i, "out-label %d", &next_hop_out_label))
9010         ;
9011       else
9012         {
9013           clib_warning ("parse error '%U'", format_unformat_error, i);
9014           return -99;
9015         }
9016     }
9017
9018   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9019     {
9020       errmsg ("next hop / label set\n");
9021       return -99;
9022     }
9023   if (0 == bp)
9024     {
9025       errmsg ("bit=position not set\n");
9026       return -99;
9027     }
9028
9029   /* Construct the API message */
9030   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9031
9032   mp->br_is_add = is_add;
9033   mp->br_tbl_id.bt_set = set;
9034   mp->br_tbl_id.bt_sub_domain = sub_domain;
9035   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9036   mp->br_bp = ntohs (bp);
9037   mp->br_n_paths = 1;
9038   mp->br_paths[0].n_labels = 1;
9039   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9040   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9041
9042   if (next_hop_proto_is_ip4)
9043     {
9044       clib_memcpy (mp->br_paths[0].next_hop,
9045                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9046     }
9047   else
9048     {
9049       clib_memcpy (mp->br_paths[0].next_hop,
9050                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9051     }
9052
9053   /* send it... */
9054   S (mp);
9055
9056   /* Wait for a reply... */
9057   W (ret);
9058
9059   return (ret);
9060 }
9061
9062 static int
9063 api_proxy_arp_add_del (vat_main_t * vam)
9064 {
9065   unformat_input_t *i = vam->input;
9066   vl_api_proxy_arp_add_del_t *mp;
9067   u32 vrf_id = 0;
9068   u8 is_add = 1;
9069   vl_api_ip4_address_t lo, hi;
9070   u8 range_set = 0;
9071   int ret;
9072
9073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9074     {
9075       if (unformat (i, "vrf %d", &vrf_id))
9076         ;
9077       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9078                          unformat_vl_api_ip4_address, &hi))
9079         range_set = 1;
9080       else if (unformat (i, "del"))
9081         is_add = 0;
9082       else
9083         {
9084           clib_warning ("parse error '%U'", format_unformat_error, i);
9085           return -99;
9086         }
9087     }
9088
9089   if (range_set == 0)
9090     {
9091       errmsg ("address range not set");
9092       return -99;
9093     }
9094
9095   M (PROXY_ARP_ADD_DEL, mp);
9096
9097   mp->proxy.table_id = ntohl (vrf_id);
9098   mp->is_add = is_add;
9099   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9100   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9101
9102   S (mp);
9103   W (ret);
9104   return ret;
9105 }
9106
9107 static int
9108 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9109 {
9110   unformat_input_t *i = vam->input;
9111   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9112   u32 sw_if_index;
9113   u8 enable = 1;
9114   u8 sw_if_index_set = 0;
9115   int ret;
9116
9117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9118     {
9119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9120         sw_if_index_set = 1;
9121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9122         sw_if_index_set = 1;
9123       else if (unformat (i, "enable"))
9124         enable = 1;
9125       else if (unformat (i, "disable"))
9126         enable = 0;
9127       else
9128         {
9129           clib_warning ("parse error '%U'", format_unformat_error, i);
9130           return -99;
9131         }
9132     }
9133
9134   if (sw_if_index_set == 0)
9135     {
9136       errmsg ("missing interface name or sw_if_index");
9137       return -99;
9138     }
9139
9140   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9141
9142   mp->sw_if_index = ntohl (sw_if_index);
9143   mp->enable_disable = enable;
9144
9145   S (mp);
9146   W (ret);
9147   return ret;
9148 }
9149
9150 static int
9151 api_mpls_tunnel_add_del (vat_main_t * vam)
9152 {
9153   unformat_input_t *i = vam->input;
9154   vl_api_mpls_tunnel_add_del_t *mp;
9155
9156   u8 is_add = 1;
9157   u8 l2_only = 0;
9158   u32 sw_if_index = ~0;
9159   u32 next_hop_sw_if_index = ~0;
9160   u32 next_hop_proto_is_ip4 = 1;
9161
9162   u32 next_hop_table_id = 0;
9163   ip4_address_t v4_next_hop_address = {
9164     .as_u32 = 0,
9165   };
9166   ip6_address_t v6_next_hop_address = { {0} };
9167   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9168   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9169   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9170   int ret;
9171
9172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9173     {
9174       if (unformat (i, "add"))
9175         is_add = 1;
9176       else
9177         if (unformat
9178             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9179         is_add = 0;
9180       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9181         is_add = 0;
9182       else if (unformat (i, "via %U",
9183                          unformat_ip4_address, &v4_next_hop_address))
9184         {
9185           next_hop_proto_is_ip4 = 1;
9186         }
9187       else if (unformat (i, "via %U",
9188                          unformat_ip6_address, &v6_next_hop_address))
9189         {
9190           next_hop_proto_is_ip4 = 0;
9191         }
9192       else if (unformat (i, "via-label %d", &next_hop_via_label))
9193         ;
9194       else
9195         if (unformat
9196             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9197         ;
9198       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9199         ;
9200       else if (unformat (i, "l2-only"))
9201         l2_only = 1;
9202       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9203         ;
9204       else if (unformat (i, "out-label %d", &next_hop_out_label))
9205         {
9206           vl_api_fib_mpls_label_t fib_label = {
9207             .label = ntohl (next_hop_out_label),
9208             .ttl = 64,
9209             .exp = 0,
9210           };
9211           vec_add1 (next_hop_out_label_stack, fib_label);
9212         }
9213       else
9214         {
9215           clib_warning ("parse error '%U'", format_unformat_error, i);
9216           return -99;
9217         }
9218     }
9219
9220   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9221       vec_len (next_hop_out_label_stack));
9222
9223   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9224   mp->mt_sw_if_index = ntohl (sw_if_index);
9225   mp->mt_is_add = is_add;
9226   mp->mt_l2_only = l2_only;
9227   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9228   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9229   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9230   mp->mt_next_hop_weight = 1;
9231   mp->mt_next_hop_preference = 0;
9232
9233   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9234
9235   if (0 != mp->mt_next_hop_n_out_labels)
9236     {
9237       clib_memcpy (mp->mt_next_hop_out_label_stack,
9238                    next_hop_out_label_stack,
9239                    (vec_len (next_hop_out_label_stack) *
9240                     sizeof (vl_api_fib_mpls_label_t)));
9241       vec_free (next_hop_out_label_stack);
9242     }
9243
9244   if (next_hop_proto_is_ip4)
9245     {
9246       clib_memcpy (mp->mt_next_hop,
9247                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9248     }
9249   else
9250     {
9251       clib_memcpy (mp->mt_next_hop,
9252                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9253     }
9254
9255   S (mp);
9256   W (ret);
9257   return ret;
9258 }
9259
9260 static int
9261 api_sw_interface_set_unnumbered (vat_main_t * vam)
9262 {
9263   unformat_input_t *i = vam->input;
9264   vl_api_sw_interface_set_unnumbered_t *mp;
9265   u32 sw_if_index;
9266   u32 unnum_sw_index = ~0;
9267   u8 is_add = 1;
9268   u8 sw_if_index_set = 0;
9269   int ret;
9270
9271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9272     {
9273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9274         sw_if_index_set = 1;
9275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9276         sw_if_index_set = 1;
9277       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9278         ;
9279       else if (unformat (i, "del"))
9280         is_add = 0;
9281       else
9282         {
9283           clib_warning ("parse error '%U'", format_unformat_error, i);
9284           return -99;
9285         }
9286     }
9287
9288   if (sw_if_index_set == 0)
9289     {
9290       errmsg ("missing interface name or sw_if_index");
9291       return -99;
9292     }
9293
9294   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9295
9296   mp->sw_if_index = ntohl (sw_if_index);
9297   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9298   mp->is_add = is_add;
9299
9300   S (mp);
9301   W (ret);
9302   return ret;
9303 }
9304
9305 static int
9306 api_ip_neighbor_add_del (vat_main_t * vam)
9307 {
9308   vl_api_mac_address_t mac_address;
9309   unformat_input_t *i = vam->input;
9310   vl_api_ip_neighbor_add_del_t *mp;
9311   vl_api_address_t ip_address;
9312   u32 sw_if_index;
9313   u8 sw_if_index_set = 0;
9314   u8 is_add = 1;
9315   u8 mac_set = 0;
9316   u8 address_set = 0;
9317   int ret;
9318   ip_neighbor_flags_t flags;
9319
9320   flags = IP_NEIGHBOR_FLAG_NONE;
9321   clib_memset (&ip_address, 0, sizeof (ip_address));
9322   clib_memset (&mac_address, 0, sizeof (mac_address));
9323   /* Parse args required to build the message */
9324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9325     {
9326       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9327         {
9328           mac_set = 1;
9329         }
9330       else if (unformat (i, "del"))
9331         is_add = 0;
9332       else
9333         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9334         sw_if_index_set = 1;
9335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9336         sw_if_index_set = 1;
9337       else if (unformat (i, "static"))
9338         flags |= IP_NEIGHBOR_FLAG_STATIC;
9339       else if (unformat (i, "no-fib-entry"))
9340         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9341       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9342         address_set = 1;
9343       else
9344         {
9345           clib_warning ("parse error '%U'", format_unformat_error, i);
9346           return -99;
9347         }
9348     }
9349
9350   if (sw_if_index_set == 0)
9351     {
9352       errmsg ("missing interface name or sw_if_index");
9353       return -99;
9354     }
9355   if (!address_set)
9356     {
9357       errmsg ("no address set");
9358       return -99;
9359     }
9360
9361   /* Construct the API message */
9362   M (IP_NEIGHBOR_ADD_DEL, mp);
9363
9364   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9365   mp->is_add = is_add;
9366   mp->neighbor.flags = htonl (flags);
9367   if (mac_set)
9368     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9369                  sizeof (mac_address));
9370   if (address_set)
9371     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9372
9373   /* send it... */
9374   S (mp);
9375
9376   /* Wait for a reply, return good/bad news  */
9377   W (ret);
9378   return ret;
9379 }
9380
9381 static int
9382 api_create_vlan_subif (vat_main_t * vam)
9383 {
9384   unformat_input_t *i = vam->input;
9385   vl_api_create_vlan_subif_t *mp;
9386   u32 sw_if_index;
9387   u8 sw_if_index_set = 0;
9388   u32 vlan_id;
9389   u8 vlan_id_set = 0;
9390   int ret;
9391
9392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9393     {
9394       if (unformat (i, "sw_if_index %d", &sw_if_index))
9395         sw_if_index_set = 1;
9396       else
9397         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9398         sw_if_index_set = 1;
9399       else if (unformat (i, "vlan %d", &vlan_id))
9400         vlan_id_set = 1;
9401       else
9402         {
9403           clib_warning ("parse error '%U'", format_unformat_error, i);
9404           return -99;
9405         }
9406     }
9407
9408   if (sw_if_index_set == 0)
9409     {
9410       errmsg ("missing interface name or sw_if_index");
9411       return -99;
9412     }
9413
9414   if (vlan_id_set == 0)
9415     {
9416       errmsg ("missing vlan_id");
9417       return -99;
9418     }
9419   M (CREATE_VLAN_SUBIF, mp);
9420
9421   mp->sw_if_index = ntohl (sw_if_index);
9422   mp->vlan_id = ntohl (vlan_id);
9423
9424   S (mp);
9425   W (ret);
9426   return ret;
9427 }
9428
9429 #define foreach_create_subif_bit                \
9430 _(no_tags)                                      \
9431 _(one_tag)                                      \
9432 _(two_tags)                                     \
9433 _(dot1ad)                                       \
9434 _(exact_match)                                  \
9435 _(default_sub)                                  \
9436 _(outer_vlan_id_any)                            \
9437 _(inner_vlan_id_any)
9438
9439 static int
9440 api_create_subif (vat_main_t * vam)
9441 {
9442   unformat_input_t *i = vam->input;
9443   vl_api_create_subif_t *mp;
9444   u32 sw_if_index;
9445   u8 sw_if_index_set = 0;
9446   u32 sub_id;
9447   u8 sub_id_set = 0;
9448   u32 no_tags = 0;
9449   u32 one_tag = 0;
9450   u32 two_tags = 0;
9451   u32 dot1ad = 0;
9452   u32 exact_match = 0;
9453   u32 default_sub = 0;
9454   u32 outer_vlan_id_any = 0;
9455   u32 inner_vlan_id_any = 0;
9456   u32 tmp;
9457   u16 outer_vlan_id = 0;
9458   u16 inner_vlan_id = 0;
9459   int ret;
9460
9461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9462     {
9463       if (unformat (i, "sw_if_index %d", &sw_if_index))
9464         sw_if_index_set = 1;
9465       else
9466         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9467         sw_if_index_set = 1;
9468       else if (unformat (i, "sub_id %d", &sub_id))
9469         sub_id_set = 1;
9470       else if (unformat (i, "outer_vlan_id %d", &tmp))
9471         outer_vlan_id = tmp;
9472       else if (unformat (i, "inner_vlan_id %d", &tmp))
9473         inner_vlan_id = tmp;
9474
9475 #define _(a) else if (unformat (i, #a)) a = 1 ;
9476       foreach_create_subif_bit
9477 #undef _
9478         else
9479         {
9480           clib_warning ("parse error '%U'", format_unformat_error, i);
9481           return -99;
9482         }
9483     }
9484
9485   if (sw_if_index_set == 0)
9486     {
9487       errmsg ("missing interface name or sw_if_index");
9488       return -99;
9489     }
9490
9491   if (sub_id_set == 0)
9492     {
9493       errmsg ("missing sub_id");
9494       return -99;
9495     }
9496   M (CREATE_SUBIF, mp);
9497
9498   mp->sw_if_index = ntohl (sw_if_index);
9499   mp->sub_id = ntohl (sub_id);
9500
9501 #define _(a) mp->a = a;
9502   foreach_create_subif_bit;
9503 #undef _
9504
9505   mp->outer_vlan_id = ntohs (outer_vlan_id);
9506   mp->inner_vlan_id = ntohs (inner_vlan_id);
9507
9508   S (mp);
9509   W (ret);
9510   return ret;
9511 }
9512
9513 static int
9514 api_oam_add_del (vat_main_t * vam)
9515 {
9516   unformat_input_t *i = vam->input;
9517   vl_api_oam_add_del_t *mp;
9518   u32 vrf_id = 0;
9519   u8 is_add = 1;
9520   ip4_address_t src, dst;
9521   u8 src_set = 0;
9522   u8 dst_set = 0;
9523   int ret;
9524
9525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9526     {
9527       if (unformat (i, "vrf %d", &vrf_id))
9528         ;
9529       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9530         src_set = 1;
9531       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9532         dst_set = 1;
9533       else if (unformat (i, "del"))
9534         is_add = 0;
9535       else
9536         {
9537           clib_warning ("parse error '%U'", format_unformat_error, i);
9538           return -99;
9539         }
9540     }
9541
9542   if (src_set == 0)
9543     {
9544       errmsg ("missing src addr");
9545       return -99;
9546     }
9547
9548   if (dst_set == 0)
9549     {
9550       errmsg ("missing dst addr");
9551       return -99;
9552     }
9553
9554   M (OAM_ADD_DEL, mp);
9555
9556   mp->vrf_id = ntohl (vrf_id);
9557   mp->is_add = is_add;
9558   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9559   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9560
9561   S (mp);
9562   W (ret);
9563   return ret;
9564 }
9565
9566 static int
9567 api_reset_fib (vat_main_t * vam)
9568 {
9569   unformat_input_t *i = vam->input;
9570   vl_api_reset_fib_t *mp;
9571   u32 vrf_id = 0;
9572   u8 is_ipv6 = 0;
9573   u8 vrf_id_set = 0;
9574
9575   int ret;
9576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9577     {
9578       if (unformat (i, "vrf %d", &vrf_id))
9579         vrf_id_set = 1;
9580       else if (unformat (i, "ipv6"))
9581         is_ipv6 = 1;
9582       else
9583         {
9584           clib_warning ("parse error '%U'", format_unformat_error, i);
9585           return -99;
9586         }
9587     }
9588
9589   if (vrf_id_set == 0)
9590     {
9591       errmsg ("missing vrf id");
9592       return -99;
9593     }
9594
9595   M (RESET_FIB, mp);
9596
9597   mp->vrf_id = ntohl (vrf_id);
9598   mp->is_ipv6 = is_ipv6;
9599
9600   S (mp);
9601   W (ret);
9602   return ret;
9603 }
9604
9605 static int
9606 api_dhcp_proxy_config (vat_main_t * vam)
9607 {
9608   unformat_input_t *i = vam->input;
9609   vl_api_dhcp_proxy_config_t *mp;
9610   u32 rx_vrf_id = 0;
9611   u32 server_vrf_id = 0;
9612   u8 is_add = 1;
9613   u8 v4_address_set = 0;
9614   u8 v6_address_set = 0;
9615   ip4_address_t v4address;
9616   ip6_address_t v6address;
9617   u8 v4_src_address_set = 0;
9618   u8 v6_src_address_set = 0;
9619   ip4_address_t v4srcaddress;
9620   ip6_address_t v6srcaddress;
9621   int ret;
9622
9623   /* Parse args required to build the message */
9624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9625     {
9626       if (unformat (i, "del"))
9627         is_add = 0;
9628       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9629         ;
9630       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9631         ;
9632       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9633         v4_address_set = 1;
9634       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9635         v6_address_set = 1;
9636       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9637         v4_src_address_set = 1;
9638       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9639         v6_src_address_set = 1;
9640       else
9641         break;
9642     }
9643
9644   if (v4_address_set && v6_address_set)
9645     {
9646       errmsg ("both v4 and v6 server addresses set");
9647       return -99;
9648     }
9649   if (!v4_address_set && !v6_address_set)
9650     {
9651       errmsg ("no server addresses set");
9652       return -99;
9653     }
9654
9655   if (v4_src_address_set && v6_src_address_set)
9656     {
9657       errmsg ("both v4 and v6  src addresses set");
9658       return -99;
9659     }
9660   if (!v4_src_address_set && !v6_src_address_set)
9661     {
9662       errmsg ("no src addresses set");
9663       return -99;
9664     }
9665
9666   if (!(v4_src_address_set && v4_address_set) &&
9667       !(v6_src_address_set && v6_address_set))
9668     {
9669       errmsg ("no matching server and src addresses set");
9670       return -99;
9671     }
9672
9673   /* Construct the API message */
9674   M (DHCP_PROXY_CONFIG, mp);
9675
9676   mp->is_add = is_add;
9677   mp->rx_vrf_id = ntohl (rx_vrf_id);
9678   mp->server_vrf_id = ntohl (server_vrf_id);
9679   if (v6_address_set)
9680     {
9681       mp->is_ipv6 = 1;
9682       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9683       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9684     }
9685   else
9686     {
9687       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9688       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9689     }
9690
9691   /* send it... */
9692   S (mp);
9693
9694   /* Wait for a reply, return good/bad news  */
9695   W (ret);
9696   return ret;
9697 }
9698
9699 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9700 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9701
9702 static void
9703 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9704 {
9705   vat_main_t *vam = &vat_main;
9706   u32 i, count = mp->count;
9707   vl_api_dhcp_server_t *s;
9708
9709   if (mp->is_ipv6)
9710     print (vam->ofp,
9711            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9712            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9713            ntohl (mp->rx_vrf_id),
9714            format_ip6_address, mp->dhcp_src_address,
9715            mp->vss_type, mp->vss_vpn_ascii_id,
9716            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9717   else
9718     print (vam->ofp,
9719            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9720            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9721            ntohl (mp->rx_vrf_id),
9722            format_ip4_address, mp->dhcp_src_address,
9723            mp->vss_type, mp->vss_vpn_ascii_id,
9724            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9725
9726   for (i = 0; i < count; i++)
9727     {
9728       s = &mp->servers[i];
9729
9730       if (mp->is_ipv6)
9731         print (vam->ofp,
9732                " Server Table-ID %d, Server Address %U",
9733                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9734       else
9735         print (vam->ofp,
9736                " Server Table-ID %d, Server Address %U",
9737                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9738     }
9739 }
9740
9741 static void vl_api_dhcp_proxy_details_t_handler_json
9742   (vl_api_dhcp_proxy_details_t * mp)
9743 {
9744   vat_main_t *vam = &vat_main;
9745   vat_json_node_t *node = NULL;
9746   u32 i, count = mp->count;
9747   struct in_addr ip4;
9748   struct in6_addr ip6;
9749   vl_api_dhcp_server_t *s;
9750
9751   if (VAT_JSON_ARRAY != vam->json_tree.type)
9752     {
9753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9754       vat_json_init_array (&vam->json_tree);
9755     }
9756   node = vat_json_array_add (&vam->json_tree);
9757
9758   vat_json_init_object (node);
9759   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9760   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9761                              sizeof (mp->vss_type));
9762   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9763                                    mp->vss_vpn_ascii_id);
9764   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9765   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9766
9767   if (mp->is_ipv6)
9768     {
9769       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9770       vat_json_object_add_ip6 (node, "src_address", ip6);
9771     }
9772   else
9773     {
9774       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9775       vat_json_object_add_ip4 (node, "src_address", ip4);
9776     }
9777
9778   for (i = 0; i < count; i++)
9779     {
9780       s = &mp->servers[i];
9781
9782       vat_json_object_add_uint (node, "server-table-id",
9783                                 ntohl (s->server_vrf_id));
9784
9785       if (mp->is_ipv6)
9786         {
9787           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9788           vat_json_object_add_ip4 (node, "src_address", ip4);
9789         }
9790       else
9791         {
9792           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9793           vat_json_object_add_ip6 (node, "server_address", ip6);
9794         }
9795     }
9796 }
9797
9798 static int
9799 api_dhcp_proxy_dump (vat_main_t * vam)
9800 {
9801   unformat_input_t *i = vam->input;
9802   vl_api_control_ping_t *mp_ping;
9803   vl_api_dhcp_proxy_dump_t *mp;
9804   u8 is_ipv6 = 0;
9805   int ret;
9806
9807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9808     {
9809       if (unformat (i, "ipv6"))
9810         is_ipv6 = 1;
9811       else
9812         {
9813           clib_warning ("parse error '%U'", format_unformat_error, i);
9814           return -99;
9815         }
9816     }
9817
9818   M (DHCP_PROXY_DUMP, mp);
9819
9820   mp->is_ip6 = is_ipv6;
9821   S (mp);
9822
9823   /* Use a control ping for synchronization */
9824   MPING (CONTROL_PING, mp_ping);
9825   S (mp_ping);
9826
9827   W (ret);
9828   return ret;
9829 }
9830
9831 static int
9832 api_dhcp_proxy_set_vss (vat_main_t * vam)
9833 {
9834   unformat_input_t *i = vam->input;
9835   vl_api_dhcp_proxy_set_vss_t *mp;
9836   u8 is_ipv6 = 0;
9837   u8 is_add = 1;
9838   u32 tbl_id = ~0;
9839   u8 vss_type = VSS_TYPE_DEFAULT;
9840   u8 *vpn_ascii_id = 0;
9841   u32 oui = 0;
9842   u32 fib_id = 0;
9843   int ret;
9844
9845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9846     {
9847       if (unformat (i, "tbl_id %d", &tbl_id))
9848         ;
9849       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9850         vss_type = VSS_TYPE_ASCII;
9851       else if (unformat (i, "fib_id %d", &fib_id))
9852         vss_type = VSS_TYPE_VPN_ID;
9853       else if (unformat (i, "oui %d", &oui))
9854         vss_type = VSS_TYPE_VPN_ID;
9855       else if (unformat (i, "ipv6"))
9856         is_ipv6 = 1;
9857       else if (unformat (i, "del"))
9858         is_add = 0;
9859       else
9860         break;
9861     }
9862
9863   if (tbl_id == ~0)
9864     {
9865       errmsg ("missing tbl_id ");
9866       vec_free (vpn_ascii_id);
9867       return -99;
9868     }
9869
9870   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9871     {
9872       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9873       vec_free (vpn_ascii_id);
9874       return -99;
9875     }
9876
9877   M (DHCP_PROXY_SET_VSS, mp);
9878   mp->tbl_id = ntohl (tbl_id);
9879   mp->vss_type = vss_type;
9880   if (vpn_ascii_id)
9881     {
9882       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9883       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9884     }
9885   mp->vpn_index = ntohl (fib_id);
9886   mp->oui = ntohl (oui);
9887   mp->is_ipv6 = is_ipv6;
9888   mp->is_add = is_add;
9889
9890   S (mp);
9891   W (ret);
9892
9893   vec_free (vpn_ascii_id);
9894   return ret;
9895 }
9896
9897 static int
9898 api_dhcp_client_config (vat_main_t * vam)
9899 {
9900   unformat_input_t *i = vam->input;
9901   vl_api_dhcp_client_config_t *mp;
9902   u32 sw_if_index;
9903   u8 sw_if_index_set = 0;
9904   u8 is_add = 1;
9905   u8 *hostname = 0;
9906   u8 disable_event = 0;
9907   int ret;
9908
9909   /* Parse args required to build the message */
9910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9911     {
9912       if (unformat (i, "del"))
9913         is_add = 0;
9914       else
9915         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9916         sw_if_index_set = 1;
9917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9918         sw_if_index_set = 1;
9919       else if (unformat (i, "hostname %s", &hostname))
9920         ;
9921       else if (unformat (i, "disable_event"))
9922         disable_event = 1;
9923       else
9924         break;
9925     }
9926
9927   if (sw_if_index_set == 0)
9928     {
9929       errmsg ("missing interface name or sw_if_index");
9930       return -99;
9931     }
9932
9933   if (vec_len (hostname) > 63)
9934     {
9935       errmsg ("hostname too long");
9936     }
9937   vec_add1 (hostname, 0);
9938
9939   /* Construct the API message */
9940   M (DHCP_CLIENT_CONFIG, mp);
9941
9942   mp->is_add = is_add;
9943   mp->client.sw_if_index = htonl (sw_if_index);
9944   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9945   vec_free (hostname);
9946   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9947   mp->client.pid = htonl (getpid ());
9948
9949   /* send it... */
9950   S (mp);
9951
9952   /* Wait for a reply, return good/bad news  */
9953   W (ret);
9954   return ret;
9955 }
9956
9957 static int
9958 api_set_ip_flow_hash (vat_main_t * vam)
9959 {
9960   unformat_input_t *i = vam->input;
9961   vl_api_set_ip_flow_hash_t *mp;
9962   u32 vrf_id = 0;
9963   u8 is_ipv6 = 0;
9964   u8 vrf_id_set = 0;
9965   u8 src = 0;
9966   u8 dst = 0;
9967   u8 sport = 0;
9968   u8 dport = 0;
9969   u8 proto = 0;
9970   u8 reverse = 0;
9971   int ret;
9972
9973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9974     {
9975       if (unformat (i, "vrf %d", &vrf_id))
9976         vrf_id_set = 1;
9977       else if (unformat (i, "ipv6"))
9978         is_ipv6 = 1;
9979       else if (unformat (i, "src"))
9980         src = 1;
9981       else if (unformat (i, "dst"))
9982         dst = 1;
9983       else if (unformat (i, "sport"))
9984         sport = 1;
9985       else if (unformat (i, "dport"))
9986         dport = 1;
9987       else if (unformat (i, "proto"))
9988         proto = 1;
9989       else if (unformat (i, "reverse"))
9990         reverse = 1;
9991
9992       else
9993         {
9994           clib_warning ("parse error '%U'", format_unformat_error, i);
9995           return -99;
9996         }
9997     }
9998
9999   if (vrf_id_set == 0)
10000     {
10001       errmsg ("missing vrf id");
10002       return -99;
10003     }
10004
10005   M (SET_IP_FLOW_HASH, mp);
10006   mp->src = src;
10007   mp->dst = dst;
10008   mp->sport = sport;
10009   mp->dport = dport;
10010   mp->proto = proto;
10011   mp->reverse = reverse;
10012   mp->vrf_id = ntohl (vrf_id);
10013   mp->is_ipv6 = is_ipv6;
10014
10015   S (mp);
10016   W (ret);
10017   return ret;
10018 }
10019
10020 static int
10021 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10022 {
10023   unformat_input_t *i = vam->input;
10024   vl_api_sw_interface_ip6_enable_disable_t *mp;
10025   u32 sw_if_index;
10026   u8 sw_if_index_set = 0;
10027   u8 enable = 0;
10028   int ret;
10029
10030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10031     {
10032       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10033         sw_if_index_set = 1;
10034       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10035         sw_if_index_set = 1;
10036       else if (unformat (i, "enable"))
10037         enable = 1;
10038       else if (unformat (i, "disable"))
10039         enable = 0;
10040       else
10041         {
10042           clib_warning ("parse error '%U'", format_unformat_error, i);
10043           return -99;
10044         }
10045     }
10046
10047   if (sw_if_index_set == 0)
10048     {
10049       errmsg ("missing interface name or sw_if_index");
10050       return -99;
10051     }
10052
10053   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10054
10055   mp->sw_if_index = ntohl (sw_if_index);
10056   mp->enable = enable;
10057
10058   S (mp);
10059   W (ret);
10060   return ret;
10061 }
10062
10063 static int
10064 api_ip6nd_proxy_add_del (vat_main_t * vam)
10065 {
10066   unformat_input_t *i = vam->input;
10067   vl_api_ip6nd_proxy_add_del_t *mp;
10068   u32 sw_if_index = ~0;
10069   u8 v6_address_set = 0;
10070   vl_api_ip6_address_t v6address;
10071   u8 is_del = 0;
10072   int ret;
10073
10074   /* Parse args required to build the message */
10075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10076     {
10077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10078         ;
10079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10080         ;
10081       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10082         v6_address_set = 1;
10083       if (unformat (i, "del"))
10084         is_del = 1;
10085       else
10086         {
10087           clib_warning ("parse error '%U'", format_unformat_error, i);
10088           return -99;
10089         }
10090     }
10091
10092   if (sw_if_index == ~0)
10093     {
10094       errmsg ("missing interface name or sw_if_index");
10095       return -99;
10096     }
10097   if (!v6_address_set)
10098     {
10099       errmsg ("no address set");
10100       return -99;
10101     }
10102
10103   /* Construct the API message */
10104   M (IP6ND_PROXY_ADD_DEL, mp);
10105
10106   mp->is_del = is_del;
10107   mp->sw_if_index = ntohl (sw_if_index);
10108   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10109
10110   /* send it... */
10111   S (mp);
10112
10113   /* Wait for a reply, return good/bad news  */
10114   W (ret);
10115   return ret;
10116 }
10117
10118 static int
10119 api_ip6nd_proxy_dump (vat_main_t * vam)
10120 {
10121   vl_api_ip6nd_proxy_dump_t *mp;
10122   vl_api_control_ping_t *mp_ping;
10123   int ret;
10124
10125   M (IP6ND_PROXY_DUMP, mp);
10126
10127   S (mp);
10128
10129   /* Use a control ping for synchronization */
10130   MPING (CONTROL_PING, mp_ping);
10131   S (mp_ping);
10132
10133   W (ret);
10134   return ret;
10135 }
10136
10137 static void vl_api_ip6nd_proxy_details_t_handler
10138   (vl_api_ip6nd_proxy_details_t * mp)
10139 {
10140   vat_main_t *vam = &vat_main;
10141
10142   print (vam->ofp, "host %U sw_if_index %d",
10143          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10144 }
10145
10146 static void vl_api_ip6nd_proxy_details_t_handler_json
10147   (vl_api_ip6nd_proxy_details_t * mp)
10148 {
10149   vat_main_t *vam = &vat_main;
10150   struct in6_addr ip6;
10151   vat_json_node_t *node = NULL;
10152
10153   if (VAT_JSON_ARRAY != vam->json_tree.type)
10154     {
10155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10156       vat_json_init_array (&vam->json_tree);
10157     }
10158   node = vat_json_array_add (&vam->json_tree);
10159
10160   vat_json_init_object (node);
10161   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10162
10163   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10164   vat_json_object_add_ip6 (node, "host", ip6);
10165 }
10166
10167 static int
10168 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10169 {
10170   unformat_input_t *i = vam->input;
10171   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10172   u32 sw_if_index;
10173   u8 sw_if_index_set = 0;
10174   u32 address_length = 0;
10175   u8 v6_address_set = 0;
10176   vl_api_prefix_t pfx;
10177   u8 use_default = 0;
10178   u8 no_advertise = 0;
10179   u8 off_link = 0;
10180   u8 no_autoconfig = 0;
10181   u8 no_onlink = 0;
10182   u8 is_no = 0;
10183   u32 val_lifetime = 0;
10184   u32 pref_lifetime = 0;
10185   int ret;
10186
10187   /* Parse args required to build the message */
10188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10189     {
10190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10191         sw_if_index_set = 1;
10192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10193         sw_if_index_set = 1;
10194       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10195         v6_address_set = 1;
10196       else if (unformat (i, "val_life %d", &val_lifetime))
10197         ;
10198       else if (unformat (i, "pref_life %d", &pref_lifetime))
10199         ;
10200       else if (unformat (i, "def"))
10201         use_default = 1;
10202       else if (unformat (i, "noadv"))
10203         no_advertise = 1;
10204       else if (unformat (i, "offl"))
10205         off_link = 1;
10206       else if (unformat (i, "noauto"))
10207         no_autoconfig = 1;
10208       else if (unformat (i, "nolink"))
10209         no_onlink = 1;
10210       else if (unformat (i, "isno"))
10211         is_no = 1;
10212       else
10213         {
10214           clib_warning ("parse error '%U'", format_unformat_error, i);
10215           return -99;
10216         }
10217     }
10218
10219   if (sw_if_index_set == 0)
10220     {
10221       errmsg ("missing interface name or sw_if_index");
10222       return -99;
10223     }
10224   if (!v6_address_set)
10225     {
10226       errmsg ("no address set");
10227       return -99;
10228     }
10229
10230   /* Construct the API message */
10231   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10232
10233   mp->sw_if_index = ntohl (sw_if_index);
10234   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10235   mp->use_default = use_default;
10236   mp->no_advertise = no_advertise;
10237   mp->off_link = off_link;
10238   mp->no_autoconfig = no_autoconfig;
10239   mp->no_onlink = no_onlink;
10240   mp->is_no = is_no;
10241   mp->val_lifetime = ntohl (val_lifetime);
10242   mp->pref_lifetime = ntohl (pref_lifetime);
10243
10244   /* send it... */
10245   S (mp);
10246
10247   /* Wait for a reply, return good/bad news  */
10248   W (ret);
10249   return ret;
10250 }
10251
10252 static int
10253 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10254 {
10255   unformat_input_t *i = vam->input;
10256   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10257   u32 sw_if_index;
10258   u8 sw_if_index_set = 0;
10259   u8 suppress = 0;
10260   u8 managed = 0;
10261   u8 other = 0;
10262   u8 ll_option = 0;
10263   u8 send_unicast = 0;
10264   u8 cease = 0;
10265   u8 is_no = 0;
10266   u8 default_router = 0;
10267   u32 max_interval = 0;
10268   u32 min_interval = 0;
10269   u32 lifetime = 0;
10270   u32 initial_count = 0;
10271   u32 initial_interval = 0;
10272   int ret;
10273
10274
10275   /* Parse args required to build the message */
10276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10277     {
10278       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10279         sw_if_index_set = 1;
10280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10281         sw_if_index_set = 1;
10282       else if (unformat (i, "maxint %d", &max_interval))
10283         ;
10284       else if (unformat (i, "minint %d", &min_interval))
10285         ;
10286       else if (unformat (i, "life %d", &lifetime))
10287         ;
10288       else if (unformat (i, "count %d", &initial_count))
10289         ;
10290       else if (unformat (i, "interval %d", &initial_interval))
10291         ;
10292       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10293         suppress = 1;
10294       else if (unformat (i, "managed"))
10295         managed = 1;
10296       else if (unformat (i, "other"))
10297         other = 1;
10298       else if (unformat (i, "ll"))
10299         ll_option = 1;
10300       else if (unformat (i, "send"))
10301         send_unicast = 1;
10302       else if (unformat (i, "cease"))
10303         cease = 1;
10304       else if (unformat (i, "isno"))
10305         is_no = 1;
10306       else if (unformat (i, "def"))
10307         default_router = 1;
10308       else
10309         {
10310           clib_warning ("parse error '%U'", format_unformat_error, i);
10311           return -99;
10312         }
10313     }
10314
10315   if (sw_if_index_set == 0)
10316     {
10317       errmsg ("missing interface name or sw_if_index");
10318       return -99;
10319     }
10320
10321   /* Construct the API message */
10322   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10323
10324   mp->sw_if_index = ntohl (sw_if_index);
10325   mp->max_interval = ntohl (max_interval);
10326   mp->min_interval = ntohl (min_interval);
10327   mp->lifetime = ntohl (lifetime);
10328   mp->initial_count = ntohl (initial_count);
10329   mp->initial_interval = ntohl (initial_interval);
10330   mp->suppress = suppress;
10331   mp->managed = managed;
10332   mp->other = other;
10333   mp->ll_option = ll_option;
10334   mp->send_unicast = send_unicast;
10335   mp->cease = cease;
10336   mp->is_no = is_no;
10337   mp->default_router = default_router;
10338
10339   /* send it... */
10340   S (mp);
10341
10342   /* Wait for a reply, return good/bad news  */
10343   W (ret);
10344   return ret;
10345 }
10346
10347 static int
10348 api_set_arp_neighbor_limit (vat_main_t * vam)
10349 {
10350   unformat_input_t *i = vam->input;
10351   vl_api_set_arp_neighbor_limit_t *mp;
10352   u32 arp_nbr_limit;
10353   u8 limit_set = 0;
10354   u8 is_ipv6 = 0;
10355   int ret;
10356
10357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10358     {
10359       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10360         limit_set = 1;
10361       else if (unformat (i, "ipv6"))
10362         is_ipv6 = 1;
10363       else
10364         {
10365           clib_warning ("parse error '%U'", format_unformat_error, i);
10366           return -99;
10367         }
10368     }
10369
10370   if (limit_set == 0)
10371     {
10372       errmsg ("missing limit value");
10373       return -99;
10374     }
10375
10376   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10377
10378   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10379   mp->is_ipv6 = is_ipv6;
10380
10381   S (mp);
10382   W (ret);
10383   return ret;
10384 }
10385
10386 static int
10387 api_l2_patch_add_del (vat_main_t * vam)
10388 {
10389   unformat_input_t *i = vam->input;
10390   vl_api_l2_patch_add_del_t *mp;
10391   u32 rx_sw_if_index;
10392   u8 rx_sw_if_index_set = 0;
10393   u32 tx_sw_if_index;
10394   u8 tx_sw_if_index_set = 0;
10395   u8 is_add = 1;
10396   int ret;
10397
10398   /* Parse args required to build the message */
10399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10400     {
10401       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10402         rx_sw_if_index_set = 1;
10403       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10404         tx_sw_if_index_set = 1;
10405       else if (unformat (i, "rx"))
10406         {
10407           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10408             {
10409               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10410                             &rx_sw_if_index))
10411                 rx_sw_if_index_set = 1;
10412             }
10413           else
10414             break;
10415         }
10416       else if (unformat (i, "tx"))
10417         {
10418           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10419             {
10420               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10421                             &tx_sw_if_index))
10422                 tx_sw_if_index_set = 1;
10423             }
10424           else
10425             break;
10426         }
10427       else if (unformat (i, "del"))
10428         is_add = 0;
10429       else
10430         break;
10431     }
10432
10433   if (rx_sw_if_index_set == 0)
10434     {
10435       errmsg ("missing rx interface name or rx_sw_if_index");
10436       return -99;
10437     }
10438
10439   if (tx_sw_if_index_set == 0)
10440     {
10441       errmsg ("missing tx interface name or tx_sw_if_index");
10442       return -99;
10443     }
10444
10445   M (L2_PATCH_ADD_DEL, mp);
10446
10447   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10448   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10449   mp->is_add = is_add;
10450
10451   S (mp);
10452   W (ret);
10453   return ret;
10454 }
10455
10456 u8 is_del;
10457 u8 localsid_addr[16];
10458 u8 end_psp;
10459 u8 behavior;
10460 u32 sw_if_index;
10461 u32 vlan_index;
10462 u32 fib_table;
10463 u8 nh_addr[16];
10464
10465 static int
10466 api_sr_localsid_add_del (vat_main_t * vam)
10467 {
10468   unformat_input_t *i = vam->input;
10469   vl_api_sr_localsid_add_del_t *mp;
10470
10471   u8 is_del;
10472   ip6_address_t localsid;
10473   u8 end_psp = 0;
10474   u8 behavior = ~0;
10475   u32 sw_if_index;
10476   u32 fib_table = ~(u32) 0;
10477   ip6_address_t nh_addr6;
10478   ip4_address_t nh_addr4;
10479   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10480   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10481
10482   bool nexthop_set = 0;
10483
10484   int ret;
10485
10486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10487     {
10488       if (unformat (i, "del"))
10489         is_del = 1;
10490       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10491       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10492         nexthop_set = 1;
10493       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10494         nexthop_set = 1;
10495       else if (unformat (i, "behavior %u", &behavior));
10496       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10497       else if (unformat (i, "fib-table %u", &fib_table));
10498       else if (unformat (i, "end.psp %u", &behavior));
10499       else
10500         break;
10501     }
10502
10503   M (SR_LOCALSID_ADD_DEL, mp);
10504
10505   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10506   if (nexthop_set)
10507     {
10508       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10509       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10510     }
10511   mp->behavior = behavior;
10512   mp->sw_if_index = ntohl (sw_if_index);
10513   mp->fib_table = ntohl (fib_table);
10514   mp->end_psp = end_psp;
10515   mp->is_del = is_del;
10516
10517   S (mp);
10518   W (ret);
10519   return ret;
10520 }
10521
10522 static int
10523 api_ioam_enable (vat_main_t * vam)
10524 {
10525   unformat_input_t *input = vam->input;
10526   vl_api_ioam_enable_t *mp;
10527   u32 id = 0;
10528   int has_trace_option = 0;
10529   int has_pot_option = 0;
10530   int has_seqno_option = 0;
10531   int has_analyse_option = 0;
10532   int ret;
10533
10534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10535     {
10536       if (unformat (input, "trace"))
10537         has_trace_option = 1;
10538       else if (unformat (input, "pot"))
10539         has_pot_option = 1;
10540       else if (unformat (input, "seqno"))
10541         has_seqno_option = 1;
10542       else if (unformat (input, "analyse"))
10543         has_analyse_option = 1;
10544       else
10545         break;
10546     }
10547   M (IOAM_ENABLE, mp);
10548   mp->id = htons (id);
10549   mp->seqno = has_seqno_option;
10550   mp->analyse = has_analyse_option;
10551   mp->pot_enable = has_pot_option;
10552   mp->trace_enable = has_trace_option;
10553
10554   S (mp);
10555   W (ret);
10556   return ret;
10557 }
10558
10559
10560 static int
10561 api_ioam_disable (vat_main_t * vam)
10562 {
10563   vl_api_ioam_disable_t *mp;
10564   int ret;
10565
10566   M (IOAM_DISABLE, mp);
10567   S (mp);
10568   W (ret);
10569   return ret;
10570 }
10571
10572 #define foreach_tcp_proto_field                 \
10573 _(src_port)                                     \
10574 _(dst_port)
10575
10576 #define foreach_udp_proto_field                 \
10577 _(src_port)                                     \
10578 _(dst_port)
10579
10580 #define foreach_ip4_proto_field                 \
10581 _(src_address)                                  \
10582 _(dst_address)                                  \
10583 _(tos)                                          \
10584 _(length)                                       \
10585 _(fragment_id)                                  \
10586 _(ttl)                                          \
10587 _(protocol)                                     \
10588 _(checksum)
10589
10590 typedef struct
10591 {
10592   u16 src_port, dst_port;
10593 } tcpudp_header_t;
10594
10595 #if VPP_API_TEST_BUILTIN == 0
10596 uword
10597 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10598 {
10599   u8 **maskp = va_arg (*args, u8 **);
10600   u8 *mask = 0;
10601   u8 found_something = 0;
10602   tcp_header_t *tcp;
10603
10604 #define _(a) u8 a=0;
10605   foreach_tcp_proto_field;
10606 #undef _
10607
10608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10609     {
10610       if (0);
10611 #define _(a) else if (unformat (input, #a)) a=1;
10612       foreach_tcp_proto_field
10613 #undef _
10614         else
10615         break;
10616     }
10617
10618 #define _(a) found_something += a;
10619   foreach_tcp_proto_field;
10620 #undef _
10621
10622   if (found_something == 0)
10623     return 0;
10624
10625   vec_validate (mask, sizeof (*tcp) - 1);
10626
10627   tcp = (tcp_header_t *) mask;
10628
10629 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10630   foreach_tcp_proto_field;
10631 #undef _
10632
10633   *maskp = mask;
10634   return 1;
10635 }
10636
10637 uword
10638 unformat_udp_mask (unformat_input_t * input, va_list * args)
10639 {
10640   u8 **maskp = va_arg (*args, u8 **);
10641   u8 *mask = 0;
10642   u8 found_something = 0;
10643   udp_header_t *udp;
10644
10645 #define _(a) u8 a=0;
10646   foreach_udp_proto_field;
10647 #undef _
10648
10649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10650     {
10651       if (0);
10652 #define _(a) else if (unformat (input, #a)) a=1;
10653       foreach_udp_proto_field
10654 #undef _
10655         else
10656         break;
10657     }
10658
10659 #define _(a) found_something += a;
10660   foreach_udp_proto_field;
10661 #undef _
10662
10663   if (found_something == 0)
10664     return 0;
10665
10666   vec_validate (mask, sizeof (*udp) - 1);
10667
10668   udp = (udp_header_t *) mask;
10669
10670 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10671   foreach_udp_proto_field;
10672 #undef _
10673
10674   *maskp = mask;
10675   return 1;
10676 }
10677
10678 uword
10679 unformat_l4_mask (unformat_input_t * input, va_list * args)
10680 {
10681   u8 **maskp = va_arg (*args, u8 **);
10682   u16 src_port = 0, dst_port = 0;
10683   tcpudp_header_t *tcpudp;
10684
10685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10686     {
10687       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10688         return 1;
10689       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10690         return 1;
10691       else if (unformat (input, "src_port"))
10692         src_port = 0xFFFF;
10693       else if (unformat (input, "dst_port"))
10694         dst_port = 0xFFFF;
10695       else
10696         return 0;
10697     }
10698
10699   if (!src_port && !dst_port)
10700     return 0;
10701
10702   u8 *mask = 0;
10703   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10704
10705   tcpudp = (tcpudp_header_t *) mask;
10706   tcpudp->src_port = src_port;
10707   tcpudp->dst_port = dst_port;
10708
10709   *maskp = mask;
10710
10711   return 1;
10712 }
10713
10714 uword
10715 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10716 {
10717   u8 **maskp = va_arg (*args, u8 **);
10718   u8 *mask = 0;
10719   u8 found_something = 0;
10720   ip4_header_t *ip;
10721
10722 #define _(a) u8 a=0;
10723   foreach_ip4_proto_field;
10724 #undef _
10725   u8 version = 0;
10726   u8 hdr_length = 0;
10727
10728
10729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10730     {
10731       if (unformat (input, "version"))
10732         version = 1;
10733       else if (unformat (input, "hdr_length"))
10734         hdr_length = 1;
10735       else if (unformat (input, "src"))
10736         src_address = 1;
10737       else if (unformat (input, "dst"))
10738         dst_address = 1;
10739       else if (unformat (input, "proto"))
10740         protocol = 1;
10741
10742 #define _(a) else if (unformat (input, #a)) a=1;
10743       foreach_ip4_proto_field
10744 #undef _
10745         else
10746         break;
10747     }
10748
10749 #define _(a) found_something += a;
10750   foreach_ip4_proto_field;
10751 #undef _
10752
10753   if (found_something == 0)
10754     return 0;
10755
10756   vec_validate (mask, sizeof (*ip) - 1);
10757
10758   ip = (ip4_header_t *) mask;
10759
10760 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10761   foreach_ip4_proto_field;
10762 #undef _
10763
10764   ip->ip_version_and_header_length = 0;
10765
10766   if (version)
10767     ip->ip_version_and_header_length |= 0xF0;
10768
10769   if (hdr_length)
10770     ip->ip_version_and_header_length |= 0x0F;
10771
10772   *maskp = mask;
10773   return 1;
10774 }
10775
10776 #define foreach_ip6_proto_field                 \
10777 _(src_address)                                  \
10778 _(dst_address)                                  \
10779 _(payload_length)                               \
10780 _(hop_limit)                                    \
10781 _(protocol)
10782
10783 uword
10784 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10785 {
10786   u8 **maskp = va_arg (*args, u8 **);
10787   u8 *mask = 0;
10788   u8 found_something = 0;
10789   ip6_header_t *ip;
10790   u32 ip_version_traffic_class_and_flow_label;
10791
10792 #define _(a) u8 a=0;
10793   foreach_ip6_proto_field;
10794 #undef _
10795   u8 version = 0;
10796   u8 traffic_class = 0;
10797   u8 flow_label = 0;
10798
10799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (input, "version"))
10802         version = 1;
10803       else if (unformat (input, "traffic-class"))
10804         traffic_class = 1;
10805       else if (unformat (input, "flow-label"))
10806         flow_label = 1;
10807       else if (unformat (input, "src"))
10808         src_address = 1;
10809       else if (unformat (input, "dst"))
10810         dst_address = 1;
10811       else if (unformat (input, "proto"))
10812         protocol = 1;
10813
10814 #define _(a) else if (unformat (input, #a)) a=1;
10815       foreach_ip6_proto_field
10816 #undef _
10817         else
10818         break;
10819     }
10820
10821 #define _(a) found_something += a;
10822   foreach_ip6_proto_field;
10823 #undef _
10824
10825   if (found_something == 0)
10826     return 0;
10827
10828   vec_validate (mask, sizeof (*ip) - 1);
10829
10830   ip = (ip6_header_t *) mask;
10831
10832 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10833   foreach_ip6_proto_field;
10834 #undef _
10835
10836   ip_version_traffic_class_and_flow_label = 0;
10837
10838   if (version)
10839     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10840
10841   if (traffic_class)
10842     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10843
10844   if (flow_label)
10845     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10846
10847   ip->ip_version_traffic_class_and_flow_label =
10848     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10849
10850   *maskp = mask;
10851   return 1;
10852 }
10853
10854 uword
10855 unformat_l3_mask (unformat_input_t * input, va_list * args)
10856 {
10857   u8 **maskp = va_arg (*args, u8 **);
10858
10859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10860     {
10861       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10862         return 1;
10863       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10864         return 1;
10865       else
10866         break;
10867     }
10868   return 0;
10869 }
10870
10871 uword
10872 unformat_l2_mask (unformat_input_t * input, va_list * args)
10873 {
10874   u8 **maskp = va_arg (*args, u8 **);
10875   u8 *mask = 0;
10876   u8 src = 0;
10877   u8 dst = 0;
10878   u8 proto = 0;
10879   u8 tag1 = 0;
10880   u8 tag2 = 0;
10881   u8 ignore_tag1 = 0;
10882   u8 ignore_tag2 = 0;
10883   u8 cos1 = 0;
10884   u8 cos2 = 0;
10885   u8 dot1q = 0;
10886   u8 dot1ad = 0;
10887   int len = 14;
10888
10889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10890     {
10891       if (unformat (input, "src"))
10892         src = 1;
10893       else if (unformat (input, "dst"))
10894         dst = 1;
10895       else if (unformat (input, "proto"))
10896         proto = 1;
10897       else if (unformat (input, "tag1"))
10898         tag1 = 1;
10899       else if (unformat (input, "tag2"))
10900         tag2 = 1;
10901       else if (unformat (input, "ignore-tag1"))
10902         ignore_tag1 = 1;
10903       else if (unformat (input, "ignore-tag2"))
10904         ignore_tag2 = 1;
10905       else if (unformat (input, "cos1"))
10906         cos1 = 1;
10907       else if (unformat (input, "cos2"))
10908         cos2 = 1;
10909       else if (unformat (input, "dot1q"))
10910         dot1q = 1;
10911       else if (unformat (input, "dot1ad"))
10912         dot1ad = 1;
10913       else
10914         break;
10915     }
10916   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10917        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10918     return 0;
10919
10920   if (tag1 || ignore_tag1 || cos1 || dot1q)
10921     len = 18;
10922   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10923     len = 22;
10924
10925   vec_validate (mask, len - 1);
10926
10927   if (dst)
10928     clib_memset (mask, 0xff, 6);
10929
10930   if (src)
10931     clib_memset (mask + 6, 0xff, 6);
10932
10933   if (tag2 || dot1ad)
10934     {
10935       /* inner vlan tag */
10936       if (tag2)
10937         {
10938           mask[19] = 0xff;
10939           mask[18] = 0x0f;
10940         }
10941       if (cos2)
10942         mask[18] |= 0xe0;
10943       if (proto)
10944         mask[21] = mask[20] = 0xff;
10945       if (tag1)
10946         {
10947           mask[15] = 0xff;
10948           mask[14] = 0x0f;
10949         }
10950       if (cos1)
10951         mask[14] |= 0xe0;
10952       *maskp = mask;
10953       return 1;
10954     }
10955   if (tag1 | dot1q)
10956     {
10957       if (tag1)
10958         {
10959           mask[15] = 0xff;
10960           mask[14] = 0x0f;
10961         }
10962       if (cos1)
10963         mask[14] |= 0xe0;
10964       if (proto)
10965         mask[16] = mask[17] = 0xff;
10966
10967       *maskp = mask;
10968       return 1;
10969     }
10970   if (cos2)
10971     mask[18] |= 0xe0;
10972   if (cos1)
10973     mask[14] |= 0xe0;
10974   if (proto)
10975     mask[12] = mask[13] = 0xff;
10976
10977   *maskp = mask;
10978   return 1;
10979 }
10980
10981 uword
10982 unformat_classify_mask (unformat_input_t * input, va_list * args)
10983 {
10984   u8 **maskp = va_arg (*args, u8 **);
10985   u32 *skipp = va_arg (*args, u32 *);
10986   u32 *matchp = va_arg (*args, u32 *);
10987   u32 match;
10988   u8 *mask = 0;
10989   u8 *l2 = 0;
10990   u8 *l3 = 0;
10991   u8 *l4 = 0;
10992   int i;
10993
10994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10995     {
10996       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10997         ;
10998       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10999         ;
11000       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11001         ;
11002       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11003         ;
11004       else
11005         break;
11006     }
11007
11008   if (l4 && !l3)
11009     {
11010       vec_free (mask);
11011       vec_free (l2);
11012       vec_free (l4);
11013       return 0;
11014     }
11015
11016   if (mask || l2 || l3 || l4)
11017     {
11018       if (l2 || l3 || l4)
11019         {
11020           /* "With a free Ethernet header in every package" */
11021           if (l2 == 0)
11022             vec_validate (l2, 13);
11023           mask = l2;
11024           if (vec_len (l3))
11025             {
11026               vec_append (mask, l3);
11027               vec_free (l3);
11028             }
11029           if (vec_len (l4))
11030             {
11031               vec_append (mask, l4);
11032               vec_free (l4);
11033             }
11034         }
11035
11036       /* Scan forward looking for the first significant mask octet */
11037       for (i = 0; i < vec_len (mask); i++)
11038         if (mask[i])
11039           break;
11040
11041       /* compute (skip, match) params */
11042       *skipp = i / sizeof (u32x4);
11043       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11044
11045       /* Pad mask to an even multiple of the vector size */
11046       while (vec_len (mask) % sizeof (u32x4))
11047         vec_add1 (mask, 0);
11048
11049       match = vec_len (mask) / sizeof (u32x4);
11050
11051       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11052         {
11053           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11054           if (*tmp || *(tmp + 1))
11055             break;
11056           match--;
11057         }
11058       if (match == 0)
11059         clib_warning ("BUG: match 0");
11060
11061       _vec_len (mask) = match * sizeof (u32x4);
11062
11063       *matchp = match;
11064       *maskp = mask;
11065
11066       return 1;
11067     }
11068
11069   return 0;
11070 }
11071 #endif /* VPP_API_TEST_BUILTIN */
11072
11073 #define foreach_l2_next                         \
11074 _(drop, DROP)                                   \
11075 _(ethernet, ETHERNET_INPUT)                     \
11076 _(ip4, IP4_INPUT)                               \
11077 _(ip6, IP6_INPUT)
11078
11079 uword
11080 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11081 {
11082   u32 *miss_next_indexp = va_arg (*args, u32 *);
11083   u32 next_index = 0;
11084   u32 tmp;
11085
11086 #define _(n,N) \
11087   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11088   foreach_l2_next;
11089 #undef _
11090
11091   if (unformat (input, "%d", &tmp))
11092     {
11093       next_index = tmp;
11094       goto out;
11095     }
11096
11097   return 0;
11098
11099 out:
11100   *miss_next_indexp = next_index;
11101   return 1;
11102 }
11103
11104 #define foreach_ip_next                         \
11105 _(drop, DROP)                                   \
11106 _(local, LOCAL)                                 \
11107 _(rewrite, REWRITE)
11108
11109 uword
11110 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11111 {
11112   u32 *miss_next_indexp = va_arg (*args, u32 *);
11113   u32 next_index = 0;
11114   u32 tmp;
11115
11116 #define _(n,N) \
11117   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11118   foreach_ip_next;
11119 #undef _
11120
11121   if (unformat (input, "%d", &tmp))
11122     {
11123       next_index = tmp;
11124       goto out;
11125     }
11126
11127   return 0;
11128
11129 out:
11130   *miss_next_indexp = next_index;
11131   return 1;
11132 }
11133
11134 #define foreach_acl_next                        \
11135 _(deny, DENY)
11136
11137 uword
11138 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11139 {
11140   u32 *miss_next_indexp = va_arg (*args, u32 *);
11141   u32 next_index = 0;
11142   u32 tmp;
11143
11144 #define _(n,N) \
11145   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11146   foreach_acl_next;
11147 #undef _
11148
11149   if (unformat (input, "permit"))
11150     {
11151       next_index = ~0;
11152       goto out;
11153     }
11154   else if (unformat (input, "%d", &tmp))
11155     {
11156       next_index = tmp;
11157       goto out;
11158     }
11159
11160   return 0;
11161
11162 out:
11163   *miss_next_indexp = next_index;
11164   return 1;
11165 }
11166
11167 uword
11168 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11169 {
11170   u32 *r = va_arg (*args, u32 *);
11171
11172   if (unformat (input, "conform-color"))
11173     *r = POLICE_CONFORM;
11174   else if (unformat (input, "exceed-color"))
11175     *r = POLICE_EXCEED;
11176   else
11177     return 0;
11178
11179   return 1;
11180 }
11181
11182 static int
11183 api_classify_add_del_table (vat_main_t * vam)
11184 {
11185   unformat_input_t *i = vam->input;
11186   vl_api_classify_add_del_table_t *mp;
11187
11188   u32 nbuckets = 2;
11189   u32 skip = ~0;
11190   u32 match = ~0;
11191   int is_add = 1;
11192   int del_chain = 0;
11193   u32 table_index = ~0;
11194   u32 next_table_index = ~0;
11195   u32 miss_next_index = ~0;
11196   u32 memory_size = 32 << 20;
11197   u8 *mask = 0;
11198   u32 current_data_flag = 0;
11199   int current_data_offset = 0;
11200   int ret;
11201
11202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11203     {
11204       if (unformat (i, "del"))
11205         is_add = 0;
11206       else if (unformat (i, "del-chain"))
11207         {
11208           is_add = 0;
11209           del_chain = 1;
11210         }
11211       else if (unformat (i, "buckets %d", &nbuckets))
11212         ;
11213       else if (unformat (i, "memory_size %d", &memory_size))
11214         ;
11215       else if (unformat (i, "skip %d", &skip))
11216         ;
11217       else if (unformat (i, "match %d", &match))
11218         ;
11219       else if (unformat (i, "table %d", &table_index))
11220         ;
11221       else if (unformat (i, "mask %U", unformat_classify_mask,
11222                          &mask, &skip, &match))
11223         ;
11224       else if (unformat (i, "next-table %d", &next_table_index))
11225         ;
11226       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11227                          &miss_next_index))
11228         ;
11229       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11230                          &miss_next_index))
11231         ;
11232       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11233                          &miss_next_index))
11234         ;
11235       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11236         ;
11237       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11238         ;
11239       else
11240         break;
11241     }
11242
11243   if (is_add && mask == 0)
11244     {
11245       errmsg ("Mask required");
11246       return -99;
11247     }
11248
11249   if (is_add && skip == ~0)
11250     {
11251       errmsg ("skip count required");
11252       return -99;
11253     }
11254
11255   if (is_add && match == ~0)
11256     {
11257       errmsg ("match count required");
11258       return -99;
11259     }
11260
11261   if (!is_add && table_index == ~0)
11262     {
11263       errmsg ("table index required for delete");
11264       return -99;
11265     }
11266
11267   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11268
11269   mp->is_add = is_add;
11270   mp->del_chain = del_chain;
11271   mp->table_index = ntohl (table_index);
11272   mp->nbuckets = ntohl (nbuckets);
11273   mp->memory_size = ntohl (memory_size);
11274   mp->skip_n_vectors = ntohl (skip);
11275   mp->match_n_vectors = ntohl (match);
11276   mp->next_table_index = ntohl (next_table_index);
11277   mp->miss_next_index = ntohl (miss_next_index);
11278   mp->current_data_flag = ntohl (current_data_flag);
11279   mp->current_data_offset = ntohl (current_data_offset);
11280   mp->mask_len = ntohl (vec_len (mask));
11281   clib_memcpy (mp->mask, mask, vec_len (mask));
11282
11283   vec_free (mask);
11284
11285   S (mp);
11286   W (ret);
11287   return ret;
11288 }
11289
11290 #if VPP_API_TEST_BUILTIN == 0
11291 uword
11292 unformat_l4_match (unformat_input_t * input, va_list * args)
11293 {
11294   u8 **matchp = va_arg (*args, u8 **);
11295
11296   u8 *proto_header = 0;
11297   int src_port = 0;
11298   int dst_port = 0;
11299
11300   tcpudp_header_t h;
11301
11302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11303     {
11304       if (unformat (input, "src_port %d", &src_port))
11305         ;
11306       else if (unformat (input, "dst_port %d", &dst_port))
11307         ;
11308       else
11309         return 0;
11310     }
11311
11312   h.src_port = clib_host_to_net_u16 (src_port);
11313   h.dst_port = clib_host_to_net_u16 (dst_port);
11314   vec_validate (proto_header, sizeof (h) - 1);
11315   memcpy (proto_header, &h, sizeof (h));
11316
11317   *matchp = proto_header;
11318
11319   return 1;
11320 }
11321
11322 uword
11323 unformat_ip4_match (unformat_input_t * input, va_list * args)
11324 {
11325   u8 **matchp = va_arg (*args, u8 **);
11326   u8 *match = 0;
11327   ip4_header_t *ip;
11328   int version = 0;
11329   u32 version_val;
11330   int hdr_length = 0;
11331   u32 hdr_length_val;
11332   int src = 0, dst = 0;
11333   ip4_address_t src_val, dst_val;
11334   int proto = 0;
11335   u32 proto_val;
11336   int tos = 0;
11337   u32 tos_val;
11338   int length = 0;
11339   u32 length_val;
11340   int fragment_id = 0;
11341   u32 fragment_id_val;
11342   int ttl = 0;
11343   int ttl_val;
11344   int checksum = 0;
11345   u32 checksum_val;
11346
11347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11348     {
11349       if (unformat (input, "version %d", &version_val))
11350         version = 1;
11351       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11352         hdr_length = 1;
11353       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11354         src = 1;
11355       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11356         dst = 1;
11357       else if (unformat (input, "proto %d", &proto_val))
11358         proto = 1;
11359       else if (unformat (input, "tos %d", &tos_val))
11360         tos = 1;
11361       else if (unformat (input, "length %d", &length_val))
11362         length = 1;
11363       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11364         fragment_id = 1;
11365       else if (unformat (input, "ttl %d", &ttl_val))
11366         ttl = 1;
11367       else if (unformat (input, "checksum %d", &checksum_val))
11368         checksum = 1;
11369       else
11370         break;
11371     }
11372
11373   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11374       + ttl + checksum == 0)
11375     return 0;
11376
11377   /*
11378    * Aligned because we use the real comparison functions
11379    */
11380   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11381
11382   ip = (ip4_header_t *) match;
11383
11384   /* These are realistically matched in practice */
11385   if (src)
11386     ip->src_address.as_u32 = src_val.as_u32;
11387
11388   if (dst)
11389     ip->dst_address.as_u32 = dst_val.as_u32;
11390
11391   if (proto)
11392     ip->protocol = proto_val;
11393
11394
11395   /* These are not, but they're included for completeness */
11396   if (version)
11397     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11398
11399   if (hdr_length)
11400     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11401
11402   if (tos)
11403     ip->tos = tos_val;
11404
11405   if (length)
11406     ip->length = clib_host_to_net_u16 (length_val);
11407
11408   if (ttl)
11409     ip->ttl = ttl_val;
11410
11411   if (checksum)
11412     ip->checksum = clib_host_to_net_u16 (checksum_val);
11413
11414   *matchp = match;
11415   return 1;
11416 }
11417
11418 uword
11419 unformat_ip6_match (unformat_input_t * input, va_list * args)
11420 {
11421   u8 **matchp = va_arg (*args, u8 **);
11422   u8 *match = 0;
11423   ip6_header_t *ip;
11424   int version = 0;
11425   u32 version_val;
11426   u8 traffic_class = 0;
11427   u32 traffic_class_val = 0;
11428   u8 flow_label = 0;
11429   u8 flow_label_val;
11430   int src = 0, dst = 0;
11431   ip6_address_t src_val, dst_val;
11432   int proto = 0;
11433   u32 proto_val;
11434   int payload_length = 0;
11435   u32 payload_length_val;
11436   int hop_limit = 0;
11437   int hop_limit_val;
11438   u32 ip_version_traffic_class_and_flow_label;
11439
11440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11441     {
11442       if (unformat (input, "version %d", &version_val))
11443         version = 1;
11444       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11445         traffic_class = 1;
11446       else if (unformat (input, "flow_label %d", &flow_label_val))
11447         flow_label = 1;
11448       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11449         src = 1;
11450       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11451         dst = 1;
11452       else if (unformat (input, "proto %d", &proto_val))
11453         proto = 1;
11454       else if (unformat (input, "payload_length %d", &payload_length_val))
11455         payload_length = 1;
11456       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11457         hop_limit = 1;
11458       else
11459         break;
11460     }
11461
11462   if (version + traffic_class + flow_label + src + dst + proto +
11463       payload_length + hop_limit == 0)
11464     return 0;
11465
11466   /*
11467    * Aligned because we use the real comparison functions
11468    */
11469   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11470
11471   ip = (ip6_header_t *) match;
11472
11473   if (src)
11474     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11475
11476   if (dst)
11477     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11478
11479   if (proto)
11480     ip->protocol = proto_val;
11481
11482   ip_version_traffic_class_and_flow_label = 0;
11483
11484   if (version)
11485     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11486
11487   if (traffic_class)
11488     ip_version_traffic_class_and_flow_label |=
11489       (traffic_class_val & 0xFF) << 20;
11490
11491   if (flow_label)
11492     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11493
11494   ip->ip_version_traffic_class_and_flow_label =
11495     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11496
11497   if (payload_length)
11498     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11499
11500   if (hop_limit)
11501     ip->hop_limit = hop_limit_val;
11502
11503   *matchp = match;
11504   return 1;
11505 }
11506
11507 uword
11508 unformat_l3_match (unformat_input_t * input, va_list * args)
11509 {
11510   u8 **matchp = va_arg (*args, u8 **);
11511
11512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11513     {
11514       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11515         return 1;
11516       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11517         return 1;
11518       else
11519         break;
11520     }
11521   return 0;
11522 }
11523
11524 uword
11525 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11526 {
11527   u8 *tagp = va_arg (*args, u8 *);
11528   u32 tag;
11529
11530   if (unformat (input, "%d", &tag))
11531     {
11532       tagp[0] = (tag >> 8) & 0x0F;
11533       tagp[1] = tag & 0xFF;
11534       return 1;
11535     }
11536
11537   return 0;
11538 }
11539
11540 uword
11541 unformat_l2_match (unformat_input_t * input, va_list * args)
11542 {
11543   u8 **matchp = va_arg (*args, u8 **);
11544   u8 *match = 0;
11545   u8 src = 0;
11546   u8 src_val[6];
11547   u8 dst = 0;
11548   u8 dst_val[6];
11549   u8 proto = 0;
11550   u16 proto_val;
11551   u8 tag1 = 0;
11552   u8 tag1_val[2];
11553   u8 tag2 = 0;
11554   u8 tag2_val[2];
11555   int len = 14;
11556   u8 ignore_tag1 = 0;
11557   u8 ignore_tag2 = 0;
11558   u8 cos1 = 0;
11559   u8 cos2 = 0;
11560   u32 cos1_val = 0;
11561   u32 cos2_val = 0;
11562
11563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11564     {
11565       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11566         src = 1;
11567       else
11568         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11569         dst = 1;
11570       else if (unformat (input, "proto %U",
11571                          unformat_ethernet_type_host_byte_order, &proto_val))
11572         proto = 1;
11573       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11574         tag1 = 1;
11575       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11576         tag2 = 1;
11577       else if (unformat (input, "ignore-tag1"))
11578         ignore_tag1 = 1;
11579       else if (unformat (input, "ignore-tag2"))
11580         ignore_tag2 = 1;
11581       else if (unformat (input, "cos1 %d", &cos1_val))
11582         cos1 = 1;
11583       else if (unformat (input, "cos2 %d", &cos2_val))
11584         cos2 = 1;
11585       else
11586         break;
11587     }
11588   if ((src + dst + proto + tag1 + tag2 +
11589        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11590     return 0;
11591
11592   if (tag1 || ignore_tag1 || cos1)
11593     len = 18;
11594   if (tag2 || ignore_tag2 || cos2)
11595     len = 22;
11596
11597   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11598
11599   if (dst)
11600     clib_memcpy (match, dst_val, 6);
11601
11602   if (src)
11603     clib_memcpy (match + 6, src_val, 6);
11604
11605   if (tag2)
11606     {
11607       /* inner vlan tag */
11608       match[19] = tag2_val[1];
11609       match[18] = tag2_val[0];
11610       if (cos2)
11611         match[18] |= (cos2_val & 0x7) << 5;
11612       if (proto)
11613         {
11614           match[21] = proto_val & 0xff;
11615           match[20] = proto_val >> 8;
11616         }
11617       if (tag1)
11618         {
11619           match[15] = tag1_val[1];
11620           match[14] = tag1_val[0];
11621         }
11622       if (cos1)
11623         match[14] |= (cos1_val & 0x7) << 5;
11624       *matchp = match;
11625       return 1;
11626     }
11627   if (tag1)
11628     {
11629       match[15] = tag1_val[1];
11630       match[14] = tag1_val[0];
11631       if (proto)
11632         {
11633           match[17] = proto_val & 0xff;
11634           match[16] = proto_val >> 8;
11635         }
11636       if (cos1)
11637         match[14] |= (cos1_val & 0x7) << 5;
11638
11639       *matchp = match;
11640       return 1;
11641     }
11642   if (cos2)
11643     match[18] |= (cos2_val & 0x7) << 5;
11644   if (cos1)
11645     match[14] |= (cos1_val & 0x7) << 5;
11646   if (proto)
11647     {
11648       match[13] = proto_val & 0xff;
11649       match[12] = proto_val >> 8;
11650     }
11651
11652   *matchp = match;
11653   return 1;
11654 }
11655
11656 uword
11657 unformat_qos_source (unformat_input_t * input, va_list * args)
11658 {
11659   int *qs = va_arg (*args, int *);
11660
11661   if (unformat (input, "ip"))
11662     *qs = QOS_SOURCE_IP;
11663   else if (unformat (input, "mpls"))
11664     *qs = QOS_SOURCE_MPLS;
11665   else if (unformat (input, "ext"))
11666     *qs = QOS_SOURCE_EXT;
11667   else if (unformat (input, "vlan"))
11668     *qs = QOS_SOURCE_VLAN;
11669   else
11670     return 0;
11671
11672   return 1;
11673 }
11674 #endif
11675
11676 uword
11677 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11678 {
11679   u8 **matchp = va_arg (*args, u8 **);
11680   u32 skip_n_vectors = va_arg (*args, u32);
11681   u32 match_n_vectors = va_arg (*args, u32);
11682
11683   u8 *match = 0;
11684   u8 *l2 = 0;
11685   u8 *l3 = 0;
11686   u8 *l4 = 0;
11687
11688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (input, "hex %U", unformat_hex_string, &match))
11691         ;
11692       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11693         ;
11694       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11695         ;
11696       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11697         ;
11698       else
11699         break;
11700     }
11701
11702   if (l4 && !l3)
11703     {
11704       vec_free (match);
11705       vec_free (l2);
11706       vec_free (l4);
11707       return 0;
11708     }
11709
11710   if (match || l2 || l3 || l4)
11711     {
11712       if (l2 || l3 || l4)
11713         {
11714           /* "Win a free Ethernet header in every packet" */
11715           if (l2 == 0)
11716             vec_validate_aligned (l2, 13, sizeof (u32x4));
11717           match = l2;
11718           if (vec_len (l3))
11719             {
11720               vec_append_aligned (match, l3, sizeof (u32x4));
11721               vec_free (l3);
11722             }
11723           if (vec_len (l4))
11724             {
11725               vec_append_aligned (match, l4, sizeof (u32x4));
11726               vec_free (l4);
11727             }
11728         }
11729
11730       /* Make sure the vector is big enough even if key is all 0's */
11731       vec_validate_aligned
11732         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11733          sizeof (u32x4));
11734
11735       /* Set size, include skipped vectors */
11736       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11737
11738       *matchp = match;
11739
11740       return 1;
11741     }
11742
11743   return 0;
11744 }
11745
11746 static int
11747 api_classify_add_del_session (vat_main_t * vam)
11748 {
11749   unformat_input_t *i = vam->input;
11750   vl_api_classify_add_del_session_t *mp;
11751   int is_add = 1;
11752   u32 table_index = ~0;
11753   u32 hit_next_index = ~0;
11754   u32 opaque_index = ~0;
11755   u8 *match = 0;
11756   i32 advance = 0;
11757   u32 skip_n_vectors = 0;
11758   u32 match_n_vectors = 0;
11759   u32 action = 0;
11760   u32 metadata = 0;
11761   int ret;
11762
11763   /*
11764    * Warning: you have to supply skip_n and match_n
11765    * because the API client cant simply look at the classify
11766    * table object.
11767    */
11768
11769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11770     {
11771       if (unformat (i, "del"))
11772         is_add = 0;
11773       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11774                          &hit_next_index))
11775         ;
11776       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11777                          &hit_next_index))
11778         ;
11779       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11780                          &hit_next_index))
11781         ;
11782       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11783         ;
11784       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11785         ;
11786       else if (unformat (i, "opaque-index %d", &opaque_index))
11787         ;
11788       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11789         ;
11790       else if (unformat (i, "match_n %d", &match_n_vectors))
11791         ;
11792       else if (unformat (i, "match %U", api_unformat_classify_match,
11793                          &match, skip_n_vectors, match_n_vectors))
11794         ;
11795       else if (unformat (i, "advance %d", &advance))
11796         ;
11797       else if (unformat (i, "table-index %d", &table_index))
11798         ;
11799       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11800         action = 1;
11801       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11802         action = 2;
11803       else if (unformat (i, "action %d", &action))
11804         ;
11805       else if (unformat (i, "metadata %d", &metadata))
11806         ;
11807       else
11808         break;
11809     }
11810
11811   if (table_index == ~0)
11812     {
11813       errmsg ("Table index required");
11814       return -99;
11815     }
11816
11817   if (is_add && match == 0)
11818     {
11819       errmsg ("Match value required");
11820       return -99;
11821     }
11822
11823   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11824
11825   mp->is_add = is_add;
11826   mp->table_index = ntohl (table_index);
11827   mp->hit_next_index = ntohl (hit_next_index);
11828   mp->opaque_index = ntohl (opaque_index);
11829   mp->advance = ntohl (advance);
11830   mp->action = action;
11831   mp->metadata = ntohl (metadata);
11832   mp->match_len = ntohl (vec_len (match));
11833   clib_memcpy (mp->match, match, vec_len (match));
11834   vec_free (match);
11835
11836   S (mp);
11837   W (ret);
11838   return ret;
11839 }
11840
11841 static int
11842 api_classify_set_interface_ip_table (vat_main_t * vam)
11843 {
11844   unformat_input_t *i = vam->input;
11845   vl_api_classify_set_interface_ip_table_t *mp;
11846   u32 sw_if_index;
11847   int sw_if_index_set;
11848   u32 table_index = ~0;
11849   u8 is_ipv6 = 0;
11850   int ret;
11851
11852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11853     {
11854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11855         sw_if_index_set = 1;
11856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11857         sw_if_index_set = 1;
11858       else if (unformat (i, "table %d", &table_index))
11859         ;
11860       else
11861         {
11862           clib_warning ("parse error '%U'", format_unformat_error, i);
11863           return -99;
11864         }
11865     }
11866
11867   if (sw_if_index_set == 0)
11868     {
11869       errmsg ("missing interface name or sw_if_index");
11870       return -99;
11871     }
11872
11873
11874   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11875
11876   mp->sw_if_index = ntohl (sw_if_index);
11877   mp->table_index = ntohl (table_index);
11878   mp->is_ipv6 = is_ipv6;
11879
11880   S (mp);
11881   W (ret);
11882   return ret;
11883 }
11884
11885 static int
11886 api_classify_set_interface_l2_tables (vat_main_t * vam)
11887 {
11888   unformat_input_t *i = vam->input;
11889   vl_api_classify_set_interface_l2_tables_t *mp;
11890   u32 sw_if_index;
11891   int sw_if_index_set;
11892   u32 ip4_table_index = ~0;
11893   u32 ip6_table_index = ~0;
11894   u32 other_table_index = ~0;
11895   u32 is_input = 1;
11896   int ret;
11897
11898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11899     {
11900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11901         sw_if_index_set = 1;
11902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11903         sw_if_index_set = 1;
11904       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11905         ;
11906       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11907         ;
11908       else if (unformat (i, "other-table %d", &other_table_index))
11909         ;
11910       else if (unformat (i, "is-input %d", &is_input))
11911         ;
11912       else
11913         {
11914           clib_warning ("parse error '%U'", format_unformat_error, i);
11915           return -99;
11916         }
11917     }
11918
11919   if (sw_if_index_set == 0)
11920     {
11921       errmsg ("missing interface name or sw_if_index");
11922       return -99;
11923     }
11924
11925
11926   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11927
11928   mp->sw_if_index = ntohl (sw_if_index);
11929   mp->ip4_table_index = ntohl (ip4_table_index);
11930   mp->ip6_table_index = ntohl (ip6_table_index);
11931   mp->other_table_index = ntohl (other_table_index);
11932   mp->is_input = (u8) is_input;
11933
11934   S (mp);
11935   W (ret);
11936   return ret;
11937 }
11938
11939 static int
11940 api_set_ipfix_exporter (vat_main_t * vam)
11941 {
11942   unformat_input_t *i = vam->input;
11943   vl_api_set_ipfix_exporter_t *mp;
11944   ip4_address_t collector_address;
11945   u8 collector_address_set = 0;
11946   u32 collector_port = ~0;
11947   ip4_address_t src_address;
11948   u8 src_address_set = 0;
11949   u32 vrf_id = ~0;
11950   u32 path_mtu = ~0;
11951   u32 template_interval = ~0;
11952   u8 udp_checksum = 0;
11953   int ret;
11954
11955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11956     {
11957       if (unformat (i, "collector_address %U", unformat_ip4_address,
11958                     &collector_address))
11959         collector_address_set = 1;
11960       else if (unformat (i, "collector_port %d", &collector_port))
11961         ;
11962       else if (unformat (i, "src_address %U", unformat_ip4_address,
11963                          &src_address))
11964         src_address_set = 1;
11965       else if (unformat (i, "vrf_id %d", &vrf_id))
11966         ;
11967       else if (unformat (i, "path_mtu %d", &path_mtu))
11968         ;
11969       else if (unformat (i, "template_interval %d", &template_interval))
11970         ;
11971       else if (unformat (i, "udp_checksum"))
11972         udp_checksum = 1;
11973       else
11974         break;
11975     }
11976
11977   if (collector_address_set == 0)
11978     {
11979       errmsg ("collector_address required");
11980       return -99;
11981     }
11982
11983   if (src_address_set == 0)
11984     {
11985       errmsg ("src_address required");
11986       return -99;
11987     }
11988
11989   M (SET_IPFIX_EXPORTER, mp);
11990
11991   memcpy (mp->collector_address, collector_address.data,
11992           sizeof (collector_address.data));
11993   mp->collector_port = htons ((u16) collector_port);
11994   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11995   mp->vrf_id = htonl (vrf_id);
11996   mp->path_mtu = htonl (path_mtu);
11997   mp->template_interval = htonl (template_interval);
11998   mp->udp_checksum = udp_checksum;
11999
12000   S (mp);
12001   W (ret);
12002   return ret;
12003 }
12004
12005 static int
12006 api_set_ipfix_classify_stream (vat_main_t * vam)
12007 {
12008   unformat_input_t *i = vam->input;
12009   vl_api_set_ipfix_classify_stream_t *mp;
12010   u32 domain_id = 0;
12011   u32 src_port = UDP_DST_PORT_ipfix;
12012   int ret;
12013
12014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12015     {
12016       if (unformat (i, "domain %d", &domain_id))
12017         ;
12018       else if (unformat (i, "src_port %d", &src_port))
12019         ;
12020       else
12021         {
12022           errmsg ("unknown input `%U'", format_unformat_error, i);
12023           return -99;
12024         }
12025     }
12026
12027   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12028
12029   mp->domain_id = htonl (domain_id);
12030   mp->src_port = htons ((u16) src_port);
12031
12032   S (mp);
12033   W (ret);
12034   return ret;
12035 }
12036
12037 static int
12038 api_ipfix_classify_table_add_del (vat_main_t * vam)
12039 {
12040   unformat_input_t *i = vam->input;
12041   vl_api_ipfix_classify_table_add_del_t *mp;
12042   int is_add = -1;
12043   u32 classify_table_index = ~0;
12044   u8 ip_version = 0;
12045   u8 transport_protocol = 255;
12046   int ret;
12047
12048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12049     {
12050       if (unformat (i, "add"))
12051         is_add = 1;
12052       else if (unformat (i, "del"))
12053         is_add = 0;
12054       else if (unformat (i, "table %d", &classify_table_index))
12055         ;
12056       else if (unformat (i, "ip4"))
12057         ip_version = 4;
12058       else if (unformat (i, "ip6"))
12059         ip_version = 6;
12060       else if (unformat (i, "tcp"))
12061         transport_protocol = 6;
12062       else if (unformat (i, "udp"))
12063         transport_protocol = 17;
12064       else
12065         {
12066           errmsg ("unknown input `%U'", format_unformat_error, i);
12067           return -99;
12068         }
12069     }
12070
12071   if (is_add == -1)
12072     {
12073       errmsg ("expecting: add|del");
12074       return -99;
12075     }
12076   if (classify_table_index == ~0)
12077     {
12078       errmsg ("classifier table not specified");
12079       return -99;
12080     }
12081   if (ip_version == 0)
12082     {
12083       errmsg ("IP version not specified");
12084       return -99;
12085     }
12086
12087   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12088
12089   mp->is_add = is_add;
12090   mp->table_id = htonl (classify_table_index);
12091   mp->ip_version = ip_version;
12092   mp->transport_protocol = transport_protocol;
12093
12094   S (mp);
12095   W (ret);
12096   return ret;
12097 }
12098
12099 static int
12100 api_get_node_index (vat_main_t * vam)
12101 {
12102   unformat_input_t *i = vam->input;
12103   vl_api_get_node_index_t *mp;
12104   u8 *name = 0;
12105   int ret;
12106
12107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12108     {
12109       if (unformat (i, "node %s", &name))
12110         ;
12111       else
12112         break;
12113     }
12114   if (name == 0)
12115     {
12116       errmsg ("node name required");
12117       return -99;
12118     }
12119   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12120     {
12121       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12122       return -99;
12123     }
12124
12125   M (GET_NODE_INDEX, mp);
12126   clib_memcpy (mp->node_name, name, vec_len (name));
12127   vec_free (name);
12128
12129   S (mp);
12130   W (ret);
12131   return ret;
12132 }
12133
12134 static int
12135 api_get_next_index (vat_main_t * vam)
12136 {
12137   unformat_input_t *i = vam->input;
12138   vl_api_get_next_index_t *mp;
12139   u8 *node_name = 0, *next_node_name = 0;
12140   int ret;
12141
12142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12143     {
12144       if (unformat (i, "node-name %s", &node_name))
12145         ;
12146       else if (unformat (i, "next-node-name %s", &next_node_name))
12147         break;
12148     }
12149
12150   if (node_name == 0)
12151     {
12152       errmsg ("node name required");
12153       return -99;
12154     }
12155   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12156     {
12157       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12158       return -99;
12159     }
12160
12161   if (next_node_name == 0)
12162     {
12163       errmsg ("next node name required");
12164       return -99;
12165     }
12166   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12167     {
12168       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12169       return -99;
12170     }
12171
12172   M (GET_NEXT_INDEX, mp);
12173   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12174   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12175   vec_free (node_name);
12176   vec_free (next_node_name);
12177
12178   S (mp);
12179   W (ret);
12180   return ret;
12181 }
12182
12183 static int
12184 api_add_node_next (vat_main_t * vam)
12185 {
12186   unformat_input_t *i = vam->input;
12187   vl_api_add_node_next_t *mp;
12188   u8 *name = 0;
12189   u8 *next = 0;
12190   int ret;
12191
12192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12193     {
12194       if (unformat (i, "node %s", &name))
12195         ;
12196       else if (unformat (i, "next %s", &next))
12197         ;
12198       else
12199         break;
12200     }
12201   if (name == 0)
12202     {
12203       errmsg ("node name required");
12204       return -99;
12205     }
12206   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12207     {
12208       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12209       return -99;
12210     }
12211   if (next == 0)
12212     {
12213       errmsg ("next node required");
12214       return -99;
12215     }
12216   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12217     {
12218       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12219       return -99;
12220     }
12221
12222   M (ADD_NODE_NEXT, mp);
12223   clib_memcpy (mp->node_name, name, vec_len (name));
12224   clib_memcpy (mp->next_name, next, vec_len (next));
12225   vec_free (name);
12226   vec_free (next);
12227
12228   S (mp);
12229   W (ret);
12230   return ret;
12231 }
12232
12233 static int
12234 api_l2tpv3_create_tunnel (vat_main_t * vam)
12235 {
12236   unformat_input_t *i = vam->input;
12237   ip6_address_t client_address, our_address;
12238   int client_address_set = 0;
12239   int our_address_set = 0;
12240   u32 local_session_id = 0;
12241   u32 remote_session_id = 0;
12242   u64 local_cookie = 0;
12243   u64 remote_cookie = 0;
12244   u8 l2_sublayer_present = 0;
12245   vl_api_l2tpv3_create_tunnel_t *mp;
12246   int ret;
12247
12248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12249     {
12250       if (unformat (i, "client_address %U", unformat_ip6_address,
12251                     &client_address))
12252         client_address_set = 1;
12253       else if (unformat (i, "our_address %U", unformat_ip6_address,
12254                          &our_address))
12255         our_address_set = 1;
12256       else if (unformat (i, "local_session_id %d", &local_session_id))
12257         ;
12258       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12259         ;
12260       else if (unformat (i, "local_cookie %lld", &local_cookie))
12261         ;
12262       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12263         ;
12264       else if (unformat (i, "l2-sublayer-present"))
12265         l2_sublayer_present = 1;
12266       else
12267         break;
12268     }
12269
12270   if (client_address_set == 0)
12271     {
12272       errmsg ("client_address required");
12273       return -99;
12274     }
12275
12276   if (our_address_set == 0)
12277     {
12278       errmsg ("our_address required");
12279       return -99;
12280     }
12281
12282   M (L2TPV3_CREATE_TUNNEL, mp);
12283
12284   clib_memcpy (mp->client_address, client_address.as_u8,
12285                sizeof (mp->client_address));
12286
12287   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12288
12289   mp->local_session_id = ntohl (local_session_id);
12290   mp->remote_session_id = ntohl (remote_session_id);
12291   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12292   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12293   mp->l2_sublayer_present = l2_sublayer_present;
12294   mp->is_ipv6 = 1;
12295
12296   S (mp);
12297   W (ret);
12298   return ret;
12299 }
12300
12301 static int
12302 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12303 {
12304   unformat_input_t *i = vam->input;
12305   u32 sw_if_index;
12306   u8 sw_if_index_set = 0;
12307   u64 new_local_cookie = 0;
12308   u64 new_remote_cookie = 0;
12309   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12310   int ret;
12311
12312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12313     {
12314       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12315         sw_if_index_set = 1;
12316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12317         sw_if_index_set = 1;
12318       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12319         ;
12320       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12321         ;
12322       else
12323         break;
12324     }
12325
12326   if (sw_if_index_set == 0)
12327     {
12328       errmsg ("missing interface name or sw_if_index");
12329       return -99;
12330     }
12331
12332   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12333
12334   mp->sw_if_index = ntohl (sw_if_index);
12335   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12336   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12337
12338   S (mp);
12339   W (ret);
12340   return ret;
12341 }
12342
12343 static int
12344 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12345 {
12346   unformat_input_t *i = vam->input;
12347   vl_api_l2tpv3_interface_enable_disable_t *mp;
12348   u32 sw_if_index;
12349   u8 sw_if_index_set = 0;
12350   u8 enable_disable = 1;
12351   int ret;
12352
12353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12354     {
12355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12356         sw_if_index_set = 1;
12357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12358         sw_if_index_set = 1;
12359       else if (unformat (i, "enable"))
12360         enable_disable = 1;
12361       else if (unformat (i, "disable"))
12362         enable_disable = 0;
12363       else
12364         break;
12365     }
12366
12367   if (sw_if_index_set == 0)
12368     {
12369       errmsg ("missing interface name or sw_if_index");
12370       return -99;
12371     }
12372
12373   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12374
12375   mp->sw_if_index = ntohl (sw_if_index);
12376   mp->enable_disable = enable_disable;
12377
12378   S (mp);
12379   W (ret);
12380   return ret;
12381 }
12382
12383 static int
12384 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12385 {
12386   unformat_input_t *i = vam->input;
12387   vl_api_l2tpv3_set_lookup_key_t *mp;
12388   u8 key = ~0;
12389   int ret;
12390
12391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12392     {
12393       if (unformat (i, "lookup_v6_src"))
12394         key = L2T_LOOKUP_SRC_ADDRESS;
12395       else if (unformat (i, "lookup_v6_dst"))
12396         key = L2T_LOOKUP_DST_ADDRESS;
12397       else if (unformat (i, "lookup_session_id"))
12398         key = L2T_LOOKUP_SESSION_ID;
12399       else
12400         break;
12401     }
12402
12403   if (key == (u8) ~ 0)
12404     {
12405       errmsg ("l2tp session lookup key unset");
12406       return -99;
12407     }
12408
12409   M (L2TPV3_SET_LOOKUP_KEY, mp);
12410
12411   mp->key = key;
12412
12413   S (mp);
12414   W (ret);
12415   return ret;
12416 }
12417
12418 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12419   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12420 {
12421   vat_main_t *vam = &vat_main;
12422
12423   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12424          format_ip6_address, mp->our_address,
12425          format_ip6_address, mp->client_address,
12426          clib_net_to_host_u32 (mp->sw_if_index));
12427
12428   print (vam->ofp,
12429          "   local cookies %016llx %016llx remote cookie %016llx",
12430          clib_net_to_host_u64 (mp->local_cookie[0]),
12431          clib_net_to_host_u64 (mp->local_cookie[1]),
12432          clib_net_to_host_u64 (mp->remote_cookie));
12433
12434   print (vam->ofp, "   local session-id %d remote session-id %d",
12435          clib_net_to_host_u32 (mp->local_session_id),
12436          clib_net_to_host_u32 (mp->remote_session_id));
12437
12438   print (vam->ofp, "   l2 specific sublayer %s\n",
12439          mp->l2_sublayer_present ? "preset" : "absent");
12440
12441 }
12442
12443 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12444   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12445 {
12446   vat_main_t *vam = &vat_main;
12447   vat_json_node_t *node = NULL;
12448   struct in6_addr addr;
12449
12450   if (VAT_JSON_ARRAY != vam->json_tree.type)
12451     {
12452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12453       vat_json_init_array (&vam->json_tree);
12454     }
12455   node = vat_json_array_add (&vam->json_tree);
12456
12457   vat_json_init_object (node);
12458
12459   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12460   vat_json_object_add_ip6 (node, "our_address", addr);
12461   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12462   vat_json_object_add_ip6 (node, "client_address", addr);
12463
12464   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12465   vat_json_init_array (lc);
12466   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12467   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12468   vat_json_object_add_uint (node, "remote_cookie",
12469                             clib_net_to_host_u64 (mp->remote_cookie));
12470
12471   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12472   vat_json_object_add_uint (node, "local_session_id",
12473                             clib_net_to_host_u32 (mp->local_session_id));
12474   vat_json_object_add_uint (node, "remote_session_id",
12475                             clib_net_to_host_u32 (mp->remote_session_id));
12476   vat_json_object_add_string_copy (node, "l2_sublayer",
12477                                    mp->l2_sublayer_present ? (u8 *) "present"
12478                                    : (u8 *) "absent");
12479 }
12480
12481 static int
12482 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12483 {
12484   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12485   vl_api_control_ping_t *mp_ping;
12486   int ret;
12487
12488   /* Get list of l2tpv3-tunnel interfaces */
12489   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12490   S (mp);
12491
12492   /* Use a control ping for synchronization */
12493   MPING (CONTROL_PING, mp_ping);
12494   S (mp_ping);
12495
12496   W (ret);
12497   return ret;
12498 }
12499
12500
12501 static void vl_api_sw_interface_tap_v2_details_t_handler
12502   (vl_api_sw_interface_tap_v2_details_t * mp)
12503 {
12504   vat_main_t *vam = &vat_main;
12505
12506   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12507                     mp->host_ip4_prefix_len);
12508   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12509                     mp->host_ip6_prefix_len);
12510
12511   print (vam->ofp,
12512          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12513          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12514          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12515          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12516          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12517
12518   vec_free (ip4);
12519   vec_free (ip6);
12520 }
12521
12522 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12523   (vl_api_sw_interface_tap_v2_details_t * mp)
12524 {
12525   vat_main_t *vam = &vat_main;
12526   vat_json_node_t *node = NULL;
12527
12528   if (VAT_JSON_ARRAY != vam->json_tree.type)
12529     {
12530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12531       vat_json_init_array (&vam->json_tree);
12532     }
12533   node = vat_json_array_add (&vam->json_tree);
12534
12535   vat_json_init_object (node);
12536   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12537   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12538   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12539   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12540   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12541   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12542   vat_json_object_add_string_copy (node, "host_mac_addr",
12543                                    format (0, "%U", format_ethernet_address,
12544                                            &mp->host_mac_addr));
12545   vat_json_object_add_string_copy (node, "host_namespace",
12546                                    mp->host_namespace);
12547   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12548   vat_json_object_add_string_copy (node, "host_ip4_addr",
12549                                    format (0, "%U/%d", format_ip4_address,
12550                                            mp->host_ip4_addr,
12551                                            mp->host_ip4_prefix_len));
12552   vat_json_object_add_string_copy (node, "host_ip6_addr",
12553                                    format (0, "%U/%d", format_ip6_address,
12554                                            mp->host_ip6_addr,
12555                                            mp->host_ip6_prefix_len));
12556
12557 }
12558
12559 static int
12560 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12561 {
12562   vl_api_sw_interface_tap_v2_dump_t *mp;
12563   vl_api_control_ping_t *mp_ping;
12564   int ret;
12565
12566   print (vam->ofp,
12567          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12568          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12569          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12570          "host_ip6_addr");
12571
12572   /* Get list of tap interfaces */
12573   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12574   S (mp);
12575
12576   /* Use a control ping for synchronization */
12577   MPING (CONTROL_PING, mp_ping);
12578   S (mp_ping);
12579
12580   W (ret);
12581   return ret;
12582 }
12583
12584 static void vl_api_sw_interface_virtio_pci_details_t_handler
12585   (vl_api_sw_interface_virtio_pci_details_t * mp)
12586 {
12587   vat_main_t *vam = &vat_main;
12588
12589   typedef union
12590   {
12591     struct
12592     {
12593       u16 domain;
12594       u8 bus;
12595       u8 slot:5;
12596       u8 function:3;
12597     };
12598     u32 as_u32;
12599   } pci_addr_t;
12600   pci_addr_t addr;
12601   addr.as_u32 = ntohl (mp->pci_addr);
12602   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12603                          addr.slot, addr.function);
12604
12605   print (vam->ofp,
12606          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12607          pci_addr, ntohl (mp->sw_if_index),
12608          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12609          format_ethernet_address, mp->mac_addr,
12610          clib_net_to_host_u64 (mp->features));
12611   vec_free (pci_addr);
12612 }
12613
12614 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12615   (vl_api_sw_interface_virtio_pci_details_t * mp)
12616 {
12617   vat_main_t *vam = &vat_main;
12618   vat_json_node_t *node = NULL;
12619
12620   if (VAT_JSON_ARRAY != vam->json_tree.type)
12621     {
12622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12623       vat_json_init_array (&vam->json_tree);
12624     }
12625   node = vat_json_array_add (&vam->json_tree);
12626
12627   vat_json_init_object (node);
12628   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12629   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12630   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12631   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12632   vat_json_object_add_uint (node, "features",
12633                             clib_net_to_host_u64 (mp->features));
12634   vat_json_object_add_string_copy (node, "mac_addr",
12635                                    format (0, "%U", format_ethernet_address,
12636                                            &mp->mac_addr));
12637 }
12638
12639 static int
12640 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12641 {
12642   vl_api_sw_interface_virtio_pci_dump_t *mp;
12643   vl_api_control_ping_t *mp_ping;
12644   int ret;
12645
12646   print (vam->ofp,
12647          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12648          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12649          "mac_addr", "features");
12650
12651   /* Get list of tap interfaces */
12652   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12653   S (mp);
12654
12655   /* Use a control ping for synchronization */
12656   MPING (CONTROL_PING, mp_ping);
12657   S (mp_ping);
12658
12659   W (ret);
12660   return ret;
12661 }
12662
12663 static int
12664 api_vxlan_offload_rx (vat_main_t * vam)
12665 {
12666   unformat_input_t *line_input = vam->input;
12667   vl_api_vxlan_offload_rx_t *mp;
12668   u32 hw_if_index = ~0, rx_if_index = ~0;
12669   u8 is_add = 1;
12670   int ret;
12671
12672   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12673     {
12674       if (unformat (line_input, "del"))
12675         is_add = 0;
12676       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12677                          &hw_if_index))
12678         ;
12679       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12680         ;
12681       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12682                          &rx_if_index))
12683         ;
12684       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12685         ;
12686       else
12687         {
12688           errmsg ("parse error '%U'", format_unformat_error, line_input);
12689           return -99;
12690         }
12691     }
12692
12693   if (hw_if_index == ~0)
12694     {
12695       errmsg ("no hw interface");
12696       return -99;
12697     }
12698
12699   if (rx_if_index == ~0)
12700     {
12701       errmsg ("no rx tunnel");
12702       return -99;
12703     }
12704
12705   M (VXLAN_OFFLOAD_RX, mp);
12706
12707   mp->hw_if_index = ntohl (hw_if_index);
12708   mp->sw_if_index = ntohl (rx_if_index);
12709   mp->enable = is_add;
12710
12711   S (mp);
12712   W (ret);
12713   return ret;
12714 }
12715
12716 static uword unformat_vxlan_decap_next
12717   (unformat_input_t * input, va_list * args)
12718 {
12719   u32 *result = va_arg (*args, u32 *);
12720   u32 tmp;
12721
12722   if (unformat (input, "l2"))
12723     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12724   else if (unformat (input, "%d", &tmp))
12725     *result = tmp;
12726   else
12727     return 0;
12728   return 1;
12729 }
12730
12731 static int
12732 api_vxlan_add_del_tunnel (vat_main_t * vam)
12733 {
12734   unformat_input_t *line_input = vam->input;
12735   vl_api_vxlan_add_del_tunnel_t *mp;
12736   ip46_address_t src, dst;
12737   u8 is_add = 1;
12738   u8 ipv4_set = 0, ipv6_set = 0;
12739   u8 src_set = 0;
12740   u8 dst_set = 0;
12741   u8 grp_set = 0;
12742   u32 instance = ~0;
12743   u32 mcast_sw_if_index = ~0;
12744   u32 encap_vrf_id = 0;
12745   u32 decap_next_index = ~0;
12746   u32 vni = 0;
12747   int ret;
12748
12749   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12750   clib_memset (&src, 0, sizeof src);
12751   clib_memset (&dst, 0, sizeof dst);
12752
12753   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12754     {
12755       if (unformat (line_input, "del"))
12756         is_add = 0;
12757       else if (unformat (line_input, "instance %d", &instance))
12758         ;
12759       else
12760         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12761         {
12762           ipv4_set = 1;
12763           src_set = 1;
12764         }
12765       else
12766         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12767         {
12768           ipv4_set = 1;
12769           dst_set = 1;
12770         }
12771       else
12772         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12773         {
12774           ipv6_set = 1;
12775           src_set = 1;
12776         }
12777       else
12778         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12779         {
12780           ipv6_set = 1;
12781           dst_set = 1;
12782         }
12783       else if (unformat (line_input, "group %U %U",
12784                          unformat_ip4_address, &dst.ip4,
12785                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12786         {
12787           grp_set = dst_set = 1;
12788           ipv4_set = 1;
12789         }
12790       else if (unformat (line_input, "group %U",
12791                          unformat_ip4_address, &dst.ip4))
12792         {
12793           grp_set = dst_set = 1;
12794           ipv4_set = 1;
12795         }
12796       else if (unformat (line_input, "group %U %U",
12797                          unformat_ip6_address, &dst.ip6,
12798                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12799         {
12800           grp_set = dst_set = 1;
12801           ipv6_set = 1;
12802         }
12803       else if (unformat (line_input, "group %U",
12804                          unformat_ip6_address, &dst.ip6))
12805         {
12806           grp_set = dst_set = 1;
12807           ipv6_set = 1;
12808         }
12809       else
12810         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12811         ;
12812       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12813         ;
12814       else if (unformat (line_input, "decap-next %U",
12815                          unformat_vxlan_decap_next, &decap_next_index))
12816         ;
12817       else if (unformat (line_input, "vni %d", &vni))
12818         ;
12819       else
12820         {
12821           errmsg ("parse error '%U'", format_unformat_error, line_input);
12822           return -99;
12823         }
12824     }
12825
12826   if (src_set == 0)
12827     {
12828       errmsg ("tunnel src address not specified");
12829       return -99;
12830     }
12831   if (dst_set == 0)
12832     {
12833       errmsg ("tunnel dst address not specified");
12834       return -99;
12835     }
12836
12837   if (grp_set && !ip46_address_is_multicast (&dst))
12838     {
12839       errmsg ("tunnel group address not multicast");
12840       return -99;
12841     }
12842   if (grp_set && mcast_sw_if_index == ~0)
12843     {
12844       errmsg ("tunnel nonexistent multicast device");
12845       return -99;
12846     }
12847   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12848     {
12849       errmsg ("tunnel dst address must be unicast");
12850       return -99;
12851     }
12852
12853
12854   if (ipv4_set && ipv6_set)
12855     {
12856       errmsg ("both IPv4 and IPv6 addresses specified");
12857       return -99;
12858     }
12859
12860   if ((vni == 0) || (vni >> 24))
12861     {
12862       errmsg ("vni not specified or out of range");
12863       return -99;
12864     }
12865
12866   M (VXLAN_ADD_DEL_TUNNEL, mp);
12867
12868   if (ipv6_set)
12869     {
12870       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12871       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12872     }
12873   else
12874     {
12875       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12876       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12877     }
12878
12879   mp->instance = htonl (instance);
12880   mp->encap_vrf_id = ntohl (encap_vrf_id);
12881   mp->decap_next_index = ntohl (decap_next_index);
12882   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12883   mp->vni = ntohl (vni);
12884   mp->is_add = is_add;
12885   mp->is_ipv6 = ipv6_set;
12886
12887   S (mp);
12888   W (ret);
12889   return ret;
12890 }
12891
12892 static void vl_api_vxlan_tunnel_details_t_handler
12893   (vl_api_vxlan_tunnel_details_t * mp)
12894 {
12895   vat_main_t *vam = &vat_main;
12896   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12897   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12898
12899   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12900          ntohl (mp->sw_if_index),
12901          ntohl (mp->instance),
12902          format_ip46_address, &src, IP46_TYPE_ANY,
12903          format_ip46_address, &dst, IP46_TYPE_ANY,
12904          ntohl (mp->encap_vrf_id),
12905          ntohl (mp->decap_next_index), ntohl (mp->vni),
12906          ntohl (mp->mcast_sw_if_index));
12907 }
12908
12909 static void vl_api_vxlan_tunnel_details_t_handler_json
12910   (vl_api_vxlan_tunnel_details_t * mp)
12911 {
12912   vat_main_t *vam = &vat_main;
12913   vat_json_node_t *node = NULL;
12914
12915   if (VAT_JSON_ARRAY != vam->json_tree.type)
12916     {
12917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12918       vat_json_init_array (&vam->json_tree);
12919     }
12920   node = vat_json_array_add (&vam->json_tree);
12921
12922   vat_json_init_object (node);
12923   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12924
12925   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12926
12927   if (mp->is_ipv6)
12928     {
12929       struct in6_addr ip6;
12930
12931       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12932       vat_json_object_add_ip6 (node, "src_address", ip6);
12933       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12934       vat_json_object_add_ip6 (node, "dst_address", ip6);
12935     }
12936   else
12937     {
12938       struct in_addr ip4;
12939
12940       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12941       vat_json_object_add_ip4 (node, "src_address", ip4);
12942       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12943       vat_json_object_add_ip4 (node, "dst_address", ip4);
12944     }
12945   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12946   vat_json_object_add_uint (node, "decap_next_index",
12947                             ntohl (mp->decap_next_index));
12948   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12949   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12950   vat_json_object_add_uint (node, "mcast_sw_if_index",
12951                             ntohl (mp->mcast_sw_if_index));
12952 }
12953
12954 static int
12955 api_vxlan_tunnel_dump (vat_main_t * vam)
12956 {
12957   unformat_input_t *i = vam->input;
12958   vl_api_vxlan_tunnel_dump_t *mp;
12959   vl_api_control_ping_t *mp_ping;
12960   u32 sw_if_index;
12961   u8 sw_if_index_set = 0;
12962   int ret;
12963
12964   /* Parse args required to build the message */
12965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12966     {
12967       if (unformat (i, "sw_if_index %d", &sw_if_index))
12968         sw_if_index_set = 1;
12969       else
12970         break;
12971     }
12972
12973   if (sw_if_index_set == 0)
12974     {
12975       sw_if_index = ~0;
12976     }
12977
12978   if (!vam->json_output)
12979     {
12980       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12981              "sw_if_index", "instance", "src_address", "dst_address",
12982              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12983     }
12984
12985   /* Get list of vxlan-tunnel interfaces */
12986   M (VXLAN_TUNNEL_DUMP, mp);
12987
12988   mp->sw_if_index = htonl (sw_if_index);
12989
12990   S (mp);
12991
12992   /* Use a control ping for synchronization */
12993   MPING (CONTROL_PING, mp_ping);
12994   S (mp_ping);
12995
12996   W (ret);
12997   return ret;
12998 }
12999
13000 static uword unformat_geneve_decap_next
13001   (unformat_input_t * input, va_list * args)
13002 {
13003   u32 *result = va_arg (*args, u32 *);
13004   u32 tmp;
13005
13006   if (unformat (input, "l2"))
13007     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13008   else if (unformat (input, "%d", &tmp))
13009     *result = tmp;
13010   else
13011     return 0;
13012   return 1;
13013 }
13014
13015 static int
13016 api_geneve_add_del_tunnel (vat_main_t * vam)
13017 {
13018   unformat_input_t *line_input = vam->input;
13019   vl_api_geneve_add_del_tunnel_t *mp;
13020   ip46_address_t src, dst;
13021   u8 is_add = 1;
13022   u8 ipv4_set = 0, ipv6_set = 0;
13023   u8 src_set = 0;
13024   u8 dst_set = 0;
13025   u8 grp_set = 0;
13026   u32 mcast_sw_if_index = ~0;
13027   u32 encap_vrf_id = 0;
13028   u32 decap_next_index = ~0;
13029   u32 vni = 0;
13030   int ret;
13031
13032   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13033   clib_memset (&src, 0, sizeof src);
13034   clib_memset (&dst, 0, sizeof dst);
13035
13036   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13037     {
13038       if (unformat (line_input, "del"))
13039         is_add = 0;
13040       else
13041         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13042         {
13043           ipv4_set = 1;
13044           src_set = 1;
13045         }
13046       else
13047         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13048         {
13049           ipv4_set = 1;
13050           dst_set = 1;
13051         }
13052       else
13053         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13054         {
13055           ipv6_set = 1;
13056           src_set = 1;
13057         }
13058       else
13059         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13060         {
13061           ipv6_set = 1;
13062           dst_set = 1;
13063         }
13064       else if (unformat (line_input, "group %U %U",
13065                          unformat_ip4_address, &dst.ip4,
13066                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13067         {
13068           grp_set = dst_set = 1;
13069           ipv4_set = 1;
13070         }
13071       else if (unformat (line_input, "group %U",
13072                          unformat_ip4_address, &dst.ip4))
13073         {
13074           grp_set = dst_set = 1;
13075           ipv4_set = 1;
13076         }
13077       else if (unformat (line_input, "group %U %U",
13078                          unformat_ip6_address, &dst.ip6,
13079                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13080         {
13081           grp_set = dst_set = 1;
13082           ipv6_set = 1;
13083         }
13084       else if (unformat (line_input, "group %U",
13085                          unformat_ip6_address, &dst.ip6))
13086         {
13087           grp_set = dst_set = 1;
13088           ipv6_set = 1;
13089         }
13090       else
13091         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13092         ;
13093       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13094         ;
13095       else if (unformat (line_input, "decap-next %U",
13096                          unformat_geneve_decap_next, &decap_next_index))
13097         ;
13098       else if (unformat (line_input, "vni %d", &vni))
13099         ;
13100       else
13101         {
13102           errmsg ("parse error '%U'", format_unformat_error, line_input);
13103           return -99;
13104         }
13105     }
13106
13107   if (src_set == 0)
13108     {
13109       errmsg ("tunnel src address not specified");
13110       return -99;
13111     }
13112   if (dst_set == 0)
13113     {
13114       errmsg ("tunnel dst address not specified");
13115       return -99;
13116     }
13117
13118   if (grp_set && !ip46_address_is_multicast (&dst))
13119     {
13120       errmsg ("tunnel group address not multicast");
13121       return -99;
13122     }
13123   if (grp_set && mcast_sw_if_index == ~0)
13124     {
13125       errmsg ("tunnel nonexistent multicast device");
13126       return -99;
13127     }
13128   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13129     {
13130       errmsg ("tunnel dst address must be unicast");
13131       return -99;
13132     }
13133
13134
13135   if (ipv4_set && ipv6_set)
13136     {
13137       errmsg ("both IPv4 and IPv6 addresses specified");
13138       return -99;
13139     }
13140
13141   if ((vni == 0) || (vni >> 24))
13142     {
13143       errmsg ("vni not specified or out of range");
13144       return -99;
13145     }
13146
13147   M (GENEVE_ADD_DEL_TUNNEL, mp);
13148
13149   if (ipv6_set)
13150     {
13151       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13152       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13153     }
13154   else
13155     {
13156       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13157       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13158     }
13159   mp->encap_vrf_id = ntohl (encap_vrf_id);
13160   mp->decap_next_index = ntohl (decap_next_index);
13161   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13162   mp->vni = ntohl (vni);
13163   mp->is_add = is_add;
13164   mp->is_ipv6 = ipv6_set;
13165
13166   S (mp);
13167   W (ret);
13168   return ret;
13169 }
13170
13171 static void vl_api_geneve_tunnel_details_t_handler
13172   (vl_api_geneve_tunnel_details_t * mp)
13173 {
13174   vat_main_t *vam = &vat_main;
13175   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13176   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13177
13178   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13179          ntohl (mp->sw_if_index),
13180          format_ip46_address, &src, IP46_TYPE_ANY,
13181          format_ip46_address, &dst, IP46_TYPE_ANY,
13182          ntohl (mp->encap_vrf_id),
13183          ntohl (mp->decap_next_index), ntohl (mp->vni),
13184          ntohl (mp->mcast_sw_if_index));
13185 }
13186
13187 static void vl_api_geneve_tunnel_details_t_handler_json
13188   (vl_api_geneve_tunnel_details_t * mp)
13189 {
13190   vat_main_t *vam = &vat_main;
13191   vat_json_node_t *node = NULL;
13192
13193   if (VAT_JSON_ARRAY != vam->json_tree.type)
13194     {
13195       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13196       vat_json_init_array (&vam->json_tree);
13197     }
13198   node = vat_json_array_add (&vam->json_tree);
13199
13200   vat_json_init_object (node);
13201   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13202   if (mp->is_ipv6)
13203     {
13204       struct in6_addr ip6;
13205
13206       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13207       vat_json_object_add_ip6 (node, "src_address", ip6);
13208       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13209       vat_json_object_add_ip6 (node, "dst_address", ip6);
13210     }
13211   else
13212     {
13213       struct in_addr ip4;
13214
13215       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13216       vat_json_object_add_ip4 (node, "src_address", ip4);
13217       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13218       vat_json_object_add_ip4 (node, "dst_address", ip4);
13219     }
13220   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13221   vat_json_object_add_uint (node, "decap_next_index",
13222                             ntohl (mp->decap_next_index));
13223   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13224   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13225   vat_json_object_add_uint (node, "mcast_sw_if_index",
13226                             ntohl (mp->mcast_sw_if_index));
13227 }
13228
13229 static int
13230 api_geneve_tunnel_dump (vat_main_t * vam)
13231 {
13232   unformat_input_t *i = vam->input;
13233   vl_api_geneve_tunnel_dump_t *mp;
13234   vl_api_control_ping_t *mp_ping;
13235   u32 sw_if_index;
13236   u8 sw_if_index_set = 0;
13237   int ret;
13238
13239   /* Parse args required to build the message */
13240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (i, "sw_if_index %d", &sw_if_index))
13243         sw_if_index_set = 1;
13244       else
13245         break;
13246     }
13247
13248   if (sw_if_index_set == 0)
13249     {
13250       sw_if_index = ~0;
13251     }
13252
13253   if (!vam->json_output)
13254     {
13255       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13256              "sw_if_index", "local_address", "remote_address",
13257              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13258     }
13259
13260   /* Get list of geneve-tunnel interfaces */
13261   M (GENEVE_TUNNEL_DUMP, mp);
13262
13263   mp->sw_if_index = htonl (sw_if_index);
13264
13265   S (mp);
13266
13267   /* Use a control ping for synchronization */
13268   M (CONTROL_PING, mp_ping);
13269   S (mp_ping);
13270
13271   W (ret);
13272   return ret;
13273 }
13274
13275 static int
13276 api_gre_add_del_tunnel (vat_main_t * vam)
13277 {
13278   unformat_input_t *line_input = vam->input;
13279   vl_api_gre_add_del_tunnel_t *mp;
13280   ip4_address_t src4, dst4;
13281   ip6_address_t src6, dst6;
13282   u8 is_add = 1;
13283   u8 ipv4_set = 0;
13284   u8 ipv6_set = 0;
13285   u8 t_type = GRE_TUNNEL_TYPE_L3;
13286   u8 src_set = 0;
13287   u8 dst_set = 0;
13288   u32 outer_fib_id = 0;
13289   u32 session_id = 0;
13290   u32 instance = ~0;
13291   int ret;
13292
13293   clib_memset (&src4, 0, sizeof src4);
13294   clib_memset (&dst4, 0, sizeof dst4);
13295   clib_memset (&src6, 0, sizeof src6);
13296   clib_memset (&dst6, 0, sizeof dst6);
13297
13298   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13299     {
13300       if (unformat (line_input, "del"))
13301         is_add = 0;
13302       else if (unformat (line_input, "instance %d", &instance))
13303         ;
13304       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13305         {
13306           src_set = 1;
13307           ipv4_set = 1;
13308         }
13309       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13310         {
13311           dst_set = 1;
13312           ipv4_set = 1;
13313         }
13314       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13315         {
13316           src_set = 1;
13317           ipv6_set = 1;
13318         }
13319       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13320         {
13321           dst_set = 1;
13322           ipv6_set = 1;
13323         }
13324       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13325         ;
13326       else if (unformat (line_input, "teb"))
13327         t_type = GRE_TUNNEL_TYPE_TEB;
13328       else if (unformat (line_input, "erspan %d", &session_id))
13329         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13330       else
13331         {
13332           errmsg ("parse error '%U'", format_unformat_error, line_input);
13333           return -99;
13334         }
13335     }
13336
13337   if (src_set == 0)
13338     {
13339       errmsg ("tunnel src address not specified");
13340       return -99;
13341     }
13342   if (dst_set == 0)
13343     {
13344       errmsg ("tunnel dst address not specified");
13345       return -99;
13346     }
13347   if (ipv4_set && ipv6_set)
13348     {
13349       errmsg ("both IPv4 and IPv6 addresses specified");
13350       return -99;
13351     }
13352
13353
13354   M (GRE_ADD_DEL_TUNNEL, mp);
13355
13356   if (ipv4_set)
13357     {
13358       clib_memcpy (&mp->src_address, &src4, 4);
13359       clib_memcpy (&mp->dst_address, &dst4, 4);
13360     }
13361   else
13362     {
13363       clib_memcpy (&mp->src_address, &src6, 16);
13364       clib_memcpy (&mp->dst_address, &dst6, 16);
13365     }
13366   mp->instance = htonl (instance);
13367   mp->outer_fib_id = htonl (outer_fib_id);
13368   mp->is_add = is_add;
13369   mp->session_id = htons ((u16) session_id);
13370   mp->tunnel_type = t_type;
13371   mp->is_ipv6 = ipv6_set;
13372
13373   S (mp);
13374   W (ret);
13375   return ret;
13376 }
13377
13378 static void vl_api_gre_tunnel_details_t_handler
13379   (vl_api_gre_tunnel_details_t * mp)
13380 {
13381   vat_main_t *vam = &vat_main;
13382   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13383   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13384
13385   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13386          ntohl (mp->sw_if_index),
13387          ntohl (mp->instance),
13388          format_ip46_address, &src, IP46_TYPE_ANY,
13389          format_ip46_address, &dst, IP46_TYPE_ANY,
13390          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13391 }
13392
13393 static void vl_api_gre_tunnel_details_t_handler_json
13394   (vl_api_gre_tunnel_details_t * mp)
13395 {
13396   vat_main_t *vam = &vat_main;
13397   vat_json_node_t *node = NULL;
13398   struct in_addr ip4;
13399   struct in6_addr ip6;
13400
13401   if (VAT_JSON_ARRAY != vam->json_tree.type)
13402     {
13403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13404       vat_json_init_array (&vam->json_tree);
13405     }
13406   node = vat_json_array_add (&vam->json_tree);
13407
13408   vat_json_init_object (node);
13409   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13410   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13411   if (!mp->is_ipv6)
13412     {
13413       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13414       vat_json_object_add_ip4 (node, "src_address", ip4);
13415       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13416       vat_json_object_add_ip4 (node, "dst_address", ip4);
13417     }
13418   else
13419     {
13420       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13421       vat_json_object_add_ip6 (node, "src_address", ip6);
13422       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13423       vat_json_object_add_ip6 (node, "dst_address", ip6);
13424     }
13425   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13426   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13427   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13428   vat_json_object_add_uint (node, "session_id", mp->session_id);
13429 }
13430
13431 static int
13432 api_gre_tunnel_dump (vat_main_t * vam)
13433 {
13434   unformat_input_t *i = vam->input;
13435   vl_api_gre_tunnel_dump_t *mp;
13436   vl_api_control_ping_t *mp_ping;
13437   u32 sw_if_index;
13438   u8 sw_if_index_set = 0;
13439   int ret;
13440
13441   /* Parse args required to build the message */
13442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13443     {
13444       if (unformat (i, "sw_if_index %d", &sw_if_index))
13445         sw_if_index_set = 1;
13446       else
13447         break;
13448     }
13449
13450   if (sw_if_index_set == 0)
13451     {
13452       sw_if_index = ~0;
13453     }
13454
13455   if (!vam->json_output)
13456     {
13457       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13458              "sw_if_index", "instance", "src_address", "dst_address",
13459              "tunnel_type", "outer_fib_id", "session_id");
13460     }
13461
13462   /* Get list of gre-tunnel interfaces */
13463   M (GRE_TUNNEL_DUMP, mp);
13464
13465   mp->sw_if_index = htonl (sw_if_index);
13466
13467   S (mp);
13468
13469   /* Use a control ping for synchronization */
13470   MPING (CONTROL_PING, mp_ping);
13471   S (mp_ping);
13472
13473   W (ret);
13474   return ret;
13475 }
13476
13477 static int
13478 api_l2_fib_clear_table (vat_main_t * vam)
13479 {
13480 //  unformat_input_t * i = vam->input;
13481   vl_api_l2_fib_clear_table_t *mp;
13482   int ret;
13483
13484   M (L2_FIB_CLEAR_TABLE, mp);
13485
13486   S (mp);
13487   W (ret);
13488   return ret;
13489 }
13490
13491 static int
13492 api_l2_interface_efp_filter (vat_main_t * vam)
13493 {
13494   unformat_input_t *i = vam->input;
13495   vl_api_l2_interface_efp_filter_t *mp;
13496   u32 sw_if_index;
13497   u8 enable = 1;
13498   u8 sw_if_index_set = 0;
13499   int ret;
13500
13501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13502     {
13503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13504         sw_if_index_set = 1;
13505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13506         sw_if_index_set = 1;
13507       else if (unformat (i, "enable"))
13508         enable = 1;
13509       else if (unformat (i, "disable"))
13510         enable = 0;
13511       else
13512         {
13513           clib_warning ("parse error '%U'", format_unformat_error, i);
13514           return -99;
13515         }
13516     }
13517
13518   if (sw_if_index_set == 0)
13519     {
13520       errmsg ("missing sw_if_index");
13521       return -99;
13522     }
13523
13524   M (L2_INTERFACE_EFP_FILTER, mp);
13525
13526   mp->sw_if_index = ntohl (sw_if_index);
13527   mp->enable_disable = enable;
13528
13529   S (mp);
13530   W (ret);
13531   return ret;
13532 }
13533
13534 #define foreach_vtr_op                          \
13535 _("disable",  L2_VTR_DISABLED)                  \
13536 _("push-1",  L2_VTR_PUSH_1)                     \
13537 _("push-2",  L2_VTR_PUSH_2)                     \
13538 _("pop-1",  L2_VTR_POP_1)                       \
13539 _("pop-2",  L2_VTR_POP_2)                       \
13540 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13541 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13542 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13543 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13544
13545 static int
13546 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13547 {
13548   unformat_input_t *i = vam->input;
13549   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13550   u32 sw_if_index;
13551   u8 sw_if_index_set = 0;
13552   u8 vtr_op_set = 0;
13553   u32 vtr_op = 0;
13554   u32 push_dot1q = 1;
13555   u32 tag1 = ~0;
13556   u32 tag2 = ~0;
13557   int ret;
13558
13559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13560     {
13561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13562         sw_if_index_set = 1;
13563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13564         sw_if_index_set = 1;
13565       else if (unformat (i, "vtr_op %d", &vtr_op))
13566         vtr_op_set = 1;
13567 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13568       foreach_vtr_op
13569 #undef _
13570         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13571         ;
13572       else if (unformat (i, "tag1 %d", &tag1))
13573         ;
13574       else if (unformat (i, "tag2 %d", &tag2))
13575         ;
13576       else
13577         {
13578           clib_warning ("parse error '%U'", format_unformat_error, i);
13579           return -99;
13580         }
13581     }
13582
13583   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13584     {
13585       errmsg ("missing vtr operation or sw_if_index");
13586       return -99;
13587     }
13588
13589   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13590   mp->sw_if_index = ntohl (sw_if_index);
13591   mp->vtr_op = ntohl (vtr_op);
13592   mp->push_dot1q = ntohl (push_dot1q);
13593   mp->tag1 = ntohl (tag1);
13594   mp->tag2 = ntohl (tag2);
13595
13596   S (mp);
13597   W (ret);
13598   return ret;
13599 }
13600
13601 static int
13602 api_create_vhost_user_if (vat_main_t * vam)
13603 {
13604   unformat_input_t *i = vam->input;
13605   vl_api_create_vhost_user_if_t *mp;
13606   u8 *file_name;
13607   u8 is_server = 0;
13608   u8 file_name_set = 0;
13609   u32 custom_dev_instance = ~0;
13610   u8 hwaddr[6];
13611   u8 use_custom_mac = 0;
13612   u8 disable_mrg_rxbuf = 0;
13613   u8 disable_indirect_desc = 0;
13614   u8 *tag = 0;
13615   int ret;
13616
13617   /* Shut up coverity */
13618   clib_memset (hwaddr, 0, sizeof (hwaddr));
13619
13620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13621     {
13622       if (unformat (i, "socket %s", &file_name))
13623         {
13624           file_name_set = 1;
13625         }
13626       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13627         ;
13628       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13629         use_custom_mac = 1;
13630       else if (unformat (i, "server"))
13631         is_server = 1;
13632       else if (unformat (i, "disable_mrg_rxbuf"))
13633         disable_mrg_rxbuf = 1;
13634       else if (unformat (i, "disable_indirect_desc"))
13635         disable_indirect_desc = 1;
13636       else if (unformat (i, "tag %s", &tag))
13637         ;
13638       else
13639         break;
13640     }
13641
13642   if (file_name_set == 0)
13643     {
13644       errmsg ("missing socket file name");
13645       return -99;
13646     }
13647
13648   if (vec_len (file_name) > 255)
13649     {
13650       errmsg ("socket file name too long");
13651       return -99;
13652     }
13653   vec_add1 (file_name, 0);
13654
13655   M (CREATE_VHOST_USER_IF, mp);
13656
13657   mp->is_server = is_server;
13658   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13659   mp->disable_indirect_desc = disable_indirect_desc;
13660   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13661   vec_free (file_name);
13662   if (custom_dev_instance != ~0)
13663     {
13664       mp->renumber = 1;
13665       mp->custom_dev_instance = ntohl (custom_dev_instance);
13666     }
13667
13668   mp->use_custom_mac = use_custom_mac;
13669   clib_memcpy (mp->mac_address, hwaddr, 6);
13670   if (tag)
13671     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13672   vec_free (tag);
13673
13674   S (mp);
13675   W (ret);
13676   return ret;
13677 }
13678
13679 static int
13680 api_modify_vhost_user_if (vat_main_t * vam)
13681 {
13682   unformat_input_t *i = vam->input;
13683   vl_api_modify_vhost_user_if_t *mp;
13684   u8 *file_name;
13685   u8 is_server = 0;
13686   u8 file_name_set = 0;
13687   u32 custom_dev_instance = ~0;
13688   u8 sw_if_index_set = 0;
13689   u32 sw_if_index = (u32) ~ 0;
13690   int ret;
13691
13692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13693     {
13694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13695         sw_if_index_set = 1;
13696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13697         sw_if_index_set = 1;
13698       else if (unformat (i, "socket %s", &file_name))
13699         {
13700           file_name_set = 1;
13701         }
13702       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13703         ;
13704       else if (unformat (i, "server"))
13705         is_server = 1;
13706       else
13707         break;
13708     }
13709
13710   if (sw_if_index_set == 0)
13711     {
13712       errmsg ("missing sw_if_index or interface name");
13713       return -99;
13714     }
13715
13716   if (file_name_set == 0)
13717     {
13718       errmsg ("missing socket file name");
13719       return -99;
13720     }
13721
13722   if (vec_len (file_name) > 255)
13723     {
13724       errmsg ("socket file name too long");
13725       return -99;
13726     }
13727   vec_add1 (file_name, 0);
13728
13729   M (MODIFY_VHOST_USER_IF, mp);
13730
13731   mp->sw_if_index = ntohl (sw_if_index);
13732   mp->is_server = is_server;
13733   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13734   vec_free (file_name);
13735   if (custom_dev_instance != ~0)
13736     {
13737       mp->renumber = 1;
13738       mp->custom_dev_instance = ntohl (custom_dev_instance);
13739     }
13740
13741   S (mp);
13742   W (ret);
13743   return ret;
13744 }
13745
13746 static int
13747 api_delete_vhost_user_if (vat_main_t * vam)
13748 {
13749   unformat_input_t *i = vam->input;
13750   vl_api_delete_vhost_user_if_t *mp;
13751   u32 sw_if_index = ~0;
13752   u8 sw_if_index_set = 0;
13753   int ret;
13754
13755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13756     {
13757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13758         sw_if_index_set = 1;
13759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13760         sw_if_index_set = 1;
13761       else
13762         break;
13763     }
13764
13765   if (sw_if_index_set == 0)
13766     {
13767       errmsg ("missing sw_if_index or interface name");
13768       return -99;
13769     }
13770
13771
13772   M (DELETE_VHOST_USER_IF, mp);
13773
13774   mp->sw_if_index = ntohl (sw_if_index);
13775
13776   S (mp);
13777   W (ret);
13778   return ret;
13779 }
13780
13781 static void vl_api_sw_interface_vhost_user_details_t_handler
13782   (vl_api_sw_interface_vhost_user_details_t * mp)
13783 {
13784   vat_main_t *vam = &vat_main;
13785
13786   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13787          (char *) mp->interface_name,
13788          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13789          clib_net_to_host_u64 (mp->features), mp->is_server,
13790          ntohl (mp->num_regions), (char *) mp->sock_filename);
13791   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13792 }
13793
13794 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13795   (vl_api_sw_interface_vhost_user_details_t * mp)
13796 {
13797   vat_main_t *vam = &vat_main;
13798   vat_json_node_t *node = NULL;
13799
13800   if (VAT_JSON_ARRAY != vam->json_tree.type)
13801     {
13802       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13803       vat_json_init_array (&vam->json_tree);
13804     }
13805   node = vat_json_array_add (&vam->json_tree);
13806
13807   vat_json_init_object (node);
13808   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13809   vat_json_object_add_string_copy (node, "interface_name",
13810                                    mp->interface_name);
13811   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13812                             ntohl (mp->virtio_net_hdr_sz));
13813   vat_json_object_add_uint (node, "features",
13814                             clib_net_to_host_u64 (mp->features));
13815   vat_json_object_add_uint (node, "is_server", mp->is_server);
13816   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13817   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13818   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13819 }
13820
13821 static int
13822 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13823 {
13824   vl_api_sw_interface_vhost_user_dump_t *mp;
13825   vl_api_control_ping_t *mp_ping;
13826   int ret;
13827   print (vam->ofp,
13828          "Interface name            idx hdr_sz features server regions filename");
13829
13830   /* Get list of vhost-user interfaces */
13831   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13832   S (mp);
13833
13834   /* Use a control ping for synchronization */
13835   MPING (CONTROL_PING, mp_ping);
13836   S (mp_ping);
13837
13838   W (ret);
13839   return ret;
13840 }
13841
13842 static int
13843 api_show_version (vat_main_t * vam)
13844 {
13845   vl_api_show_version_t *mp;
13846   int ret;
13847
13848   M (SHOW_VERSION, mp);
13849
13850   S (mp);
13851   W (ret);
13852   return ret;
13853 }
13854
13855
13856 static int
13857 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13858 {
13859   unformat_input_t *line_input = vam->input;
13860   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13861   ip4_address_t local4, remote4;
13862   ip6_address_t local6, remote6;
13863   u8 is_add = 1;
13864   u8 ipv4_set = 0, ipv6_set = 0;
13865   u8 local_set = 0;
13866   u8 remote_set = 0;
13867   u8 grp_set = 0;
13868   u32 mcast_sw_if_index = ~0;
13869   u32 encap_vrf_id = 0;
13870   u32 decap_vrf_id = 0;
13871   u8 protocol = ~0;
13872   u32 vni;
13873   u8 vni_set = 0;
13874   int ret;
13875
13876   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13877   clib_memset (&local4, 0, sizeof local4);
13878   clib_memset (&remote4, 0, sizeof remote4);
13879   clib_memset (&local6, 0, sizeof local6);
13880   clib_memset (&remote6, 0, sizeof remote6);
13881
13882   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13883     {
13884       if (unformat (line_input, "del"))
13885         is_add = 0;
13886       else if (unformat (line_input, "local %U",
13887                          unformat_ip4_address, &local4))
13888         {
13889           local_set = 1;
13890           ipv4_set = 1;
13891         }
13892       else if (unformat (line_input, "remote %U",
13893                          unformat_ip4_address, &remote4))
13894         {
13895           remote_set = 1;
13896           ipv4_set = 1;
13897         }
13898       else if (unformat (line_input, "local %U",
13899                          unformat_ip6_address, &local6))
13900         {
13901           local_set = 1;
13902           ipv6_set = 1;
13903         }
13904       else if (unformat (line_input, "remote %U",
13905                          unformat_ip6_address, &remote6))
13906         {
13907           remote_set = 1;
13908           ipv6_set = 1;
13909         }
13910       else if (unformat (line_input, "group %U %U",
13911                          unformat_ip4_address, &remote4,
13912                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13913         {
13914           grp_set = remote_set = 1;
13915           ipv4_set = 1;
13916         }
13917       else if (unformat (line_input, "group %U",
13918                          unformat_ip4_address, &remote4))
13919         {
13920           grp_set = remote_set = 1;
13921           ipv4_set = 1;
13922         }
13923       else if (unformat (line_input, "group %U %U",
13924                          unformat_ip6_address, &remote6,
13925                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13926         {
13927           grp_set = remote_set = 1;
13928           ipv6_set = 1;
13929         }
13930       else if (unformat (line_input, "group %U",
13931                          unformat_ip6_address, &remote6))
13932         {
13933           grp_set = remote_set = 1;
13934           ipv6_set = 1;
13935         }
13936       else
13937         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13938         ;
13939       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13940         ;
13941       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13942         ;
13943       else if (unformat (line_input, "vni %d", &vni))
13944         vni_set = 1;
13945       else if (unformat (line_input, "next-ip4"))
13946         protocol = 1;
13947       else if (unformat (line_input, "next-ip6"))
13948         protocol = 2;
13949       else if (unformat (line_input, "next-ethernet"))
13950         protocol = 3;
13951       else if (unformat (line_input, "next-nsh"))
13952         protocol = 4;
13953       else
13954         {
13955           errmsg ("parse error '%U'", format_unformat_error, line_input);
13956           return -99;
13957         }
13958     }
13959
13960   if (local_set == 0)
13961     {
13962       errmsg ("tunnel local address not specified");
13963       return -99;
13964     }
13965   if (remote_set == 0)
13966     {
13967       errmsg ("tunnel remote address not specified");
13968       return -99;
13969     }
13970   if (grp_set && mcast_sw_if_index == ~0)
13971     {
13972       errmsg ("tunnel nonexistent multicast device");
13973       return -99;
13974     }
13975   if (ipv4_set && ipv6_set)
13976     {
13977       errmsg ("both IPv4 and IPv6 addresses specified");
13978       return -99;
13979     }
13980
13981   if (vni_set == 0)
13982     {
13983       errmsg ("vni not specified");
13984       return -99;
13985     }
13986
13987   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13988
13989
13990   if (ipv6_set)
13991     {
13992       clib_memcpy (&mp->local, &local6, sizeof (local6));
13993       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13994     }
13995   else
13996     {
13997       clib_memcpy (&mp->local, &local4, sizeof (local4));
13998       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13999     }
14000
14001   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14002   mp->encap_vrf_id = ntohl (encap_vrf_id);
14003   mp->decap_vrf_id = ntohl (decap_vrf_id);
14004   mp->protocol = protocol;
14005   mp->vni = ntohl (vni);
14006   mp->is_add = is_add;
14007   mp->is_ipv6 = ipv6_set;
14008
14009   S (mp);
14010   W (ret);
14011   return ret;
14012 }
14013
14014 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14015   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14016 {
14017   vat_main_t *vam = &vat_main;
14018   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14019   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14020
14021   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14022          ntohl (mp->sw_if_index),
14023          format_ip46_address, &local, IP46_TYPE_ANY,
14024          format_ip46_address, &remote, IP46_TYPE_ANY,
14025          ntohl (mp->vni), mp->protocol,
14026          ntohl (mp->mcast_sw_if_index),
14027          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14028 }
14029
14030
14031 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14032   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14033 {
14034   vat_main_t *vam = &vat_main;
14035   vat_json_node_t *node = NULL;
14036   struct in_addr ip4;
14037   struct in6_addr ip6;
14038
14039   if (VAT_JSON_ARRAY != vam->json_tree.type)
14040     {
14041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14042       vat_json_init_array (&vam->json_tree);
14043     }
14044   node = vat_json_array_add (&vam->json_tree);
14045
14046   vat_json_init_object (node);
14047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14048   if (mp->is_ipv6)
14049     {
14050       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14051       vat_json_object_add_ip6 (node, "local", ip6);
14052       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14053       vat_json_object_add_ip6 (node, "remote", ip6);
14054     }
14055   else
14056     {
14057       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14058       vat_json_object_add_ip4 (node, "local", ip4);
14059       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14060       vat_json_object_add_ip4 (node, "remote", ip4);
14061     }
14062   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14063   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14064   vat_json_object_add_uint (node, "mcast_sw_if_index",
14065                             ntohl (mp->mcast_sw_if_index));
14066   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14067   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14068   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14069 }
14070
14071 static int
14072 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14073 {
14074   unformat_input_t *i = vam->input;
14075   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14076   vl_api_control_ping_t *mp_ping;
14077   u32 sw_if_index;
14078   u8 sw_if_index_set = 0;
14079   int ret;
14080
14081   /* Parse args required to build the message */
14082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14083     {
14084       if (unformat (i, "sw_if_index %d", &sw_if_index))
14085         sw_if_index_set = 1;
14086       else
14087         break;
14088     }
14089
14090   if (sw_if_index_set == 0)
14091     {
14092       sw_if_index = ~0;
14093     }
14094
14095   if (!vam->json_output)
14096     {
14097       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14098              "sw_if_index", "local", "remote", "vni",
14099              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14100     }
14101
14102   /* Get list of vxlan-tunnel interfaces */
14103   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14104
14105   mp->sw_if_index = htonl (sw_if_index);
14106
14107   S (mp);
14108
14109   /* Use a control ping for synchronization */
14110   MPING (CONTROL_PING, mp_ping);
14111   S (mp_ping);
14112
14113   W (ret);
14114   return ret;
14115 }
14116
14117 static void vl_api_l2_fib_table_details_t_handler
14118   (vl_api_l2_fib_table_details_t * mp)
14119 {
14120   vat_main_t *vam = &vat_main;
14121
14122   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14123          "       %d       %d     %d",
14124          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14125          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14126          mp->bvi_mac);
14127 }
14128
14129 static void vl_api_l2_fib_table_details_t_handler_json
14130   (vl_api_l2_fib_table_details_t * mp)
14131 {
14132   vat_main_t *vam = &vat_main;
14133   vat_json_node_t *node = NULL;
14134
14135   if (VAT_JSON_ARRAY != vam->json_tree.type)
14136     {
14137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14138       vat_json_init_array (&vam->json_tree);
14139     }
14140   node = vat_json_array_add (&vam->json_tree);
14141
14142   vat_json_init_object (node);
14143   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14144   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14145   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14146   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14147   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14148   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14149 }
14150
14151 static int
14152 api_l2_fib_table_dump (vat_main_t * vam)
14153 {
14154   unformat_input_t *i = vam->input;
14155   vl_api_l2_fib_table_dump_t *mp;
14156   vl_api_control_ping_t *mp_ping;
14157   u32 bd_id;
14158   u8 bd_id_set = 0;
14159   int ret;
14160
14161   /* Parse args required to build the message */
14162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14163     {
14164       if (unformat (i, "bd_id %d", &bd_id))
14165         bd_id_set = 1;
14166       else
14167         break;
14168     }
14169
14170   if (bd_id_set == 0)
14171     {
14172       errmsg ("missing bridge domain");
14173       return -99;
14174     }
14175
14176   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14177
14178   /* Get list of l2 fib entries */
14179   M (L2_FIB_TABLE_DUMP, mp);
14180
14181   mp->bd_id = ntohl (bd_id);
14182   S (mp);
14183
14184   /* Use a control ping for synchronization */
14185   MPING (CONTROL_PING, mp_ping);
14186   S (mp_ping);
14187
14188   W (ret);
14189   return ret;
14190 }
14191
14192
14193 static int
14194 api_interface_name_renumber (vat_main_t * vam)
14195 {
14196   unformat_input_t *line_input = vam->input;
14197   vl_api_interface_name_renumber_t *mp;
14198   u32 sw_if_index = ~0;
14199   u32 new_show_dev_instance = ~0;
14200   int ret;
14201
14202   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14205                     &sw_if_index))
14206         ;
14207       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14208         ;
14209       else if (unformat (line_input, "new_show_dev_instance %d",
14210                          &new_show_dev_instance))
14211         ;
14212       else
14213         break;
14214     }
14215
14216   if (sw_if_index == ~0)
14217     {
14218       errmsg ("missing interface name or sw_if_index");
14219       return -99;
14220     }
14221
14222   if (new_show_dev_instance == ~0)
14223     {
14224       errmsg ("missing new_show_dev_instance");
14225       return -99;
14226     }
14227
14228   M (INTERFACE_NAME_RENUMBER, mp);
14229
14230   mp->sw_if_index = ntohl (sw_if_index);
14231   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14232
14233   S (mp);
14234   W (ret);
14235   return ret;
14236 }
14237
14238 static int
14239 api_ip_probe_neighbor (vat_main_t * vam)
14240 {
14241   unformat_input_t *i = vam->input;
14242   vl_api_ip_probe_neighbor_t *mp;
14243   vl_api_address_t dst_adr;
14244   u8 int_set = 0;
14245   u8 adr_set = 0;
14246   u32 sw_if_index;
14247   int ret;
14248
14249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14250     {
14251       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14252         int_set = 1;
14253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14254         int_set = 1;
14255       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14256         adr_set = 1;
14257       else
14258         break;
14259     }
14260
14261   if (int_set == 0)
14262     {
14263       errmsg ("missing interface");
14264       return -99;
14265     }
14266
14267   if (adr_set == 0)
14268     {
14269       errmsg ("missing addresses");
14270       return -99;
14271     }
14272
14273   M (IP_PROBE_NEIGHBOR, mp);
14274
14275   mp->sw_if_index = ntohl (sw_if_index);
14276   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14277
14278   S (mp);
14279   W (ret);
14280   return ret;
14281 }
14282
14283 static int
14284 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14285 {
14286   unformat_input_t *i = vam->input;
14287   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14288   u8 mode = IP_SCAN_V46_NEIGHBORS;
14289   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14290   int ret;
14291
14292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (unformat (i, "ip4"))
14295         mode = IP_SCAN_V4_NEIGHBORS;
14296       else if (unformat (i, "ip6"))
14297         mode = IP_SCAN_V6_NEIGHBORS;
14298       if (unformat (i, "both"))
14299         mode = IP_SCAN_V46_NEIGHBORS;
14300       else if (unformat (i, "disable"))
14301         mode = IP_SCAN_DISABLED;
14302       else if (unformat (i, "interval %d", &interval))
14303         ;
14304       else if (unformat (i, "max-time %d", &time))
14305         ;
14306       else if (unformat (i, "max-update %d", &update))
14307         ;
14308       else if (unformat (i, "delay %d", &delay))
14309         ;
14310       else if (unformat (i, "stale %d", &stale))
14311         ;
14312       else
14313         break;
14314     }
14315
14316   if (interval > 255)
14317     {
14318       errmsg ("interval cannot exceed 255 minutes.");
14319       return -99;
14320     }
14321   if (time > 255)
14322     {
14323       errmsg ("max-time cannot exceed 255 usec.");
14324       return -99;
14325     }
14326   if (update > 255)
14327     {
14328       errmsg ("max-update cannot exceed 255.");
14329       return -99;
14330     }
14331   if (delay > 255)
14332     {
14333       errmsg ("delay cannot exceed 255 msec.");
14334       return -99;
14335     }
14336   if (stale > 255)
14337     {
14338       errmsg ("stale cannot exceed 255 minutes.");
14339       return -99;
14340     }
14341
14342   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14343   mp->mode = mode;
14344   mp->scan_interval = interval;
14345   mp->max_proc_time = time;
14346   mp->max_update = update;
14347   mp->scan_int_delay = delay;
14348   mp->stale_threshold = stale;
14349
14350   S (mp);
14351   W (ret);
14352   return ret;
14353 }
14354
14355 static int
14356 api_want_ip4_arp_events (vat_main_t * vam)
14357 {
14358   unformat_input_t *line_input = vam->input;
14359   vl_api_want_ip4_arp_events_t *mp;
14360   ip4_address_t address;
14361   int address_set = 0;
14362   u32 enable_disable = 1;
14363   int ret;
14364
14365   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14366     {
14367       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14368         address_set = 1;
14369       else if (unformat (line_input, "del"))
14370         enable_disable = 0;
14371       else
14372         break;
14373     }
14374
14375   if (address_set == 0)
14376     {
14377       errmsg ("missing addresses");
14378       return -99;
14379     }
14380
14381   M (WANT_IP4_ARP_EVENTS, mp);
14382   mp->enable_disable = enable_disable;
14383   mp->pid = htonl (getpid ());
14384   clib_memcpy (mp->ip, &address, sizeof (address));
14385
14386   S (mp);
14387   W (ret);
14388   return ret;
14389 }
14390
14391 static int
14392 api_want_ip6_nd_events (vat_main_t * vam)
14393 {
14394   unformat_input_t *line_input = vam->input;
14395   vl_api_want_ip6_nd_events_t *mp;
14396   vl_api_ip6_address_t address;
14397   int address_set = 0;
14398   u32 enable_disable = 1;
14399   int ret;
14400
14401   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat
14404           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14405         address_set = 1;
14406       else if (unformat (line_input, "del"))
14407         enable_disable = 0;
14408       else
14409         break;
14410     }
14411
14412   if (address_set == 0)
14413     {
14414       errmsg ("missing addresses");
14415       return -99;
14416     }
14417
14418   M (WANT_IP6_ND_EVENTS, mp);
14419   mp->enable_disable = enable_disable;
14420   mp->pid = htonl (getpid ());
14421   clib_memcpy (&mp->ip, &address, sizeof (address));
14422
14423   S (mp);
14424   W (ret);
14425   return ret;
14426 }
14427
14428 static int
14429 api_want_l2_macs_events (vat_main_t * vam)
14430 {
14431   unformat_input_t *line_input = vam->input;
14432   vl_api_want_l2_macs_events_t *mp;
14433   u8 enable_disable = 1;
14434   u32 scan_delay = 0;
14435   u32 max_macs_in_event = 0;
14436   u32 learn_limit = 0;
14437   int ret;
14438
14439   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14440     {
14441       if (unformat (line_input, "learn-limit %d", &learn_limit))
14442         ;
14443       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14444         ;
14445       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14446         ;
14447       else if (unformat (line_input, "disable"))
14448         enable_disable = 0;
14449       else
14450         break;
14451     }
14452
14453   M (WANT_L2_MACS_EVENTS, mp);
14454   mp->enable_disable = enable_disable;
14455   mp->pid = htonl (getpid ());
14456   mp->learn_limit = htonl (learn_limit);
14457   mp->scan_delay = (u8) scan_delay;
14458   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14459   S (mp);
14460   W (ret);
14461   return ret;
14462 }
14463
14464 static int
14465 api_input_acl_set_interface (vat_main_t * vam)
14466 {
14467   unformat_input_t *i = vam->input;
14468   vl_api_input_acl_set_interface_t *mp;
14469   u32 sw_if_index;
14470   int sw_if_index_set;
14471   u32 ip4_table_index = ~0;
14472   u32 ip6_table_index = ~0;
14473   u32 l2_table_index = ~0;
14474   u8 is_add = 1;
14475   int ret;
14476
14477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14478     {
14479       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14480         sw_if_index_set = 1;
14481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14482         sw_if_index_set = 1;
14483       else if (unformat (i, "del"))
14484         is_add = 0;
14485       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14486         ;
14487       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14488         ;
14489       else if (unformat (i, "l2-table %d", &l2_table_index))
14490         ;
14491       else
14492         {
14493           clib_warning ("parse error '%U'", format_unformat_error, i);
14494           return -99;
14495         }
14496     }
14497
14498   if (sw_if_index_set == 0)
14499     {
14500       errmsg ("missing interface name or sw_if_index");
14501       return -99;
14502     }
14503
14504   M (INPUT_ACL_SET_INTERFACE, mp);
14505
14506   mp->sw_if_index = ntohl (sw_if_index);
14507   mp->ip4_table_index = ntohl (ip4_table_index);
14508   mp->ip6_table_index = ntohl (ip6_table_index);
14509   mp->l2_table_index = ntohl (l2_table_index);
14510   mp->is_add = is_add;
14511
14512   S (mp);
14513   W (ret);
14514   return ret;
14515 }
14516
14517 static int
14518 api_output_acl_set_interface (vat_main_t * vam)
14519 {
14520   unformat_input_t *i = vam->input;
14521   vl_api_output_acl_set_interface_t *mp;
14522   u32 sw_if_index;
14523   int sw_if_index_set;
14524   u32 ip4_table_index = ~0;
14525   u32 ip6_table_index = ~0;
14526   u32 l2_table_index = ~0;
14527   u8 is_add = 1;
14528   int ret;
14529
14530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14531     {
14532       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14533         sw_if_index_set = 1;
14534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14535         sw_if_index_set = 1;
14536       else if (unformat (i, "del"))
14537         is_add = 0;
14538       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14539         ;
14540       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14541         ;
14542       else if (unformat (i, "l2-table %d", &l2_table_index))
14543         ;
14544       else
14545         {
14546           clib_warning ("parse error '%U'", format_unformat_error, i);
14547           return -99;
14548         }
14549     }
14550
14551   if (sw_if_index_set == 0)
14552     {
14553       errmsg ("missing interface name or sw_if_index");
14554       return -99;
14555     }
14556
14557   M (OUTPUT_ACL_SET_INTERFACE, mp);
14558
14559   mp->sw_if_index = ntohl (sw_if_index);
14560   mp->ip4_table_index = ntohl (ip4_table_index);
14561   mp->ip6_table_index = ntohl (ip6_table_index);
14562   mp->l2_table_index = ntohl (l2_table_index);
14563   mp->is_add = is_add;
14564
14565   S (mp);
14566   W (ret);
14567   return ret;
14568 }
14569
14570 static int
14571 api_ip_address_dump (vat_main_t * vam)
14572 {
14573   unformat_input_t *i = vam->input;
14574   vl_api_ip_address_dump_t *mp;
14575   vl_api_control_ping_t *mp_ping;
14576   u32 sw_if_index = ~0;
14577   u8 sw_if_index_set = 0;
14578   u8 ipv4_set = 0;
14579   u8 ipv6_set = 0;
14580   int ret;
14581
14582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14583     {
14584       if (unformat (i, "sw_if_index %d", &sw_if_index))
14585         sw_if_index_set = 1;
14586       else
14587         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14588         sw_if_index_set = 1;
14589       else if (unformat (i, "ipv4"))
14590         ipv4_set = 1;
14591       else if (unformat (i, "ipv6"))
14592         ipv6_set = 1;
14593       else
14594         break;
14595     }
14596
14597   if (ipv4_set && ipv6_set)
14598     {
14599       errmsg ("ipv4 and ipv6 flags cannot be both set");
14600       return -99;
14601     }
14602
14603   if ((!ipv4_set) && (!ipv6_set))
14604     {
14605       errmsg ("no ipv4 nor ipv6 flag set");
14606       return -99;
14607     }
14608
14609   if (sw_if_index_set == 0)
14610     {
14611       errmsg ("missing interface name or sw_if_index");
14612       return -99;
14613     }
14614
14615   vam->current_sw_if_index = sw_if_index;
14616   vam->is_ipv6 = ipv6_set;
14617
14618   M (IP_ADDRESS_DUMP, mp);
14619   mp->sw_if_index = ntohl (sw_if_index);
14620   mp->is_ipv6 = ipv6_set;
14621   S (mp);
14622
14623   /* Use a control ping for synchronization */
14624   MPING (CONTROL_PING, mp_ping);
14625   S (mp_ping);
14626
14627   W (ret);
14628   return ret;
14629 }
14630
14631 static int
14632 api_ip_dump (vat_main_t * vam)
14633 {
14634   vl_api_ip_dump_t *mp;
14635   vl_api_control_ping_t *mp_ping;
14636   unformat_input_t *in = vam->input;
14637   int ipv4_set = 0;
14638   int ipv6_set = 0;
14639   int is_ipv6;
14640   int i;
14641   int ret;
14642
14643   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14644     {
14645       if (unformat (in, "ipv4"))
14646         ipv4_set = 1;
14647       else if (unformat (in, "ipv6"))
14648         ipv6_set = 1;
14649       else
14650         break;
14651     }
14652
14653   if (ipv4_set && ipv6_set)
14654     {
14655       errmsg ("ipv4 and ipv6 flags cannot be both set");
14656       return -99;
14657     }
14658
14659   if ((!ipv4_set) && (!ipv6_set))
14660     {
14661       errmsg ("no ipv4 nor ipv6 flag set");
14662       return -99;
14663     }
14664
14665   is_ipv6 = ipv6_set;
14666   vam->is_ipv6 = is_ipv6;
14667
14668   /* free old data */
14669   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14670     {
14671       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14672     }
14673   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14674
14675   M (IP_DUMP, mp);
14676   mp->is_ipv6 = ipv6_set;
14677   S (mp);
14678
14679   /* Use a control ping for synchronization */
14680   MPING (CONTROL_PING, mp_ping);
14681   S (mp_ping);
14682
14683   W (ret);
14684   return ret;
14685 }
14686
14687 static int
14688 api_ipsec_spd_add_del (vat_main_t * vam)
14689 {
14690   unformat_input_t *i = vam->input;
14691   vl_api_ipsec_spd_add_del_t *mp;
14692   u32 spd_id = ~0;
14693   u8 is_add = 1;
14694   int ret;
14695
14696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14697     {
14698       if (unformat (i, "spd_id %d", &spd_id))
14699         ;
14700       else if (unformat (i, "del"))
14701         is_add = 0;
14702       else
14703         {
14704           clib_warning ("parse error '%U'", format_unformat_error, i);
14705           return -99;
14706         }
14707     }
14708   if (spd_id == ~0)
14709     {
14710       errmsg ("spd_id must be set");
14711       return -99;
14712     }
14713
14714   M (IPSEC_SPD_ADD_DEL, mp);
14715
14716   mp->spd_id = ntohl (spd_id);
14717   mp->is_add = is_add;
14718
14719   S (mp);
14720   W (ret);
14721   return ret;
14722 }
14723
14724 static int
14725 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14726 {
14727   unformat_input_t *i = vam->input;
14728   vl_api_ipsec_interface_add_del_spd_t *mp;
14729   u32 sw_if_index;
14730   u8 sw_if_index_set = 0;
14731   u32 spd_id = (u32) ~ 0;
14732   u8 is_add = 1;
14733   int ret;
14734
14735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14736     {
14737       if (unformat (i, "del"))
14738         is_add = 0;
14739       else if (unformat (i, "spd_id %d", &spd_id))
14740         ;
14741       else
14742         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14743         sw_if_index_set = 1;
14744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14745         sw_if_index_set = 1;
14746       else
14747         {
14748           clib_warning ("parse error '%U'", format_unformat_error, i);
14749           return -99;
14750         }
14751
14752     }
14753
14754   if (spd_id == (u32) ~ 0)
14755     {
14756       errmsg ("spd_id must be set");
14757       return -99;
14758     }
14759
14760   if (sw_if_index_set == 0)
14761     {
14762       errmsg ("missing interface name or sw_if_index");
14763       return -99;
14764     }
14765
14766   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14767
14768   mp->spd_id = ntohl (spd_id);
14769   mp->sw_if_index = ntohl (sw_if_index);
14770   mp->is_add = is_add;
14771
14772   S (mp);
14773   W (ret);
14774   return ret;
14775 }
14776
14777 static int
14778 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14779 {
14780   unformat_input_t *i = vam->input;
14781   vl_api_ipsec_spd_entry_add_del_t *mp;
14782   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14783   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14784   i32 priority = 0;
14785   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14786   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14787   vl_api_address_t laddr_start = { }, laddr_stop =
14788   {
14789   }, raddr_start =
14790   {
14791   }, raddr_stop =
14792   {
14793   };
14794   int ret;
14795
14796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14797     {
14798       if (unformat (i, "del"))
14799         is_add = 0;
14800       if (unformat (i, "outbound"))
14801         is_outbound = 1;
14802       if (unformat (i, "inbound"))
14803         is_outbound = 0;
14804       else if (unformat (i, "spd_id %d", &spd_id))
14805         ;
14806       else if (unformat (i, "sa_id %d", &sa_id))
14807         ;
14808       else if (unformat (i, "priority %d", &priority))
14809         ;
14810       else if (unformat (i, "protocol %d", &protocol))
14811         ;
14812       else if (unformat (i, "lport_start %d", &lport_start))
14813         ;
14814       else if (unformat (i, "lport_stop %d", &lport_stop))
14815         ;
14816       else if (unformat (i, "rport_start %d", &rport_start))
14817         ;
14818       else if (unformat (i, "rport_stop %d", &rport_stop))
14819         ;
14820       else if (unformat (i, "laddr_start %U",
14821                          unformat_vl_api_address, &laddr_start))
14822         is_ip_any = 0;
14823       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14824                          &laddr_stop))
14825         is_ip_any = 0;
14826       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14827                          &raddr_start))
14828         is_ip_any = 0;
14829       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14830                          &raddr_stop))
14831         is_ip_any = 0;
14832       else
14833         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14834         {
14835           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14836             {
14837               clib_warning ("unsupported action: 'resolve'");
14838               return -99;
14839             }
14840         }
14841       else
14842         {
14843           clib_warning ("parse error '%U'", format_unformat_error, i);
14844           return -99;
14845         }
14846
14847     }
14848
14849   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14850
14851   mp->is_add = is_add;
14852
14853   mp->entry.spd_id = ntohl (spd_id);
14854   mp->entry.priority = ntohl (priority);
14855   mp->entry.is_outbound = is_outbound;
14856
14857   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14858                sizeof (vl_api_address_t));
14859   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14860                sizeof (vl_api_address_t));
14861   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14862                sizeof (vl_api_address_t));
14863   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14864                sizeof (vl_api_address_t));
14865
14866   mp->entry.protocol = (u8) protocol;
14867   mp->entry.local_port_start = ntohs ((u16) lport_start);
14868   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14869   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14870   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14871   mp->entry.policy = (u8) policy;
14872   mp->entry.sa_id = ntohl (sa_id);
14873
14874   S (mp);
14875   W (ret);
14876   return ret;
14877 }
14878
14879 static int
14880 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14881 {
14882   unformat_input_t *i = vam->input;
14883   vl_api_ipsec_sad_entry_add_del_t *mp;
14884   u32 sad_id = 0, spi = 0;
14885   u8 *ck = 0, *ik = 0;
14886   u8 is_add = 1;
14887
14888   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14889   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14890   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14891   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14892   vl_api_address_t tun_src, tun_dst;
14893   int ret;
14894
14895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14896     {
14897       if (unformat (i, "del"))
14898         is_add = 0;
14899       else if (unformat (i, "sad_id %d", &sad_id))
14900         ;
14901       else if (unformat (i, "spi %d", &spi))
14902         ;
14903       else if (unformat (i, "esp"))
14904         protocol = IPSEC_API_PROTO_ESP;
14905       else
14906         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14907         {
14908           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14909           if (ADDRESS_IP6 == tun_src.af)
14910             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14911         }
14912       else
14913         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
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, "crypto_alg %U",
14921                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14922         ;
14923       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14924         ;
14925       else if (unformat (i, "integ_alg %U",
14926                          unformat_ipsec_api_integ_alg, &integ_alg))
14927         ;
14928       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14929         ;
14930       else
14931         {
14932           clib_warning ("parse error '%U'", format_unformat_error, i);
14933           return -99;
14934         }
14935
14936     }
14937
14938   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14939
14940   mp->is_add = is_add;
14941   mp->entry.sad_id = ntohl (sad_id);
14942   mp->entry.protocol = protocol;
14943   mp->entry.spi = ntohl (spi);
14944   mp->entry.flags = flags;
14945
14946   mp->entry.crypto_algorithm = crypto_alg;
14947   mp->entry.integrity_algorithm = integ_alg;
14948   mp->entry.crypto_key.length = vec_len (ck);
14949   mp->entry.integrity_key.length = vec_len (ik);
14950
14951   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14952     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14953
14954   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14955     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14956
14957   if (ck)
14958     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14959   if (ik)
14960     clib_memcpy (mp->entry.integrity_key.data, ik,
14961                  mp->entry.integrity_key.length);
14962
14963   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14964     {
14965       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14966                    sizeof (mp->entry.tunnel_src));
14967       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14968                    sizeof (mp->entry.tunnel_dst));
14969     }
14970
14971   S (mp);
14972   W (ret);
14973   return ret;
14974 }
14975
14976 static int
14977 api_ipsec_sa_set_key (vat_main_t * vam)
14978 {
14979   unformat_input_t *i = vam->input;
14980   vl_api_ipsec_sa_set_key_t *mp;
14981   u32 sa_id;
14982   u8 *ck = 0, *ik = 0;
14983   int ret;
14984
14985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14986     {
14987       if (unformat (i, "sa_id %d", &sa_id))
14988         ;
14989       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14990         ;
14991       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14992         ;
14993       else
14994         {
14995           clib_warning ("parse error '%U'", format_unformat_error, i);
14996           return -99;
14997         }
14998     }
14999
15000   M (IPSEC_SA_SET_KEY, mp);
15001
15002   mp->sa_id = ntohl (sa_id);
15003   mp->crypto_key.length = vec_len (ck);
15004   mp->integrity_key.length = vec_len (ik);
15005
15006   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15007     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15008
15009   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15010     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15011
15012   if (ck)
15013     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15014   if (ik)
15015     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15016
15017   S (mp);
15018   W (ret);
15019   return ret;
15020 }
15021
15022 static int
15023 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15024 {
15025   unformat_input_t *i = vam->input;
15026   vl_api_ipsec_tunnel_if_add_del_t *mp;
15027   u32 local_spi = 0, remote_spi = 0;
15028   u32 crypto_alg = 0, integ_alg = 0;
15029   u8 *lck = NULL, *rck = NULL;
15030   u8 *lik = NULL, *rik = NULL;
15031   vl_api_address_t local_ip = { 0 };
15032   vl_api_address_t remote_ip = { 0 };
15033   u8 is_add = 1;
15034   u8 esn = 0;
15035   u8 anti_replay = 0;
15036   u8 renumber = 0;
15037   u32 instance = ~0;
15038   int ret;
15039
15040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (i, "del"))
15043         is_add = 0;
15044       else if (unformat (i, "esn"))
15045         esn = 1;
15046       else if (unformat (i, "anti_replay"))
15047         anti_replay = 1;
15048       else if (unformat (i, "local_spi %d", &local_spi))
15049         ;
15050       else if (unformat (i, "remote_spi %d", &remote_spi))
15051         ;
15052       else
15053         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
15054         ;
15055       else
15056         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
15057         ;
15058       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15059         ;
15060       else
15061         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15062         ;
15063       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15064         ;
15065       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15066         ;
15067       else
15068         if (unformat
15069             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15070         {
15071           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15072             {
15073               errmsg ("unsupported crypto-alg: '%U'\n",
15074                       format_ipsec_crypto_alg, crypto_alg);
15075               return -99;
15076             }
15077         }
15078       else
15079         if (unformat
15080             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15081         {
15082           if (integ_alg >= IPSEC_INTEG_N_ALG)
15083             {
15084               errmsg ("unsupported integ-alg: '%U'\n",
15085                       format_ipsec_integ_alg, integ_alg);
15086               return -99;
15087             }
15088         }
15089       else if (unformat (i, "instance %u", &instance))
15090         renumber = 1;
15091       else
15092         {
15093           errmsg ("parse error '%U'\n", format_unformat_error, i);
15094           return -99;
15095         }
15096     }
15097
15098   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15099
15100   mp->is_add = is_add;
15101   mp->esn = esn;
15102   mp->anti_replay = anti_replay;
15103
15104   clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15105   clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15106
15107   mp->local_spi = htonl (local_spi);
15108   mp->remote_spi = htonl (remote_spi);
15109   mp->crypto_alg = (u8) crypto_alg;
15110
15111   mp->local_crypto_key_len = 0;
15112   if (lck)
15113     {
15114       mp->local_crypto_key_len = vec_len (lck);
15115       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15116         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15117       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15118     }
15119
15120   mp->remote_crypto_key_len = 0;
15121   if (rck)
15122     {
15123       mp->remote_crypto_key_len = vec_len (rck);
15124       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15125         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15126       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15127     }
15128
15129   mp->integ_alg = (u8) integ_alg;
15130
15131   mp->local_integ_key_len = 0;
15132   if (lik)
15133     {
15134       mp->local_integ_key_len = vec_len (lik);
15135       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15136         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15137       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15138     }
15139
15140   mp->remote_integ_key_len = 0;
15141   if (rik)
15142     {
15143       mp->remote_integ_key_len = vec_len (rik);
15144       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15145         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15146       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15147     }
15148
15149   if (renumber)
15150     {
15151       mp->renumber = renumber;
15152       mp->show_instance = ntohl (instance);
15153     }
15154
15155   S (mp);
15156   W (ret);
15157   return ret;
15158 }
15159
15160 static void
15161 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15162 {
15163   vat_main_t *vam = &vat_main;
15164
15165   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15166          "crypto_key %U integ_alg %u integ_key %U flags %x "
15167          "tunnel_src_addr %U tunnel_dst_addr %U "
15168          "salt %u seq_outbound %lu last_seq_inbound %lu "
15169          "replay_window %lu\n",
15170          ntohl (mp->entry.sad_id),
15171          ntohl (mp->sw_if_index),
15172          ntohl (mp->entry.spi),
15173          ntohl (mp->entry.protocol),
15174          ntohl (mp->entry.crypto_algorithm),
15175          format_hex_bytes, mp->entry.crypto_key.data,
15176          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15177          format_hex_bytes, mp->entry.integrity_key.data,
15178          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15179          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15180          &mp->entry.tunnel_dst, ntohl (mp->salt),
15181          clib_net_to_host_u64 (mp->seq_outbound),
15182          clib_net_to_host_u64 (mp->last_seq_inbound),
15183          clib_net_to_host_u64 (mp->replay_window));
15184 }
15185
15186 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15187 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15188
15189 static void
15190 vat_json_object_add_address (vat_json_node_t * node,
15191                              const vl_api_address_t * addr)
15192 {
15193   if (ADDRESS_IP6 == addr->af)
15194     {
15195       struct in6_addr ip6;
15196
15197       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
15198       vat_json_object_add_ip6 (node, "ip_address", ip6);
15199     }
15200   else
15201     {
15202       struct in_addr ip4;
15203
15204       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
15205       vat_json_object_add_ip4 (node, "ip_address", ip4);
15206     }
15207 }
15208
15209 static void vl_api_ipsec_sa_details_t_handler_json
15210   (vl_api_ipsec_sa_details_t * mp)
15211 {
15212   vat_main_t *vam = &vat_main;
15213   vat_json_node_t *node = NULL;
15214   vl_api_ipsec_sad_flags_t flags;
15215
15216   if (VAT_JSON_ARRAY != vam->json_tree.type)
15217     {
15218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15219       vat_json_init_array (&vam->json_tree);
15220     }
15221   node = vat_json_array_add (&vam->json_tree);
15222
15223   vat_json_init_object (node);
15224   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15225   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15226   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15227   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15228   vat_json_object_add_uint (node, "crypto_alg",
15229                             ntohl (mp->entry.crypto_algorithm));
15230   vat_json_object_add_uint (node, "integ_alg",
15231                             ntohl (mp->entry.integrity_algorithm));
15232   flags = ntohl (mp->entry.flags);
15233   vat_json_object_add_uint (node, "use_esn",
15234                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15235   vat_json_object_add_uint (node, "use_anti_replay",
15236                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15237   vat_json_object_add_uint (node, "is_tunnel",
15238                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15239   vat_json_object_add_uint (node, "is_tunnel_ip6",
15240                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15241   vat_json_object_add_uint (node, "udp_encap",
15242                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15243   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15244                              mp->entry.crypto_key.length);
15245   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15246                              mp->entry.integrity_key.length);
15247   vat_json_object_add_address (node, &mp->entry.tunnel_src);
15248   vat_json_object_add_address (node, &mp->entry.tunnel_dst);
15249   vat_json_object_add_uint (node, "replay_window",
15250                             clib_net_to_host_u64 (mp->replay_window));
15251 }
15252
15253 static int
15254 api_ipsec_sa_dump (vat_main_t * vam)
15255 {
15256   unformat_input_t *i = vam->input;
15257   vl_api_ipsec_sa_dump_t *mp;
15258   vl_api_control_ping_t *mp_ping;
15259   u32 sa_id = ~0;
15260   int ret;
15261
15262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15263     {
15264       if (unformat (i, "sa_id %d", &sa_id))
15265         ;
15266       else
15267         {
15268           clib_warning ("parse error '%U'", format_unformat_error, i);
15269           return -99;
15270         }
15271     }
15272
15273   M (IPSEC_SA_DUMP, mp);
15274
15275   mp->sa_id = ntohl (sa_id);
15276
15277   S (mp);
15278
15279   /* Use a control ping for synchronization */
15280   M (CONTROL_PING, mp_ping);
15281   S (mp_ping);
15282
15283   W (ret);
15284   return ret;
15285 }
15286
15287 static int
15288 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15289 {
15290   unformat_input_t *i = vam->input;
15291   vl_api_ipsec_tunnel_if_set_key_t *mp;
15292   u32 sw_if_index = ~0;
15293   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15294   u8 *key = 0;
15295   u32 alg = ~0;
15296   int ret;
15297
15298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15299     {
15300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15301         ;
15302       else
15303         if (unformat
15304             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15305         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15306       else
15307         if (unformat
15308             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15309         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15310       else
15311         if (unformat
15312             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15313         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15314       else
15315         if (unformat
15316             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15317         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15318       else if (unformat (i, "%U", unformat_hex_string, &key))
15319         ;
15320       else
15321         {
15322           clib_warning ("parse error '%U'", format_unformat_error, i);
15323           return -99;
15324         }
15325     }
15326
15327   if (sw_if_index == ~0)
15328     {
15329       errmsg ("interface must be specified");
15330       return -99;
15331     }
15332
15333   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15334     {
15335       errmsg ("key type must be specified");
15336       return -99;
15337     }
15338
15339   if (alg == ~0)
15340     {
15341       errmsg ("algorithm must be specified");
15342       return -99;
15343     }
15344
15345   if (vec_len (key) == 0)
15346     {
15347       errmsg ("key must be specified");
15348       return -99;
15349     }
15350
15351   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15352
15353   mp->sw_if_index = htonl (sw_if_index);
15354   mp->alg = alg;
15355   mp->key_type = key_type;
15356   mp->key_len = vec_len (key);
15357   clib_memcpy (mp->key, key, vec_len (key));
15358
15359   S (mp);
15360   W (ret);
15361
15362   return ret;
15363 }
15364
15365 static int
15366 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15367 {
15368   unformat_input_t *i = vam->input;
15369   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15370   u32 sw_if_index = ~0;
15371   u32 sa_id = ~0;
15372   u8 is_outbound = (u8) ~ 0;
15373   int ret;
15374
15375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15376     {
15377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15378         ;
15379       else if (unformat (i, "sa_id %d", &sa_id))
15380         ;
15381       else if (unformat (i, "outbound"))
15382         is_outbound = 1;
15383       else if (unformat (i, "inbound"))
15384         is_outbound = 0;
15385       else
15386         {
15387           clib_warning ("parse error '%U'", format_unformat_error, i);
15388           return -99;
15389         }
15390     }
15391
15392   if (sw_if_index == ~0)
15393     {
15394       errmsg ("interface must be specified");
15395       return -99;
15396     }
15397
15398   if (sa_id == ~0)
15399     {
15400       errmsg ("SA ID must be specified");
15401       return -99;
15402     }
15403
15404   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15405
15406   mp->sw_if_index = htonl (sw_if_index);
15407   mp->sa_id = htonl (sa_id);
15408   mp->is_outbound = is_outbound;
15409
15410   S (mp);
15411   W (ret);
15412
15413   return ret;
15414 }
15415
15416 static int
15417 api_get_first_msg_id (vat_main_t * vam)
15418 {
15419   vl_api_get_first_msg_id_t *mp;
15420   unformat_input_t *i = vam->input;
15421   u8 *name;
15422   u8 name_set = 0;
15423   int ret;
15424
15425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15426     {
15427       if (unformat (i, "client %s", &name))
15428         name_set = 1;
15429       else
15430         break;
15431     }
15432
15433   if (name_set == 0)
15434     {
15435       errmsg ("missing client name");
15436       return -99;
15437     }
15438   vec_add1 (name, 0);
15439
15440   if (vec_len (name) > 63)
15441     {
15442       errmsg ("client name too long");
15443       return -99;
15444     }
15445
15446   M (GET_FIRST_MSG_ID, mp);
15447   clib_memcpy (mp->name, name, vec_len (name));
15448   S (mp);
15449   W (ret);
15450   return ret;
15451 }
15452
15453 static int
15454 api_cop_interface_enable_disable (vat_main_t * vam)
15455 {
15456   unformat_input_t *line_input = vam->input;
15457   vl_api_cop_interface_enable_disable_t *mp;
15458   u32 sw_if_index = ~0;
15459   u8 enable_disable = 1;
15460   int ret;
15461
15462   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15463     {
15464       if (unformat (line_input, "disable"))
15465         enable_disable = 0;
15466       if (unformat (line_input, "enable"))
15467         enable_disable = 1;
15468       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15469                          vam, &sw_if_index))
15470         ;
15471       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15472         ;
15473       else
15474         break;
15475     }
15476
15477   if (sw_if_index == ~0)
15478     {
15479       errmsg ("missing interface name or sw_if_index");
15480       return -99;
15481     }
15482
15483   /* Construct the API message */
15484   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15485   mp->sw_if_index = ntohl (sw_if_index);
15486   mp->enable_disable = enable_disable;
15487
15488   /* send it... */
15489   S (mp);
15490   /* Wait for the reply */
15491   W (ret);
15492   return ret;
15493 }
15494
15495 static int
15496 api_cop_whitelist_enable_disable (vat_main_t * vam)
15497 {
15498   unformat_input_t *line_input = vam->input;
15499   vl_api_cop_whitelist_enable_disable_t *mp;
15500   u32 sw_if_index = ~0;
15501   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15502   u32 fib_id = 0;
15503   int ret;
15504
15505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (line_input, "ip4"))
15508         ip4 = 1;
15509       else if (unformat (line_input, "ip6"))
15510         ip6 = 1;
15511       else if (unformat (line_input, "default"))
15512         default_cop = 1;
15513       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15514                          vam, &sw_if_index))
15515         ;
15516       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15517         ;
15518       else if (unformat (line_input, "fib-id %d", &fib_id))
15519         ;
15520       else
15521         break;
15522     }
15523
15524   if (sw_if_index == ~0)
15525     {
15526       errmsg ("missing interface name or sw_if_index");
15527       return -99;
15528     }
15529
15530   /* Construct the API message */
15531   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15532   mp->sw_if_index = ntohl (sw_if_index);
15533   mp->fib_id = ntohl (fib_id);
15534   mp->ip4 = ip4;
15535   mp->ip6 = ip6;
15536   mp->default_cop = default_cop;
15537
15538   /* send it... */
15539   S (mp);
15540   /* Wait for the reply */
15541   W (ret);
15542   return ret;
15543 }
15544
15545 static int
15546 api_get_node_graph (vat_main_t * vam)
15547 {
15548   vl_api_get_node_graph_t *mp;
15549   int ret;
15550
15551   M (GET_NODE_GRAPH, mp);
15552
15553   /* send it... */
15554   S (mp);
15555   /* Wait for the reply */
15556   W (ret);
15557   return ret;
15558 }
15559
15560 /* *INDENT-OFF* */
15561 /** Used for parsing LISP eids */
15562 typedef CLIB_PACKED(struct{
15563   u8 addr[16];   /**< eid address */
15564   u32 len;       /**< prefix length if IP */
15565   u8 type;      /**< type of eid */
15566 }) lisp_eid_vat_t;
15567 /* *INDENT-ON* */
15568
15569 static uword
15570 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15571 {
15572   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15573
15574   clib_memset (a, 0, sizeof (a[0]));
15575
15576   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15577     {
15578       a->type = 0;              /* ipv4 type */
15579     }
15580   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15581     {
15582       a->type = 1;              /* ipv6 type */
15583     }
15584   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15585     {
15586       a->type = 2;              /* mac type */
15587     }
15588   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15589     {
15590       a->type = 3;              /* NSH type */
15591       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15592       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15593     }
15594   else
15595     {
15596       return 0;
15597     }
15598
15599   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15600     {
15601       return 0;
15602     }
15603
15604   return 1;
15605 }
15606
15607 static int
15608 lisp_eid_size_vat (u8 type)
15609 {
15610   switch (type)
15611     {
15612     case 0:
15613       return 4;
15614     case 1:
15615       return 16;
15616     case 2:
15617       return 6;
15618     case 3:
15619       return 5;
15620     }
15621   return 0;
15622 }
15623
15624 static void
15625 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15626 {
15627   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15628 }
15629
15630 static int
15631 api_one_add_del_locator_set (vat_main_t * vam)
15632 {
15633   unformat_input_t *input = vam->input;
15634   vl_api_one_add_del_locator_set_t *mp;
15635   u8 is_add = 1;
15636   u8 *locator_set_name = NULL;
15637   u8 locator_set_name_set = 0;
15638   vl_api_local_locator_t locator, *locators = 0;
15639   u32 sw_if_index, priority, weight;
15640   u32 data_len = 0;
15641
15642   int ret;
15643   /* Parse args required to build the message */
15644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15645     {
15646       if (unformat (input, "del"))
15647         {
15648           is_add = 0;
15649         }
15650       else if (unformat (input, "locator-set %s", &locator_set_name))
15651         {
15652           locator_set_name_set = 1;
15653         }
15654       else if (unformat (input, "sw_if_index %u p %u w %u",
15655                          &sw_if_index, &priority, &weight))
15656         {
15657           locator.sw_if_index = htonl (sw_if_index);
15658           locator.priority = priority;
15659           locator.weight = weight;
15660           vec_add1 (locators, locator);
15661         }
15662       else
15663         if (unformat
15664             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15665              &sw_if_index, &priority, &weight))
15666         {
15667           locator.sw_if_index = htonl (sw_if_index);
15668           locator.priority = priority;
15669           locator.weight = weight;
15670           vec_add1 (locators, locator);
15671         }
15672       else
15673         break;
15674     }
15675
15676   if (locator_set_name_set == 0)
15677     {
15678       errmsg ("missing locator-set name");
15679       vec_free (locators);
15680       return -99;
15681     }
15682
15683   if (vec_len (locator_set_name) > 64)
15684     {
15685       errmsg ("locator-set name too long");
15686       vec_free (locator_set_name);
15687       vec_free (locators);
15688       return -99;
15689     }
15690   vec_add1 (locator_set_name, 0);
15691
15692   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15693
15694   /* Construct the API message */
15695   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15696
15697   mp->is_add = is_add;
15698   clib_memcpy (mp->locator_set_name, locator_set_name,
15699                vec_len (locator_set_name));
15700   vec_free (locator_set_name);
15701
15702   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15703   if (locators)
15704     clib_memcpy (mp->locators, locators, data_len);
15705   vec_free (locators);
15706
15707   /* send it... */
15708   S (mp);
15709
15710   /* Wait for a reply... */
15711   W (ret);
15712   return ret;
15713 }
15714
15715 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15716
15717 static int
15718 api_one_add_del_locator (vat_main_t * vam)
15719 {
15720   unformat_input_t *input = vam->input;
15721   vl_api_one_add_del_locator_t *mp;
15722   u32 tmp_if_index = ~0;
15723   u32 sw_if_index = ~0;
15724   u8 sw_if_index_set = 0;
15725   u8 sw_if_index_if_name_set = 0;
15726   u32 priority = ~0;
15727   u8 priority_set = 0;
15728   u32 weight = ~0;
15729   u8 weight_set = 0;
15730   u8 is_add = 1;
15731   u8 *locator_set_name = NULL;
15732   u8 locator_set_name_set = 0;
15733   int ret;
15734
15735   /* Parse args required to build the message */
15736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15737     {
15738       if (unformat (input, "del"))
15739         {
15740           is_add = 0;
15741         }
15742       else if (unformat (input, "locator-set %s", &locator_set_name))
15743         {
15744           locator_set_name_set = 1;
15745         }
15746       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15747                          &tmp_if_index))
15748         {
15749           sw_if_index_if_name_set = 1;
15750           sw_if_index = tmp_if_index;
15751         }
15752       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15753         {
15754           sw_if_index_set = 1;
15755           sw_if_index = tmp_if_index;
15756         }
15757       else if (unformat (input, "p %d", &priority))
15758         {
15759           priority_set = 1;
15760         }
15761       else if (unformat (input, "w %d", &weight))
15762         {
15763           weight_set = 1;
15764         }
15765       else
15766         break;
15767     }
15768
15769   if (locator_set_name_set == 0)
15770     {
15771       errmsg ("missing locator-set name");
15772       return -99;
15773     }
15774
15775   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15776     {
15777       errmsg ("missing sw_if_index");
15778       vec_free (locator_set_name);
15779       return -99;
15780     }
15781
15782   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15783     {
15784       errmsg ("cannot use both params interface name and sw_if_index");
15785       vec_free (locator_set_name);
15786       return -99;
15787     }
15788
15789   if (priority_set == 0)
15790     {
15791       errmsg ("missing locator-set priority");
15792       vec_free (locator_set_name);
15793       return -99;
15794     }
15795
15796   if (weight_set == 0)
15797     {
15798       errmsg ("missing locator-set weight");
15799       vec_free (locator_set_name);
15800       return -99;
15801     }
15802
15803   if (vec_len (locator_set_name) > 64)
15804     {
15805       errmsg ("locator-set name too long");
15806       vec_free (locator_set_name);
15807       return -99;
15808     }
15809   vec_add1 (locator_set_name, 0);
15810
15811   /* Construct the API message */
15812   M (ONE_ADD_DEL_LOCATOR, mp);
15813
15814   mp->is_add = is_add;
15815   mp->sw_if_index = ntohl (sw_if_index);
15816   mp->priority = priority;
15817   mp->weight = weight;
15818   clib_memcpy (mp->locator_set_name, locator_set_name,
15819                vec_len (locator_set_name));
15820   vec_free (locator_set_name);
15821
15822   /* send it... */
15823   S (mp);
15824
15825   /* Wait for a reply... */
15826   W (ret);
15827   return ret;
15828 }
15829
15830 #define api_lisp_add_del_locator api_one_add_del_locator
15831
15832 uword
15833 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15834 {
15835   u32 *key_id = va_arg (*args, u32 *);
15836   u8 *s = 0;
15837
15838   if (unformat (input, "%s", &s))
15839     {
15840       if (!strcmp ((char *) s, "sha1"))
15841         key_id[0] = HMAC_SHA_1_96;
15842       else if (!strcmp ((char *) s, "sha256"))
15843         key_id[0] = HMAC_SHA_256_128;
15844       else
15845         {
15846           clib_warning ("invalid key_id: '%s'", s);
15847           key_id[0] = HMAC_NO_KEY;
15848         }
15849     }
15850   else
15851     return 0;
15852
15853   vec_free (s);
15854   return 1;
15855 }
15856
15857 static int
15858 api_one_add_del_local_eid (vat_main_t * vam)
15859 {
15860   unformat_input_t *input = vam->input;
15861   vl_api_one_add_del_local_eid_t *mp;
15862   u8 is_add = 1;
15863   u8 eid_set = 0;
15864   lisp_eid_vat_t _eid, *eid = &_eid;
15865   u8 *locator_set_name = 0;
15866   u8 locator_set_name_set = 0;
15867   u32 vni = 0;
15868   u16 key_id = 0;
15869   u8 *key = 0;
15870   int ret;
15871
15872   /* Parse args required to build the message */
15873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15874     {
15875       if (unformat (input, "del"))
15876         {
15877           is_add = 0;
15878         }
15879       else if (unformat (input, "vni %d", &vni))
15880         {
15881           ;
15882         }
15883       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15884         {
15885           eid_set = 1;
15886         }
15887       else if (unformat (input, "locator-set %s", &locator_set_name))
15888         {
15889           locator_set_name_set = 1;
15890         }
15891       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15892         ;
15893       else if (unformat (input, "secret-key %_%v%_", &key))
15894         ;
15895       else
15896         break;
15897     }
15898
15899   if (locator_set_name_set == 0)
15900     {
15901       errmsg ("missing locator-set name");
15902       return -99;
15903     }
15904
15905   if (0 == eid_set)
15906     {
15907       errmsg ("EID address not set!");
15908       vec_free (locator_set_name);
15909       return -99;
15910     }
15911
15912   if (key && (0 == key_id))
15913     {
15914       errmsg ("invalid key_id!");
15915       return -99;
15916     }
15917
15918   if (vec_len (key) > 64)
15919     {
15920       errmsg ("key too long");
15921       vec_free (key);
15922       return -99;
15923     }
15924
15925   if (vec_len (locator_set_name) > 64)
15926     {
15927       errmsg ("locator-set name too long");
15928       vec_free (locator_set_name);
15929       return -99;
15930     }
15931   vec_add1 (locator_set_name, 0);
15932
15933   /* Construct the API message */
15934   M (ONE_ADD_DEL_LOCAL_EID, mp);
15935
15936   mp->is_add = is_add;
15937   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15938   mp->eid_type = eid->type;
15939   mp->prefix_len = eid->len;
15940   mp->vni = clib_host_to_net_u32 (vni);
15941   mp->key_id = clib_host_to_net_u16 (key_id);
15942   clib_memcpy (mp->locator_set_name, locator_set_name,
15943                vec_len (locator_set_name));
15944   clib_memcpy (mp->key, key, vec_len (key));
15945
15946   vec_free (locator_set_name);
15947   vec_free (key);
15948
15949   /* send it... */
15950   S (mp);
15951
15952   /* Wait for a reply... */
15953   W (ret);
15954   return ret;
15955 }
15956
15957 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15958
15959 static int
15960 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15961 {
15962   u32 dp_table = 0, vni = 0;;
15963   unformat_input_t *input = vam->input;
15964   vl_api_gpe_add_del_fwd_entry_t *mp;
15965   u8 is_add = 1;
15966   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15967   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15968   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15969   u32 action = ~0, w;
15970   ip4_address_t rmt_rloc4, lcl_rloc4;
15971   ip6_address_t rmt_rloc6, lcl_rloc6;
15972   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15973   int ret;
15974
15975   clib_memset (&rloc, 0, sizeof (rloc));
15976
15977   /* Parse args required to build the message */
15978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15979     {
15980       if (unformat (input, "del"))
15981         is_add = 0;
15982       else if (unformat (input, "add"))
15983         is_add = 1;
15984       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15985         {
15986           rmt_eid_set = 1;
15987         }
15988       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15989         {
15990           lcl_eid_set = 1;
15991         }
15992       else if (unformat (input, "vrf %d", &dp_table))
15993         ;
15994       else if (unformat (input, "bd %d", &dp_table))
15995         ;
15996       else if (unformat (input, "vni %d", &vni))
15997         ;
15998       else if (unformat (input, "w %d", &w))
15999         {
16000           if (!curr_rloc)
16001             {
16002               errmsg ("No RLOC configured for setting priority/weight!");
16003               return -99;
16004             }
16005           curr_rloc->weight = w;
16006         }
16007       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16008                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16009         {
16010           rloc.is_ip4 = 1;
16011
16012           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16013           rloc.weight = 0;
16014           vec_add1 (lcl_locs, rloc);
16015
16016           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16017           vec_add1 (rmt_locs, rloc);
16018           /* weight saved in rmt loc */
16019           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16020         }
16021       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16022                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16023         {
16024           rloc.is_ip4 = 0;
16025           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16026           rloc.weight = 0;
16027           vec_add1 (lcl_locs, rloc);
16028
16029           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16030           vec_add1 (rmt_locs, rloc);
16031           /* weight saved in rmt loc */
16032           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16033         }
16034       else if (unformat (input, "action %d", &action))
16035         {
16036           ;
16037         }
16038       else
16039         {
16040           clib_warning ("parse error '%U'", format_unformat_error, input);
16041           return -99;
16042         }
16043     }
16044
16045   if (!rmt_eid_set)
16046     {
16047       errmsg ("remote eid addresses not set");
16048       return -99;
16049     }
16050
16051   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16052     {
16053       errmsg ("eid types don't match");
16054       return -99;
16055     }
16056
16057   if (0 == rmt_locs && (u32) ~ 0 == action)
16058     {
16059       errmsg ("action not set for negative mapping");
16060       return -99;
16061     }
16062
16063   /* Construct the API message */
16064   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16065       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16066
16067   mp->is_add = is_add;
16068   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16069   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16070   mp->eid_type = rmt_eid->type;
16071   mp->dp_table = clib_host_to_net_u32 (dp_table);
16072   mp->vni = clib_host_to_net_u32 (vni);
16073   mp->rmt_len = rmt_eid->len;
16074   mp->lcl_len = lcl_eid->len;
16075   mp->action = action;
16076
16077   if (0 != rmt_locs && 0 != lcl_locs)
16078     {
16079       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16080       clib_memcpy (mp->locs, lcl_locs,
16081                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16082
16083       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16084       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16085                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16086     }
16087   vec_free (lcl_locs);
16088   vec_free (rmt_locs);
16089
16090   /* send it... */
16091   S (mp);
16092
16093   /* Wait for a reply... */
16094   W (ret);
16095   return ret;
16096 }
16097
16098 static int
16099 api_one_add_del_map_server (vat_main_t * vam)
16100 {
16101   unformat_input_t *input = vam->input;
16102   vl_api_one_add_del_map_server_t *mp;
16103   u8 is_add = 1;
16104   u8 ipv4_set = 0;
16105   u8 ipv6_set = 0;
16106   ip4_address_t ipv4;
16107   ip6_address_t ipv6;
16108   int ret;
16109
16110   /* Parse args required to build the message */
16111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16112     {
16113       if (unformat (input, "del"))
16114         {
16115           is_add = 0;
16116         }
16117       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16118         {
16119           ipv4_set = 1;
16120         }
16121       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16122         {
16123           ipv6_set = 1;
16124         }
16125       else
16126         break;
16127     }
16128
16129   if (ipv4_set && ipv6_set)
16130     {
16131       errmsg ("both eid v4 and v6 addresses set");
16132       return -99;
16133     }
16134
16135   if (!ipv4_set && !ipv6_set)
16136     {
16137       errmsg ("eid addresses not set");
16138       return -99;
16139     }
16140
16141   /* Construct the API message */
16142   M (ONE_ADD_DEL_MAP_SERVER, mp);
16143
16144   mp->is_add = is_add;
16145   if (ipv6_set)
16146     {
16147       mp->is_ipv6 = 1;
16148       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16149     }
16150   else
16151     {
16152       mp->is_ipv6 = 0;
16153       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16154     }
16155
16156   /* send it... */
16157   S (mp);
16158
16159   /* Wait for a reply... */
16160   W (ret);
16161   return ret;
16162 }
16163
16164 #define api_lisp_add_del_map_server api_one_add_del_map_server
16165
16166 static int
16167 api_one_add_del_map_resolver (vat_main_t * vam)
16168 {
16169   unformat_input_t *input = vam->input;
16170   vl_api_one_add_del_map_resolver_t *mp;
16171   u8 is_add = 1;
16172   u8 ipv4_set = 0;
16173   u8 ipv6_set = 0;
16174   ip4_address_t ipv4;
16175   ip6_address_t ipv6;
16176   int ret;
16177
16178   /* Parse args required to build the message */
16179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16180     {
16181       if (unformat (input, "del"))
16182         {
16183           is_add = 0;
16184         }
16185       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16186         {
16187           ipv4_set = 1;
16188         }
16189       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16190         {
16191           ipv6_set = 1;
16192         }
16193       else
16194         break;
16195     }
16196
16197   if (ipv4_set && ipv6_set)
16198     {
16199       errmsg ("both eid v4 and v6 addresses set");
16200       return -99;
16201     }
16202
16203   if (!ipv4_set && !ipv6_set)
16204     {
16205       errmsg ("eid addresses not set");
16206       return -99;
16207     }
16208
16209   /* Construct the API message */
16210   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16211
16212   mp->is_add = is_add;
16213   if (ipv6_set)
16214     {
16215       mp->is_ipv6 = 1;
16216       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16217     }
16218   else
16219     {
16220       mp->is_ipv6 = 0;
16221       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16222     }
16223
16224   /* send it... */
16225   S (mp);
16226
16227   /* Wait for a reply... */
16228   W (ret);
16229   return ret;
16230 }
16231
16232 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16233
16234 static int
16235 api_lisp_gpe_enable_disable (vat_main_t * vam)
16236 {
16237   unformat_input_t *input = vam->input;
16238   vl_api_gpe_enable_disable_t *mp;
16239   u8 is_set = 0;
16240   u8 is_en = 1;
16241   int ret;
16242
16243   /* Parse args required to build the message */
16244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (input, "enable"))
16247         {
16248           is_set = 1;
16249           is_en = 1;
16250         }
16251       else if (unformat (input, "disable"))
16252         {
16253           is_set = 1;
16254           is_en = 0;
16255         }
16256       else
16257         break;
16258     }
16259
16260   if (is_set == 0)
16261     {
16262       errmsg ("Value not set");
16263       return -99;
16264     }
16265
16266   /* Construct the API message */
16267   M (GPE_ENABLE_DISABLE, mp);
16268
16269   mp->is_en = is_en;
16270
16271   /* send it... */
16272   S (mp);
16273
16274   /* Wait for a reply... */
16275   W (ret);
16276   return ret;
16277 }
16278
16279 static int
16280 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16281 {
16282   unformat_input_t *input = vam->input;
16283   vl_api_one_rloc_probe_enable_disable_t *mp;
16284   u8 is_set = 0;
16285   u8 is_en = 0;
16286   int ret;
16287
16288   /* Parse args required to build the message */
16289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16290     {
16291       if (unformat (input, "enable"))
16292         {
16293           is_set = 1;
16294           is_en = 1;
16295         }
16296       else if (unformat (input, "disable"))
16297         is_set = 1;
16298       else
16299         break;
16300     }
16301
16302   if (!is_set)
16303     {
16304       errmsg ("Value not set");
16305       return -99;
16306     }
16307
16308   /* Construct the API message */
16309   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16310
16311   mp->is_enabled = is_en;
16312
16313   /* send it... */
16314   S (mp);
16315
16316   /* Wait for a reply... */
16317   W (ret);
16318   return ret;
16319 }
16320
16321 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16322
16323 static int
16324 api_one_map_register_enable_disable (vat_main_t * vam)
16325 {
16326   unformat_input_t *input = vam->input;
16327   vl_api_one_map_register_enable_disable_t *mp;
16328   u8 is_set = 0;
16329   u8 is_en = 0;
16330   int ret;
16331
16332   /* Parse args required to build the message */
16333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16334     {
16335       if (unformat (input, "enable"))
16336         {
16337           is_set = 1;
16338           is_en = 1;
16339         }
16340       else if (unformat (input, "disable"))
16341         is_set = 1;
16342       else
16343         break;
16344     }
16345
16346   if (!is_set)
16347     {
16348       errmsg ("Value not set");
16349       return -99;
16350     }
16351
16352   /* Construct the API message */
16353   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16354
16355   mp->is_enabled = is_en;
16356
16357   /* send it... */
16358   S (mp);
16359
16360   /* Wait for a reply... */
16361   W (ret);
16362   return ret;
16363 }
16364
16365 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16366
16367 static int
16368 api_one_enable_disable (vat_main_t * vam)
16369 {
16370   unformat_input_t *input = vam->input;
16371   vl_api_one_enable_disable_t *mp;
16372   u8 is_set = 0;
16373   u8 is_en = 0;
16374   int ret;
16375
16376   /* Parse args required to build the message */
16377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (input, "enable"))
16380         {
16381           is_set = 1;
16382           is_en = 1;
16383         }
16384       else if (unformat (input, "disable"))
16385         {
16386           is_set = 1;
16387         }
16388       else
16389         break;
16390     }
16391
16392   if (!is_set)
16393     {
16394       errmsg ("Value not set");
16395       return -99;
16396     }
16397
16398   /* Construct the API message */
16399   M (ONE_ENABLE_DISABLE, mp);
16400
16401   mp->is_en = is_en;
16402
16403   /* send it... */
16404   S (mp);
16405
16406   /* Wait for a reply... */
16407   W (ret);
16408   return ret;
16409 }
16410
16411 #define api_lisp_enable_disable api_one_enable_disable
16412
16413 static int
16414 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16415 {
16416   unformat_input_t *input = vam->input;
16417   vl_api_one_enable_disable_xtr_mode_t *mp;
16418   u8 is_set = 0;
16419   u8 is_en = 0;
16420   int ret;
16421
16422   /* Parse args required to build the message */
16423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16424     {
16425       if (unformat (input, "enable"))
16426         {
16427           is_set = 1;
16428           is_en = 1;
16429         }
16430       else if (unformat (input, "disable"))
16431         {
16432           is_set = 1;
16433         }
16434       else
16435         break;
16436     }
16437
16438   if (!is_set)
16439     {
16440       errmsg ("Value not set");
16441       return -99;
16442     }
16443
16444   /* Construct the API message */
16445   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16446
16447   mp->is_en = is_en;
16448
16449   /* send it... */
16450   S (mp);
16451
16452   /* Wait for a reply... */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 static int
16458 api_one_show_xtr_mode (vat_main_t * vam)
16459 {
16460   vl_api_one_show_xtr_mode_t *mp;
16461   int ret;
16462
16463   /* Construct the API message */
16464   M (ONE_SHOW_XTR_MODE, mp);
16465
16466   /* send it... */
16467   S (mp);
16468
16469   /* Wait for a reply... */
16470   W (ret);
16471   return ret;
16472 }
16473
16474 static int
16475 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16476 {
16477   unformat_input_t *input = vam->input;
16478   vl_api_one_enable_disable_pitr_mode_t *mp;
16479   u8 is_set = 0;
16480   u8 is_en = 0;
16481   int ret;
16482
16483   /* Parse args required to build the message */
16484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16485     {
16486       if (unformat (input, "enable"))
16487         {
16488           is_set = 1;
16489           is_en = 1;
16490         }
16491       else if (unformat (input, "disable"))
16492         {
16493           is_set = 1;
16494         }
16495       else
16496         break;
16497     }
16498
16499   if (!is_set)
16500     {
16501       errmsg ("Value not set");
16502       return -99;
16503     }
16504
16505   /* Construct the API message */
16506   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16507
16508   mp->is_en = is_en;
16509
16510   /* send it... */
16511   S (mp);
16512
16513   /* Wait for a reply... */
16514   W (ret);
16515   return ret;
16516 }
16517
16518 static int
16519 api_one_show_pitr_mode (vat_main_t * vam)
16520 {
16521   vl_api_one_show_pitr_mode_t *mp;
16522   int ret;
16523
16524   /* Construct the API message */
16525   M (ONE_SHOW_PITR_MODE, mp);
16526
16527   /* send it... */
16528   S (mp);
16529
16530   /* Wait for a reply... */
16531   W (ret);
16532   return ret;
16533 }
16534
16535 static int
16536 api_one_enable_disable_petr_mode (vat_main_t * vam)
16537 {
16538   unformat_input_t *input = vam->input;
16539   vl_api_one_enable_disable_petr_mode_t *mp;
16540   u8 is_set = 0;
16541   u8 is_en = 0;
16542   int ret;
16543
16544   /* Parse args required to build the message */
16545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16546     {
16547       if (unformat (input, "enable"))
16548         {
16549           is_set = 1;
16550           is_en = 1;
16551         }
16552       else if (unformat (input, "disable"))
16553         {
16554           is_set = 1;
16555         }
16556       else
16557         break;
16558     }
16559
16560   if (!is_set)
16561     {
16562       errmsg ("Value not set");
16563       return -99;
16564     }
16565
16566   /* Construct the API message */
16567   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16568
16569   mp->is_en = is_en;
16570
16571   /* send it... */
16572   S (mp);
16573
16574   /* Wait for a reply... */
16575   W (ret);
16576   return ret;
16577 }
16578
16579 static int
16580 api_one_show_petr_mode (vat_main_t * vam)
16581 {
16582   vl_api_one_show_petr_mode_t *mp;
16583   int ret;
16584
16585   /* Construct the API message */
16586   M (ONE_SHOW_PETR_MODE, mp);
16587
16588   /* send it... */
16589   S (mp);
16590
16591   /* Wait for a reply... */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 static int
16597 api_show_one_map_register_state (vat_main_t * vam)
16598 {
16599   vl_api_show_one_map_register_state_t *mp;
16600   int ret;
16601
16602   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16603
16604   /* send */
16605   S (mp);
16606
16607   /* wait for reply */
16608   W (ret);
16609   return ret;
16610 }
16611
16612 #define api_show_lisp_map_register_state api_show_one_map_register_state
16613
16614 static int
16615 api_show_one_rloc_probe_state (vat_main_t * vam)
16616 {
16617   vl_api_show_one_rloc_probe_state_t *mp;
16618   int ret;
16619
16620   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16621
16622   /* send */
16623   S (mp);
16624
16625   /* wait for reply */
16626   W (ret);
16627   return ret;
16628 }
16629
16630 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16631
16632 static int
16633 api_one_add_del_ndp_entry (vat_main_t * vam)
16634 {
16635   vl_api_one_add_del_ndp_entry_t *mp;
16636   unformat_input_t *input = vam->input;
16637   u8 is_add = 1;
16638   u8 mac_set = 0;
16639   u8 bd_set = 0;
16640   u8 ip_set = 0;
16641   u8 mac[6] = { 0, };
16642   u8 ip6[16] = { 0, };
16643   u32 bd = ~0;
16644   int ret;
16645
16646   /* Parse args required to build the message */
16647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16648     {
16649       if (unformat (input, "del"))
16650         is_add = 0;
16651       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16652         mac_set = 1;
16653       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16654         ip_set = 1;
16655       else if (unformat (input, "bd %d", &bd))
16656         bd_set = 1;
16657       else
16658         {
16659           errmsg ("parse error '%U'", format_unformat_error, input);
16660           return -99;
16661         }
16662     }
16663
16664   if (!bd_set || !ip_set || (!mac_set && is_add))
16665     {
16666       errmsg ("Missing BD, IP or MAC!");
16667       return -99;
16668     }
16669
16670   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16671   mp->is_add = is_add;
16672   clib_memcpy (mp->mac, mac, 6);
16673   mp->bd = clib_host_to_net_u32 (bd);
16674   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16675
16676   /* send */
16677   S (mp);
16678
16679   /* wait for reply */
16680   W (ret);
16681   return ret;
16682 }
16683
16684 static int
16685 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16686 {
16687   vl_api_one_add_del_l2_arp_entry_t *mp;
16688   unformat_input_t *input = vam->input;
16689   u8 is_add = 1;
16690   u8 mac_set = 0;
16691   u8 bd_set = 0;
16692   u8 ip_set = 0;
16693   u8 mac[6] = { 0, };
16694   u32 ip4 = 0, bd = ~0;
16695   int ret;
16696
16697   /* Parse args required to build the message */
16698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16699     {
16700       if (unformat (input, "del"))
16701         is_add = 0;
16702       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16703         mac_set = 1;
16704       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16705         ip_set = 1;
16706       else if (unformat (input, "bd %d", &bd))
16707         bd_set = 1;
16708       else
16709         {
16710           errmsg ("parse error '%U'", format_unformat_error, input);
16711           return -99;
16712         }
16713     }
16714
16715   if (!bd_set || !ip_set || (!mac_set && is_add))
16716     {
16717       errmsg ("Missing BD, IP or MAC!");
16718       return -99;
16719     }
16720
16721   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16722   mp->is_add = is_add;
16723   clib_memcpy (mp->mac, mac, 6);
16724   mp->bd = clib_host_to_net_u32 (bd);
16725   mp->ip4 = ip4;
16726
16727   /* send */
16728   S (mp);
16729
16730   /* wait for reply */
16731   W (ret);
16732   return ret;
16733 }
16734
16735 static int
16736 api_one_ndp_bd_get (vat_main_t * vam)
16737 {
16738   vl_api_one_ndp_bd_get_t *mp;
16739   int ret;
16740
16741   M (ONE_NDP_BD_GET, mp);
16742
16743   /* send */
16744   S (mp);
16745
16746   /* wait for reply */
16747   W (ret);
16748   return ret;
16749 }
16750
16751 static int
16752 api_one_ndp_entries_get (vat_main_t * vam)
16753 {
16754   vl_api_one_ndp_entries_get_t *mp;
16755   unformat_input_t *input = vam->input;
16756   u8 bd_set = 0;
16757   u32 bd = ~0;
16758   int ret;
16759
16760   /* Parse args required to build the message */
16761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16762     {
16763       if (unformat (input, "bd %d", &bd))
16764         bd_set = 1;
16765       else
16766         {
16767           errmsg ("parse error '%U'", format_unformat_error, input);
16768           return -99;
16769         }
16770     }
16771
16772   if (!bd_set)
16773     {
16774       errmsg ("Expected bridge domain!");
16775       return -99;
16776     }
16777
16778   M (ONE_NDP_ENTRIES_GET, mp);
16779   mp->bd = clib_host_to_net_u32 (bd);
16780
16781   /* send */
16782   S (mp);
16783
16784   /* wait for reply */
16785   W (ret);
16786   return ret;
16787 }
16788
16789 static int
16790 api_one_l2_arp_bd_get (vat_main_t * vam)
16791 {
16792   vl_api_one_l2_arp_bd_get_t *mp;
16793   int ret;
16794
16795   M (ONE_L2_ARP_BD_GET, mp);
16796
16797   /* send */
16798   S (mp);
16799
16800   /* wait for reply */
16801   W (ret);
16802   return ret;
16803 }
16804
16805 static int
16806 api_one_l2_arp_entries_get (vat_main_t * vam)
16807 {
16808   vl_api_one_l2_arp_entries_get_t *mp;
16809   unformat_input_t *input = vam->input;
16810   u8 bd_set = 0;
16811   u32 bd = ~0;
16812   int ret;
16813
16814   /* Parse args required to build the message */
16815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (input, "bd %d", &bd))
16818         bd_set = 1;
16819       else
16820         {
16821           errmsg ("parse error '%U'", format_unformat_error, input);
16822           return -99;
16823         }
16824     }
16825
16826   if (!bd_set)
16827     {
16828       errmsg ("Expected bridge domain!");
16829       return -99;
16830     }
16831
16832   M (ONE_L2_ARP_ENTRIES_GET, mp);
16833   mp->bd = clib_host_to_net_u32 (bd);
16834
16835   /* send */
16836   S (mp);
16837
16838   /* wait for reply */
16839   W (ret);
16840   return ret;
16841 }
16842
16843 static int
16844 api_one_stats_enable_disable (vat_main_t * vam)
16845 {
16846   vl_api_one_stats_enable_disable_t *mp;
16847   unformat_input_t *input = vam->input;
16848   u8 is_set = 0;
16849   u8 is_en = 0;
16850   int ret;
16851
16852   /* Parse args required to build the message */
16853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16854     {
16855       if (unformat (input, "enable"))
16856         {
16857           is_set = 1;
16858           is_en = 1;
16859         }
16860       else if (unformat (input, "disable"))
16861         {
16862           is_set = 1;
16863         }
16864       else
16865         break;
16866     }
16867
16868   if (!is_set)
16869     {
16870       errmsg ("Value not set");
16871       return -99;
16872     }
16873
16874   M (ONE_STATS_ENABLE_DISABLE, mp);
16875   mp->is_en = is_en;
16876
16877   /* send */
16878   S (mp);
16879
16880   /* wait for reply */
16881   W (ret);
16882   return ret;
16883 }
16884
16885 static int
16886 api_show_one_stats_enable_disable (vat_main_t * vam)
16887 {
16888   vl_api_show_one_stats_enable_disable_t *mp;
16889   int ret;
16890
16891   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16892
16893   /* send */
16894   S (mp);
16895
16896   /* wait for reply */
16897   W (ret);
16898   return ret;
16899 }
16900
16901 static int
16902 api_show_one_map_request_mode (vat_main_t * vam)
16903 {
16904   vl_api_show_one_map_request_mode_t *mp;
16905   int ret;
16906
16907   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16908
16909   /* send */
16910   S (mp);
16911
16912   /* wait for reply */
16913   W (ret);
16914   return ret;
16915 }
16916
16917 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16918
16919 static int
16920 api_one_map_request_mode (vat_main_t * vam)
16921 {
16922   unformat_input_t *input = vam->input;
16923   vl_api_one_map_request_mode_t *mp;
16924   u8 mode = 0;
16925   int ret;
16926
16927   /* Parse args required to build the message */
16928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16929     {
16930       if (unformat (input, "dst-only"))
16931         mode = 0;
16932       else if (unformat (input, "src-dst"))
16933         mode = 1;
16934       else
16935         {
16936           errmsg ("parse error '%U'", format_unformat_error, input);
16937           return -99;
16938         }
16939     }
16940
16941   M (ONE_MAP_REQUEST_MODE, mp);
16942
16943   mp->mode = mode;
16944
16945   /* send */
16946   S (mp);
16947
16948   /* wait for reply */
16949   W (ret);
16950   return ret;
16951 }
16952
16953 #define api_lisp_map_request_mode api_one_map_request_mode
16954
16955 /**
16956  * Enable/disable ONE proxy ITR.
16957  *
16958  * @param vam vpp API test context
16959  * @return return code
16960  */
16961 static int
16962 api_one_pitr_set_locator_set (vat_main_t * vam)
16963 {
16964   u8 ls_name_set = 0;
16965   unformat_input_t *input = vam->input;
16966   vl_api_one_pitr_set_locator_set_t *mp;
16967   u8 is_add = 1;
16968   u8 *ls_name = 0;
16969   int ret;
16970
16971   /* Parse args required to build the message */
16972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16973     {
16974       if (unformat (input, "del"))
16975         is_add = 0;
16976       else if (unformat (input, "locator-set %s", &ls_name))
16977         ls_name_set = 1;
16978       else
16979         {
16980           errmsg ("parse error '%U'", format_unformat_error, input);
16981           return -99;
16982         }
16983     }
16984
16985   if (!ls_name_set)
16986     {
16987       errmsg ("locator-set name not set!");
16988       return -99;
16989     }
16990
16991   M (ONE_PITR_SET_LOCATOR_SET, mp);
16992
16993   mp->is_add = is_add;
16994   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16995   vec_free (ls_name);
16996
16997   /* send */
16998   S (mp);
16999
17000   /* wait for reply */
17001   W (ret);
17002   return ret;
17003 }
17004
17005 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17006
17007 static int
17008 api_one_nsh_set_locator_set (vat_main_t * vam)
17009 {
17010   u8 ls_name_set = 0;
17011   unformat_input_t *input = vam->input;
17012   vl_api_one_nsh_set_locator_set_t *mp;
17013   u8 is_add = 1;
17014   u8 *ls_name = 0;
17015   int ret;
17016
17017   /* Parse args required to build the message */
17018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17019     {
17020       if (unformat (input, "del"))
17021         is_add = 0;
17022       else if (unformat (input, "ls %s", &ls_name))
17023         ls_name_set = 1;
17024       else
17025         {
17026           errmsg ("parse error '%U'", format_unformat_error, input);
17027           return -99;
17028         }
17029     }
17030
17031   if (!ls_name_set && is_add)
17032     {
17033       errmsg ("locator-set name not set!");
17034       return -99;
17035     }
17036
17037   M (ONE_NSH_SET_LOCATOR_SET, mp);
17038
17039   mp->is_add = is_add;
17040   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17041   vec_free (ls_name);
17042
17043   /* send */
17044   S (mp);
17045
17046   /* wait for reply */
17047   W (ret);
17048   return ret;
17049 }
17050
17051 static int
17052 api_show_one_pitr (vat_main_t * vam)
17053 {
17054   vl_api_show_one_pitr_t *mp;
17055   int ret;
17056
17057   if (!vam->json_output)
17058     {
17059       print (vam->ofp, "%=20s", "lisp status:");
17060     }
17061
17062   M (SHOW_ONE_PITR, mp);
17063   /* send it... */
17064   S (mp);
17065
17066   /* Wait for a reply... */
17067   W (ret);
17068   return ret;
17069 }
17070
17071 #define api_show_lisp_pitr api_show_one_pitr
17072
17073 static int
17074 api_one_use_petr (vat_main_t * vam)
17075 {
17076   unformat_input_t *input = vam->input;
17077   vl_api_one_use_petr_t *mp;
17078   u8 is_add = 0;
17079   ip_address_t ip;
17080   int ret;
17081
17082   clib_memset (&ip, 0, sizeof (ip));
17083
17084   /* Parse args required to build the message */
17085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17086     {
17087       if (unformat (input, "disable"))
17088         is_add = 0;
17089       else
17090         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17091         {
17092           is_add = 1;
17093           ip_addr_version (&ip) = IP4;
17094         }
17095       else
17096         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17097         {
17098           is_add = 1;
17099           ip_addr_version (&ip) = IP6;
17100         }
17101       else
17102         {
17103           errmsg ("parse error '%U'", format_unformat_error, input);
17104           return -99;
17105         }
17106     }
17107
17108   M (ONE_USE_PETR, mp);
17109
17110   mp->is_add = is_add;
17111   if (is_add)
17112     {
17113       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17114       if (mp->is_ip4)
17115         clib_memcpy (mp->address, &ip, 4);
17116       else
17117         clib_memcpy (mp->address, &ip, 16);
17118     }
17119
17120   /* send */
17121   S (mp);
17122
17123   /* wait for reply */
17124   W (ret);
17125   return ret;
17126 }
17127
17128 #define api_lisp_use_petr api_one_use_petr
17129
17130 static int
17131 api_show_one_nsh_mapping (vat_main_t * vam)
17132 {
17133   vl_api_show_one_use_petr_t *mp;
17134   int ret;
17135
17136   if (!vam->json_output)
17137     {
17138       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17139     }
17140
17141   M (SHOW_ONE_NSH_MAPPING, mp);
17142   /* send it... */
17143   S (mp);
17144
17145   /* Wait for a reply... */
17146   W (ret);
17147   return ret;
17148 }
17149
17150 static int
17151 api_show_one_use_petr (vat_main_t * vam)
17152 {
17153   vl_api_show_one_use_petr_t *mp;
17154   int ret;
17155
17156   if (!vam->json_output)
17157     {
17158       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17159     }
17160
17161   M (SHOW_ONE_USE_PETR, mp);
17162   /* send it... */
17163   S (mp);
17164
17165   /* Wait for a reply... */
17166   W (ret);
17167   return ret;
17168 }
17169
17170 #define api_show_lisp_use_petr api_show_one_use_petr
17171
17172 /**
17173  * Add/delete mapping between vni and vrf
17174  */
17175 static int
17176 api_one_eid_table_add_del_map (vat_main_t * vam)
17177 {
17178   unformat_input_t *input = vam->input;
17179   vl_api_one_eid_table_add_del_map_t *mp;
17180   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17181   u32 vni, vrf, bd_index;
17182   int ret;
17183
17184   /* Parse args required to build the message */
17185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17186     {
17187       if (unformat (input, "del"))
17188         is_add = 0;
17189       else if (unformat (input, "vrf %d", &vrf))
17190         vrf_set = 1;
17191       else if (unformat (input, "bd_index %d", &bd_index))
17192         bd_index_set = 1;
17193       else if (unformat (input, "vni %d", &vni))
17194         vni_set = 1;
17195       else
17196         break;
17197     }
17198
17199   if (!vni_set || (!vrf_set && !bd_index_set))
17200     {
17201       errmsg ("missing arguments!");
17202       return -99;
17203     }
17204
17205   if (vrf_set && bd_index_set)
17206     {
17207       errmsg ("error: both vrf and bd entered!");
17208       return -99;
17209     }
17210
17211   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17212
17213   mp->is_add = is_add;
17214   mp->vni = htonl (vni);
17215   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17216   mp->is_l2 = bd_index_set;
17217
17218   /* send */
17219   S (mp);
17220
17221   /* wait for reply */
17222   W (ret);
17223   return ret;
17224 }
17225
17226 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17227
17228 uword
17229 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17230 {
17231   u32 *action = va_arg (*args, u32 *);
17232   u8 *s = 0;
17233
17234   if (unformat (input, "%s", &s))
17235     {
17236       if (!strcmp ((char *) s, "no-action"))
17237         action[0] = 0;
17238       else if (!strcmp ((char *) s, "natively-forward"))
17239         action[0] = 1;
17240       else if (!strcmp ((char *) s, "send-map-request"))
17241         action[0] = 2;
17242       else if (!strcmp ((char *) s, "drop"))
17243         action[0] = 3;
17244       else
17245         {
17246           clib_warning ("invalid action: '%s'", s);
17247           action[0] = 3;
17248         }
17249     }
17250   else
17251     return 0;
17252
17253   vec_free (s);
17254   return 1;
17255 }
17256
17257 /**
17258  * Add/del remote mapping to/from ONE control plane
17259  *
17260  * @param vam vpp API test context
17261  * @return return code
17262  */
17263 static int
17264 api_one_add_del_remote_mapping (vat_main_t * vam)
17265 {
17266   unformat_input_t *input = vam->input;
17267   vl_api_one_add_del_remote_mapping_t *mp;
17268   u32 vni = 0;
17269   lisp_eid_vat_t _eid, *eid = &_eid;
17270   lisp_eid_vat_t _seid, *seid = &_seid;
17271   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17272   u32 action = ~0, p, w, data_len;
17273   ip4_address_t rloc4;
17274   ip6_address_t rloc6;
17275   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17276   int ret;
17277
17278   clib_memset (&rloc, 0, sizeof (rloc));
17279
17280   /* Parse args required to build the message */
17281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17282     {
17283       if (unformat (input, "del-all"))
17284         {
17285           del_all = 1;
17286         }
17287       else if (unformat (input, "del"))
17288         {
17289           is_add = 0;
17290         }
17291       else if (unformat (input, "add"))
17292         {
17293           is_add = 1;
17294         }
17295       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17296         {
17297           eid_set = 1;
17298         }
17299       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17300         {
17301           seid_set = 1;
17302         }
17303       else if (unformat (input, "vni %d", &vni))
17304         {
17305           ;
17306         }
17307       else if (unformat (input, "p %d w %d", &p, &w))
17308         {
17309           if (!curr_rloc)
17310             {
17311               errmsg ("No RLOC configured for setting priority/weight!");
17312               return -99;
17313             }
17314           curr_rloc->priority = p;
17315           curr_rloc->weight = w;
17316         }
17317       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17318         {
17319           rloc.is_ip4 = 1;
17320           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17321           vec_add1 (rlocs, rloc);
17322           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17323         }
17324       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17325         {
17326           rloc.is_ip4 = 0;
17327           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17328           vec_add1 (rlocs, rloc);
17329           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17330         }
17331       else if (unformat (input, "action %U",
17332                          unformat_negative_mapping_action, &action))
17333         {
17334           ;
17335         }
17336       else
17337         {
17338           clib_warning ("parse error '%U'", format_unformat_error, input);
17339           return -99;
17340         }
17341     }
17342
17343   if (0 == eid_set)
17344     {
17345       errmsg ("missing params!");
17346       return -99;
17347     }
17348
17349   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17350     {
17351       errmsg ("no action set for negative map-reply!");
17352       return -99;
17353     }
17354
17355   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17356
17357   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17358   mp->is_add = is_add;
17359   mp->vni = htonl (vni);
17360   mp->action = (u8) action;
17361   mp->is_src_dst = seid_set;
17362   mp->eid_len = eid->len;
17363   mp->seid_len = seid->len;
17364   mp->del_all = del_all;
17365   mp->eid_type = eid->type;
17366   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17367   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17368
17369   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17370   clib_memcpy (mp->rlocs, rlocs, data_len);
17371   vec_free (rlocs);
17372
17373   /* send it... */
17374   S (mp);
17375
17376   /* Wait for a reply... */
17377   W (ret);
17378   return ret;
17379 }
17380
17381 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17382
17383 /**
17384  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17385  * forwarding entries in data-plane accordingly.
17386  *
17387  * @param vam vpp API test context
17388  * @return return code
17389  */
17390 static int
17391 api_one_add_del_adjacency (vat_main_t * vam)
17392 {
17393   unformat_input_t *input = vam->input;
17394   vl_api_one_add_del_adjacency_t *mp;
17395   u32 vni = 0;
17396   ip4_address_t leid4, reid4;
17397   ip6_address_t leid6, reid6;
17398   u8 reid_mac[6] = { 0 };
17399   u8 leid_mac[6] = { 0 };
17400   u8 reid_type, leid_type;
17401   u32 leid_len = 0, reid_len = 0, len;
17402   u8 is_add = 1;
17403   int ret;
17404
17405   leid_type = reid_type = (u8) ~ 0;
17406
17407   /* Parse args required to build the message */
17408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17409     {
17410       if (unformat (input, "del"))
17411         {
17412           is_add = 0;
17413         }
17414       else if (unformat (input, "add"))
17415         {
17416           is_add = 1;
17417         }
17418       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17419                          &reid4, &len))
17420         {
17421           reid_type = 0;        /* ipv4 */
17422           reid_len = len;
17423         }
17424       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17425                          &reid6, &len))
17426         {
17427           reid_type = 1;        /* ipv6 */
17428           reid_len = len;
17429         }
17430       else if (unformat (input, "reid %U", unformat_ethernet_address,
17431                          reid_mac))
17432         {
17433           reid_type = 2;        /* mac */
17434         }
17435       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17436                          &leid4, &len))
17437         {
17438           leid_type = 0;        /* ipv4 */
17439           leid_len = len;
17440         }
17441       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17442                          &leid6, &len))
17443         {
17444           leid_type = 1;        /* ipv6 */
17445           leid_len = len;
17446         }
17447       else if (unformat (input, "leid %U", unformat_ethernet_address,
17448                          leid_mac))
17449         {
17450           leid_type = 2;        /* mac */
17451         }
17452       else if (unformat (input, "vni %d", &vni))
17453         {
17454           ;
17455         }
17456       else
17457         {
17458           errmsg ("parse error '%U'", format_unformat_error, input);
17459           return -99;
17460         }
17461     }
17462
17463   if ((u8) ~ 0 == reid_type)
17464     {
17465       errmsg ("missing params!");
17466       return -99;
17467     }
17468
17469   if (leid_type != reid_type)
17470     {
17471       errmsg ("remote and local EIDs are of different types!");
17472       return -99;
17473     }
17474
17475   M (ONE_ADD_DEL_ADJACENCY, mp);
17476   mp->is_add = is_add;
17477   mp->vni = htonl (vni);
17478   mp->leid_len = leid_len;
17479   mp->reid_len = reid_len;
17480   mp->eid_type = reid_type;
17481
17482   switch (mp->eid_type)
17483     {
17484     case 0:
17485       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17486       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17487       break;
17488     case 1:
17489       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17490       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17491       break;
17492     case 2:
17493       clib_memcpy (mp->leid, leid_mac, 6);
17494       clib_memcpy (mp->reid, reid_mac, 6);
17495       break;
17496     default:
17497       errmsg ("unknown EID type %d!", mp->eid_type);
17498       return 0;
17499     }
17500
17501   /* send it... */
17502   S (mp);
17503
17504   /* Wait for a reply... */
17505   W (ret);
17506   return ret;
17507 }
17508
17509 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17510
17511 uword
17512 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17513 {
17514   u32 *mode = va_arg (*args, u32 *);
17515
17516   if (unformat (input, "lisp"))
17517     *mode = 0;
17518   else if (unformat (input, "vxlan"))
17519     *mode = 1;
17520   else
17521     return 0;
17522
17523   return 1;
17524 }
17525
17526 static int
17527 api_gpe_get_encap_mode (vat_main_t * vam)
17528 {
17529   vl_api_gpe_get_encap_mode_t *mp;
17530   int ret;
17531
17532   /* Construct the API message */
17533   M (GPE_GET_ENCAP_MODE, mp);
17534
17535   /* send it... */
17536   S (mp);
17537
17538   /* Wait for a reply... */
17539   W (ret);
17540   return ret;
17541 }
17542
17543 static int
17544 api_gpe_set_encap_mode (vat_main_t * vam)
17545 {
17546   unformat_input_t *input = vam->input;
17547   vl_api_gpe_set_encap_mode_t *mp;
17548   int ret;
17549   u32 mode = 0;
17550
17551   /* Parse args required to build the message */
17552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17553     {
17554       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17555         ;
17556       else
17557         break;
17558     }
17559
17560   /* Construct the API message */
17561   M (GPE_SET_ENCAP_MODE, mp);
17562
17563   mp->mode = mode;
17564
17565   /* send it... */
17566   S (mp);
17567
17568   /* Wait for a reply... */
17569   W (ret);
17570   return ret;
17571 }
17572
17573 static int
17574 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17575 {
17576   unformat_input_t *input = vam->input;
17577   vl_api_gpe_add_del_iface_t *mp;
17578   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17579   u32 dp_table = 0, vni = 0;
17580   int ret;
17581
17582   /* Parse args required to build the message */
17583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17584     {
17585       if (unformat (input, "up"))
17586         {
17587           action_set = 1;
17588           is_add = 1;
17589         }
17590       else if (unformat (input, "down"))
17591         {
17592           action_set = 1;
17593           is_add = 0;
17594         }
17595       else if (unformat (input, "table_id %d", &dp_table))
17596         {
17597           dp_table_set = 1;
17598         }
17599       else if (unformat (input, "bd_id %d", &dp_table))
17600         {
17601           dp_table_set = 1;
17602           is_l2 = 1;
17603         }
17604       else if (unformat (input, "vni %d", &vni))
17605         {
17606           vni_set = 1;
17607         }
17608       else
17609         break;
17610     }
17611
17612   if (action_set == 0)
17613     {
17614       errmsg ("Action not set");
17615       return -99;
17616     }
17617   if (dp_table_set == 0 || vni_set == 0)
17618     {
17619       errmsg ("vni and dp_table must be set");
17620       return -99;
17621     }
17622
17623   /* Construct the API message */
17624   M (GPE_ADD_DEL_IFACE, mp);
17625
17626   mp->is_add = is_add;
17627   mp->dp_table = clib_host_to_net_u32 (dp_table);
17628   mp->is_l2 = is_l2;
17629   mp->vni = clib_host_to_net_u32 (vni);
17630
17631   /* send it... */
17632   S (mp);
17633
17634   /* Wait for a reply... */
17635   W (ret);
17636   return ret;
17637 }
17638
17639 static int
17640 api_one_map_register_fallback_threshold (vat_main_t * vam)
17641 {
17642   unformat_input_t *input = vam->input;
17643   vl_api_one_map_register_fallback_threshold_t *mp;
17644   u32 value = 0;
17645   u8 is_set = 0;
17646   int ret;
17647
17648   /* Parse args required to build the message */
17649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17650     {
17651       if (unformat (input, "%u", &value))
17652         is_set = 1;
17653       else
17654         {
17655           clib_warning ("parse error '%U'", format_unformat_error, input);
17656           return -99;
17657         }
17658     }
17659
17660   if (!is_set)
17661     {
17662       errmsg ("fallback threshold value is missing!");
17663       return -99;
17664     }
17665
17666   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17667   mp->value = clib_host_to_net_u32 (value);
17668
17669   /* send it... */
17670   S (mp);
17671
17672   /* Wait for a reply... */
17673   W (ret);
17674   return ret;
17675 }
17676
17677 static int
17678 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17679 {
17680   vl_api_show_one_map_register_fallback_threshold_t *mp;
17681   int ret;
17682
17683   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17684
17685   /* send it... */
17686   S (mp);
17687
17688   /* Wait for a reply... */
17689   W (ret);
17690   return ret;
17691 }
17692
17693 uword
17694 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17695 {
17696   u32 *proto = va_arg (*args, u32 *);
17697
17698   if (unformat (input, "udp"))
17699     *proto = 1;
17700   else if (unformat (input, "api"))
17701     *proto = 2;
17702   else
17703     return 0;
17704
17705   return 1;
17706 }
17707
17708 static int
17709 api_one_set_transport_protocol (vat_main_t * vam)
17710 {
17711   unformat_input_t *input = vam->input;
17712   vl_api_one_set_transport_protocol_t *mp;
17713   u8 is_set = 0;
17714   u32 protocol = 0;
17715   int ret;
17716
17717   /* Parse args required to build the message */
17718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17719     {
17720       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17721         is_set = 1;
17722       else
17723         {
17724           clib_warning ("parse error '%U'", format_unformat_error, input);
17725           return -99;
17726         }
17727     }
17728
17729   if (!is_set)
17730     {
17731       errmsg ("Transport protocol missing!");
17732       return -99;
17733     }
17734
17735   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17736   mp->protocol = (u8) protocol;
17737
17738   /* send it... */
17739   S (mp);
17740
17741   /* Wait for a reply... */
17742   W (ret);
17743   return ret;
17744 }
17745
17746 static int
17747 api_one_get_transport_protocol (vat_main_t * vam)
17748 {
17749   vl_api_one_get_transport_protocol_t *mp;
17750   int ret;
17751
17752   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17753
17754   /* send it... */
17755   S (mp);
17756
17757   /* Wait for a reply... */
17758   W (ret);
17759   return ret;
17760 }
17761
17762 static int
17763 api_one_map_register_set_ttl (vat_main_t * vam)
17764 {
17765   unformat_input_t *input = vam->input;
17766   vl_api_one_map_register_set_ttl_t *mp;
17767   u32 ttl = 0;
17768   u8 is_set = 0;
17769   int ret;
17770
17771   /* Parse args required to build the message */
17772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17773     {
17774       if (unformat (input, "%u", &ttl))
17775         is_set = 1;
17776       else
17777         {
17778           clib_warning ("parse error '%U'", format_unformat_error, input);
17779           return -99;
17780         }
17781     }
17782
17783   if (!is_set)
17784     {
17785       errmsg ("TTL value missing!");
17786       return -99;
17787     }
17788
17789   M (ONE_MAP_REGISTER_SET_TTL, mp);
17790   mp->ttl = clib_host_to_net_u32 (ttl);
17791
17792   /* send it... */
17793   S (mp);
17794
17795   /* Wait for a reply... */
17796   W (ret);
17797   return ret;
17798 }
17799
17800 static int
17801 api_show_one_map_register_ttl (vat_main_t * vam)
17802 {
17803   vl_api_show_one_map_register_ttl_t *mp;
17804   int ret;
17805
17806   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17807
17808   /* send it... */
17809   S (mp);
17810
17811   /* Wait for a reply... */
17812   W (ret);
17813   return ret;
17814 }
17815
17816 /**
17817  * Add/del map request itr rlocs from ONE control plane and updates
17818  *
17819  * @param vam vpp API test context
17820  * @return return code
17821  */
17822 static int
17823 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17824 {
17825   unformat_input_t *input = vam->input;
17826   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17827   u8 *locator_set_name = 0;
17828   u8 locator_set_name_set = 0;
17829   u8 is_add = 1;
17830   int ret;
17831
17832   /* Parse args required to build the message */
17833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17834     {
17835       if (unformat (input, "del"))
17836         {
17837           is_add = 0;
17838         }
17839       else if (unformat (input, "%_%v%_", &locator_set_name))
17840         {
17841           locator_set_name_set = 1;
17842         }
17843       else
17844         {
17845           clib_warning ("parse error '%U'", format_unformat_error, input);
17846           return -99;
17847         }
17848     }
17849
17850   if (is_add && !locator_set_name_set)
17851     {
17852       errmsg ("itr-rloc is not set!");
17853       return -99;
17854     }
17855
17856   if (is_add && vec_len (locator_set_name) > 64)
17857     {
17858       errmsg ("itr-rloc locator-set name too long");
17859       vec_free (locator_set_name);
17860       return -99;
17861     }
17862
17863   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17864   mp->is_add = is_add;
17865   if (is_add)
17866     {
17867       clib_memcpy (mp->locator_set_name, locator_set_name,
17868                    vec_len (locator_set_name));
17869     }
17870   else
17871     {
17872       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17873     }
17874   vec_free (locator_set_name);
17875
17876   /* send it... */
17877   S (mp);
17878
17879   /* Wait for a reply... */
17880   W (ret);
17881   return ret;
17882 }
17883
17884 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17885
17886 static int
17887 api_one_locator_dump (vat_main_t * vam)
17888 {
17889   unformat_input_t *input = vam->input;
17890   vl_api_one_locator_dump_t *mp;
17891   vl_api_control_ping_t *mp_ping;
17892   u8 is_index_set = 0, is_name_set = 0;
17893   u8 *ls_name = 0;
17894   u32 ls_index = ~0;
17895   int ret;
17896
17897   /* Parse args required to build the message */
17898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17899     {
17900       if (unformat (input, "ls_name %_%v%_", &ls_name))
17901         {
17902           is_name_set = 1;
17903         }
17904       else if (unformat (input, "ls_index %d", &ls_index))
17905         {
17906           is_index_set = 1;
17907         }
17908       else
17909         {
17910           errmsg ("parse error '%U'", format_unformat_error, input);
17911           return -99;
17912         }
17913     }
17914
17915   if (!is_index_set && !is_name_set)
17916     {
17917       errmsg ("error: expected one of index or name!");
17918       return -99;
17919     }
17920
17921   if (is_index_set && is_name_set)
17922     {
17923       errmsg ("error: only one param expected!");
17924       return -99;
17925     }
17926
17927   if (vec_len (ls_name) > 62)
17928     {
17929       errmsg ("error: locator set name too long!");
17930       return -99;
17931     }
17932
17933   if (!vam->json_output)
17934     {
17935       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17936     }
17937
17938   M (ONE_LOCATOR_DUMP, mp);
17939   mp->is_index_set = is_index_set;
17940
17941   if (is_index_set)
17942     mp->ls_index = clib_host_to_net_u32 (ls_index);
17943   else
17944     {
17945       vec_add1 (ls_name, 0);
17946       strncpy ((char *) mp->ls_name, (char *) ls_name,
17947                sizeof (mp->ls_name) - 1);
17948     }
17949
17950   /* send it... */
17951   S (mp);
17952
17953   /* Use a control ping for synchronization */
17954   MPING (CONTROL_PING, mp_ping);
17955   S (mp_ping);
17956
17957   /* Wait for a reply... */
17958   W (ret);
17959   return ret;
17960 }
17961
17962 #define api_lisp_locator_dump api_one_locator_dump
17963
17964 static int
17965 api_one_locator_set_dump (vat_main_t * vam)
17966 {
17967   vl_api_one_locator_set_dump_t *mp;
17968   vl_api_control_ping_t *mp_ping;
17969   unformat_input_t *input = vam->input;
17970   u8 filter = 0;
17971   int ret;
17972
17973   /* Parse args required to build the message */
17974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17975     {
17976       if (unformat (input, "local"))
17977         {
17978           filter = 1;
17979         }
17980       else if (unformat (input, "remote"))
17981         {
17982           filter = 2;
17983         }
17984       else
17985         {
17986           errmsg ("parse error '%U'", format_unformat_error, input);
17987           return -99;
17988         }
17989     }
17990
17991   if (!vam->json_output)
17992     {
17993       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17994     }
17995
17996   M (ONE_LOCATOR_SET_DUMP, mp);
17997
17998   mp->filter = filter;
17999
18000   /* send it... */
18001   S (mp);
18002
18003   /* Use a control ping for synchronization */
18004   MPING (CONTROL_PING, mp_ping);
18005   S (mp_ping);
18006
18007   /* Wait for a reply... */
18008   W (ret);
18009   return ret;
18010 }
18011
18012 #define api_lisp_locator_set_dump api_one_locator_set_dump
18013
18014 static int
18015 api_one_eid_table_map_dump (vat_main_t * vam)
18016 {
18017   u8 is_l2 = 0;
18018   u8 mode_set = 0;
18019   unformat_input_t *input = vam->input;
18020   vl_api_one_eid_table_map_dump_t *mp;
18021   vl_api_control_ping_t *mp_ping;
18022   int ret;
18023
18024   /* Parse args required to build the message */
18025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18026     {
18027       if (unformat (input, "l2"))
18028         {
18029           is_l2 = 1;
18030           mode_set = 1;
18031         }
18032       else if (unformat (input, "l3"))
18033         {
18034           is_l2 = 0;
18035           mode_set = 1;
18036         }
18037       else
18038         {
18039           errmsg ("parse error '%U'", format_unformat_error, input);
18040           return -99;
18041         }
18042     }
18043
18044   if (!mode_set)
18045     {
18046       errmsg ("expected one of 'l2' or 'l3' parameter!");
18047       return -99;
18048     }
18049
18050   if (!vam->json_output)
18051     {
18052       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18053     }
18054
18055   M (ONE_EID_TABLE_MAP_DUMP, mp);
18056   mp->is_l2 = is_l2;
18057
18058   /* send it... */
18059   S (mp);
18060
18061   /* Use a control ping for synchronization */
18062   MPING (CONTROL_PING, mp_ping);
18063   S (mp_ping);
18064
18065   /* Wait for a reply... */
18066   W (ret);
18067   return ret;
18068 }
18069
18070 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18071
18072 static int
18073 api_one_eid_table_vni_dump (vat_main_t * vam)
18074 {
18075   vl_api_one_eid_table_vni_dump_t *mp;
18076   vl_api_control_ping_t *mp_ping;
18077   int ret;
18078
18079   if (!vam->json_output)
18080     {
18081       print (vam->ofp, "VNI");
18082     }
18083
18084   M (ONE_EID_TABLE_VNI_DUMP, mp);
18085
18086   /* send it... */
18087   S (mp);
18088
18089   /* Use a control ping for synchronization */
18090   MPING (CONTROL_PING, mp_ping);
18091   S (mp_ping);
18092
18093   /* Wait for a reply... */
18094   W (ret);
18095   return ret;
18096 }
18097
18098 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18099
18100 static int
18101 api_one_eid_table_dump (vat_main_t * vam)
18102 {
18103   unformat_input_t *i = vam->input;
18104   vl_api_one_eid_table_dump_t *mp;
18105   vl_api_control_ping_t *mp_ping;
18106   struct in_addr ip4;
18107   struct in6_addr ip6;
18108   u8 mac[6];
18109   u8 eid_type = ~0, eid_set = 0;
18110   u32 prefix_length = ~0, t, vni = 0;
18111   u8 filter = 0;
18112   int ret;
18113   lisp_nsh_api_t nsh;
18114
18115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18116     {
18117       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18118         {
18119           eid_set = 1;
18120           eid_type = 0;
18121           prefix_length = t;
18122         }
18123       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18124         {
18125           eid_set = 1;
18126           eid_type = 1;
18127           prefix_length = t;
18128         }
18129       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18130         {
18131           eid_set = 1;
18132           eid_type = 2;
18133         }
18134       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18135         {
18136           eid_set = 1;
18137           eid_type = 3;
18138         }
18139       else if (unformat (i, "vni %d", &t))
18140         {
18141           vni = t;
18142         }
18143       else if (unformat (i, "local"))
18144         {
18145           filter = 1;
18146         }
18147       else if (unformat (i, "remote"))
18148         {
18149           filter = 2;
18150         }
18151       else
18152         {
18153           errmsg ("parse error '%U'", format_unformat_error, i);
18154           return -99;
18155         }
18156     }
18157
18158   if (!vam->json_output)
18159     {
18160       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18161              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18162     }
18163
18164   M (ONE_EID_TABLE_DUMP, mp);
18165
18166   mp->filter = filter;
18167   if (eid_set)
18168     {
18169       mp->eid_set = 1;
18170       mp->vni = htonl (vni);
18171       mp->eid_type = eid_type;
18172       switch (eid_type)
18173         {
18174         case 0:
18175           mp->prefix_length = prefix_length;
18176           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18177           break;
18178         case 1:
18179           mp->prefix_length = prefix_length;
18180           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18181           break;
18182         case 2:
18183           clib_memcpy (mp->eid, mac, sizeof (mac));
18184           break;
18185         case 3:
18186           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18187           break;
18188         default:
18189           errmsg ("unknown EID type %d!", eid_type);
18190           return -99;
18191         }
18192     }
18193
18194   /* send it... */
18195   S (mp);
18196
18197   /* Use a control ping for synchronization */
18198   MPING (CONTROL_PING, mp_ping);
18199   S (mp_ping);
18200
18201   /* Wait for a reply... */
18202   W (ret);
18203   return ret;
18204 }
18205
18206 #define api_lisp_eid_table_dump api_one_eid_table_dump
18207
18208 static int
18209 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18210 {
18211   unformat_input_t *i = vam->input;
18212   vl_api_gpe_fwd_entries_get_t *mp;
18213   u8 vni_set = 0;
18214   u32 vni = ~0;
18215   int ret;
18216
18217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18218     {
18219       if (unformat (i, "vni %d", &vni))
18220         {
18221           vni_set = 1;
18222         }
18223       else
18224         {
18225           errmsg ("parse error '%U'", format_unformat_error, i);
18226           return -99;
18227         }
18228     }
18229
18230   if (!vni_set)
18231     {
18232       errmsg ("vni not set!");
18233       return -99;
18234     }
18235
18236   if (!vam->json_output)
18237     {
18238       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18239              "leid", "reid");
18240     }
18241
18242   M (GPE_FWD_ENTRIES_GET, mp);
18243   mp->vni = clib_host_to_net_u32 (vni);
18244
18245   /* send it... */
18246   S (mp);
18247
18248   /* Wait for a reply... */
18249   W (ret);
18250   return ret;
18251 }
18252
18253 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18254 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18255 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18256 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18257 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18258 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18259 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18260 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18261
18262 static int
18263 api_one_adjacencies_get (vat_main_t * vam)
18264 {
18265   unformat_input_t *i = vam->input;
18266   vl_api_one_adjacencies_get_t *mp;
18267   u8 vni_set = 0;
18268   u32 vni = ~0;
18269   int ret;
18270
18271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18272     {
18273       if (unformat (i, "vni %d", &vni))
18274         {
18275           vni_set = 1;
18276         }
18277       else
18278         {
18279           errmsg ("parse error '%U'", format_unformat_error, i);
18280           return -99;
18281         }
18282     }
18283
18284   if (!vni_set)
18285     {
18286       errmsg ("vni not set!");
18287       return -99;
18288     }
18289
18290   if (!vam->json_output)
18291     {
18292       print (vam->ofp, "%s %40s", "leid", "reid");
18293     }
18294
18295   M (ONE_ADJACENCIES_GET, mp);
18296   mp->vni = clib_host_to_net_u32 (vni);
18297
18298   /* send it... */
18299   S (mp);
18300
18301   /* Wait for a reply... */
18302   W (ret);
18303   return ret;
18304 }
18305
18306 #define api_lisp_adjacencies_get api_one_adjacencies_get
18307
18308 static int
18309 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18310 {
18311   unformat_input_t *i = vam->input;
18312   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18313   int ret;
18314   u8 ip_family_set = 0, is_ip4 = 1;
18315
18316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18317     {
18318       if (unformat (i, "ip4"))
18319         {
18320           ip_family_set = 1;
18321           is_ip4 = 1;
18322         }
18323       else if (unformat (i, "ip6"))
18324         {
18325           ip_family_set = 1;
18326           is_ip4 = 0;
18327         }
18328       else
18329         {
18330           errmsg ("parse error '%U'", format_unformat_error, i);
18331           return -99;
18332         }
18333     }
18334
18335   if (!ip_family_set)
18336     {
18337       errmsg ("ip family not set!");
18338       return -99;
18339     }
18340
18341   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18342   mp->is_ip4 = is_ip4;
18343
18344   /* send it... */
18345   S (mp);
18346
18347   /* Wait for a reply... */
18348   W (ret);
18349   return ret;
18350 }
18351
18352 static int
18353 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18354 {
18355   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18356   int ret;
18357
18358   if (!vam->json_output)
18359     {
18360       print (vam->ofp, "VNIs");
18361     }
18362
18363   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18364
18365   /* send it... */
18366   S (mp);
18367
18368   /* Wait for a reply... */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 static int
18374 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18375 {
18376   unformat_input_t *i = vam->input;
18377   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18378   int ret = 0;
18379   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18380   struct in_addr ip4;
18381   struct in6_addr ip6;
18382   u32 table_id = 0, nh_sw_if_index = ~0;
18383
18384   clib_memset (&ip4, 0, sizeof (ip4));
18385   clib_memset (&ip6, 0, sizeof (ip6));
18386
18387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18388     {
18389       if (unformat (i, "del"))
18390         is_add = 0;
18391       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18392                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18393         {
18394           ip_set = 1;
18395           is_ip4 = 1;
18396         }
18397       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18398                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18399         {
18400           ip_set = 1;
18401           is_ip4 = 0;
18402         }
18403       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18404         {
18405           ip_set = 1;
18406           is_ip4 = 1;
18407           nh_sw_if_index = ~0;
18408         }
18409       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18410         {
18411           ip_set = 1;
18412           is_ip4 = 0;
18413           nh_sw_if_index = ~0;
18414         }
18415       else if (unformat (i, "table %d", &table_id))
18416         ;
18417       else
18418         {
18419           errmsg ("parse error '%U'", format_unformat_error, i);
18420           return -99;
18421         }
18422     }
18423
18424   if (!ip_set)
18425     {
18426       errmsg ("nh addr not set!");
18427       return -99;
18428     }
18429
18430   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18431   mp->is_add = is_add;
18432   mp->table_id = clib_host_to_net_u32 (table_id);
18433   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18434   mp->is_ip4 = is_ip4;
18435   if (is_ip4)
18436     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18437   else
18438     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18439
18440   /* send it... */
18441   S (mp);
18442
18443   /* Wait for a reply... */
18444   W (ret);
18445   return ret;
18446 }
18447
18448 static int
18449 api_one_map_server_dump (vat_main_t * vam)
18450 {
18451   vl_api_one_map_server_dump_t *mp;
18452   vl_api_control_ping_t *mp_ping;
18453   int ret;
18454
18455   if (!vam->json_output)
18456     {
18457       print (vam->ofp, "%=20s", "Map server");
18458     }
18459
18460   M (ONE_MAP_SERVER_DUMP, mp);
18461   /* send it... */
18462   S (mp);
18463
18464   /* Use a control ping for synchronization */
18465   MPING (CONTROL_PING, mp_ping);
18466   S (mp_ping);
18467
18468   /* Wait for a reply... */
18469   W (ret);
18470   return ret;
18471 }
18472
18473 #define api_lisp_map_server_dump api_one_map_server_dump
18474
18475 static int
18476 api_one_map_resolver_dump (vat_main_t * vam)
18477 {
18478   vl_api_one_map_resolver_dump_t *mp;
18479   vl_api_control_ping_t *mp_ping;
18480   int ret;
18481
18482   if (!vam->json_output)
18483     {
18484       print (vam->ofp, "%=20s", "Map resolver");
18485     }
18486
18487   M (ONE_MAP_RESOLVER_DUMP, mp);
18488   /* send it... */
18489   S (mp);
18490
18491   /* Use a control ping for synchronization */
18492   MPING (CONTROL_PING, mp_ping);
18493   S (mp_ping);
18494
18495   /* Wait for a reply... */
18496   W (ret);
18497   return ret;
18498 }
18499
18500 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18501
18502 static int
18503 api_one_stats_flush (vat_main_t * vam)
18504 {
18505   vl_api_one_stats_flush_t *mp;
18506   int ret = 0;
18507
18508   M (ONE_STATS_FLUSH, mp);
18509   S (mp);
18510   W (ret);
18511   return ret;
18512 }
18513
18514 static int
18515 api_one_stats_dump (vat_main_t * vam)
18516 {
18517   vl_api_one_stats_dump_t *mp;
18518   vl_api_control_ping_t *mp_ping;
18519   int ret;
18520
18521   M (ONE_STATS_DUMP, mp);
18522   /* send it... */
18523   S (mp);
18524
18525   /* Use a control ping for synchronization */
18526   MPING (CONTROL_PING, mp_ping);
18527   S (mp_ping);
18528
18529   /* Wait for a reply... */
18530   W (ret);
18531   return ret;
18532 }
18533
18534 static int
18535 api_show_one_status (vat_main_t * vam)
18536 {
18537   vl_api_show_one_status_t *mp;
18538   int ret;
18539
18540   if (!vam->json_output)
18541     {
18542       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18543     }
18544
18545   M (SHOW_ONE_STATUS, mp);
18546   /* send it... */
18547   S (mp);
18548   /* Wait for a reply... */
18549   W (ret);
18550   return ret;
18551 }
18552
18553 #define api_show_lisp_status api_show_one_status
18554
18555 static int
18556 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18557 {
18558   vl_api_gpe_fwd_entry_path_dump_t *mp;
18559   vl_api_control_ping_t *mp_ping;
18560   unformat_input_t *i = vam->input;
18561   u32 fwd_entry_index = ~0;
18562   int ret;
18563
18564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18565     {
18566       if (unformat (i, "index %d", &fwd_entry_index))
18567         ;
18568       else
18569         break;
18570     }
18571
18572   if (~0 == fwd_entry_index)
18573     {
18574       errmsg ("no index specified!");
18575       return -99;
18576     }
18577
18578   if (!vam->json_output)
18579     {
18580       print (vam->ofp, "first line");
18581     }
18582
18583   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18584
18585   /* send it... */
18586   S (mp);
18587   /* Use a control ping for synchronization */
18588   MPING (CONTROL_PING, mp_ping);
18589   S (mp_ping);
18590
18591   /* Wait for a reply... */
18592   W (ret);
18593   return ret;
18594 }
18595
18596 static int
18597 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18598 {
18599   vl_api_one_get_map_request_itr_rlocs_t *mp;
18600   int ret;
18601
18602   if (!vam->json_output)
18603     {
18604       print (vam->ofp, "%=20s", "itr-rlocs:");
18605     }
18606
18607   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18608   /* send it... */
18609   S (mp);
18610   /* Wait for a reply... */
18611   W (ret);
18612   return ret;
18613 }
18614
18615 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18616
18617 static int
18618 api_af_packet_create (vat_main_t * vam)
18619 {
18620   unformat_input_t *i = vam->input;
18621   vl_api_af_packet_create_t *mp;
18622   u8 *host_if_name = 0;
18623   u8 hw_addr[6];
18624   u8 random_hw_addr = 1;
18625   int ret;
18626
18627   clib_memset (hw_addr, 0, sizeof (hw_addr));
18628
18629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18630     {
18631       if (unformat (i, "name %s", &host_if_name))
18632         vec_add1 (host_if_name, 0);
18633       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18634         random_hw_addr = 0;
18635       else
18636         break;
18637     }
18638
18639   if (!vec_len (host_if_name))
18640     {
18641       errmsg ("host-interface name must be specified");
18642       return -99;
18643     }
18644
18645   if (vec_len (host_if_name) > 64)
18646     {
18647       errmsg ("host-interface name too long");
18648       return -99;
18649     }
18650
18651   M (AF_PACKET_CREATE, mp);
18652
18653   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18654   clib_memcpy (mp->hw_addr, hw_addr, 6);
18655   mp->use_random_hw_addr = random_hw_addr;
18656   vec_free (host_if_name);
18657
18658   S (mp);
18659
18660   /* *INDENT-OFF* */
18661   W2 (ret,
18662       ({
18663         if (ret == 0)
18664           fprintf (vam->ofp ? vam->ofp : stderr,
18665                    " new sw_if_index = %d\n", vam->sw_if_index);
18666       }));
18667   /* *INDENT-ON* */
18668   return ret;
18669 }
18670
18671 static int
18672 api_af_packet_delete (vat_main_t * vam)
18673 {
18674   unformat_input_t *i = vam->input;
18675   vl_api_af_packet_delete_t *mp;
18676   u8 *host_if_name = 0;
18677   int ret;
18678
18679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18680     {
18681       if (unformat (i, "name %s", &host_if_name))
18682         vec_add1 (host_if_name, 0);
18683       else
18684         break;
18685     }
18686
18687   if (!vec_len (host_if_name))
18688     {
18689       errmsg ("host-interface name must be specified");
18690       return -99;
18691     }
18692
18693   if (vec_len (host_if_name) > 64)
18694     {
18695       errmsg ("host-interface name too long");
18696       return -99;
18697     }
18698
18699   M (AF_PACKET_DELETE, mp);
18700
18701   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18702   vec_free (host_if_name);
18703
18704   S (mp);
18705   W (ret);
18706   return ret;
18707 }
18708
18709 static void vl_api_af_packet_details_t_handler
18710   (vl_api_af_packet_details_t * mp)
18711 {
18712   vat_main_t *vam = &vat_main;
18713
18714   print (vam->ofp, "%-16s %d",
18715          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18716 }
18717
18718 static void vl_api_af_packet_details_t_handler_json
18719   (vl_api_af_packet_details_t * mp)
18720 {
18721   vat_main_t *vam = &vat_main;
18722   vat_json_node_t *node = NULL;
18723
18724   if (VAT_JSON_ARRAY != vam->json_tree.type)
18725     {
18726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18727       vat_json_init_array (&vam->json_tree);
18728     }
18729   node = vat_json_array_add (&vam->json_tree);
18730
18731   vat_json_init_object (node);
18732   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18733   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18734 }
18735
18736 static int
18737 api_af_packet_dump (vat_main_t * vam)
18738 {
18739   vl_api_af_packet_dump_t *mp;
18740   vl_api_control_ping_t *mp_ping;
18741   int ret;
18742
18743   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18744   /* Get list of tap interfaces */
18745   M (AF_PACKET_DUMP, mp);
18746   S (mp);
18747
18748   /* Use a control ping for synchronization */
18749   MPING (CONTROL_PING, mp_ping);
18750   S (mp_ping);
18751
18752   W (ret);
18753   return ret;
18754 }
18755
18756 static int
18757 api_policer_add_del (vat_main_t * vam)
18758 {
18759   unformat_input_t *i = vam->input;
18760   vl_api_policer_add_del_t *mp;
18761   u8 is_add = 1;
18762   u8 *name = 0;
18763   u32 cir = 0;
18764   u32 eir = 0;
18765   u64 cb = 0;
18766   u64 eb = 0;
18767   u8 rate_type = 0;
18768   u8 round_type = 0;
18769   u8 type = 0;
18770   u8 color_aware = 0;
18771   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18772   int ret;
18773
18774   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18775   conform_action.dscp = 0;
18776   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18777   exceed_action.dscp = 0;
18778   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18779   violate_action.dscp = 0;
18780
18781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18782     {
18783       if (unformat (i, "del"))
18784         is_add = 0;
18785       else if (unformat (i, "name %s", &name))
18786         vec_add1 (name, 0);
18787       else if (unformat (i, "cir %u", &cir))
18788         ;
18789       else if (unformat (i, "eir %u", &eir))
18790         ;
18791       else if (unformat (i, "cb %u", &cb))
18792         ;
18793       else if (unformat (i, "eb %u", &eb))
18794         ;
18795       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18796                          &rate_type))
18797         ;
18798       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18799                          &round_type))
18800         ;
18801       else if (unformat (i, "type %U", unformat_policer_type, &type))
18802         ;
18803       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18804                          &conform_action))
18805         ;
18806       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18807                          &exceed_action))
18808         ;
18809       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18810                          &violate_action))
18811         ;
18812       else if (unformat (i, "color-aware"))
18813         color_aware = 1;
18814       else
18815         break;
18816     }
18817
18818   if (!vec_len (name))
18819     {
18820       errmsg ("policer name must be specified");
18821       return -99;
18822     }
18823
18824   if (vec_len (name) > 64)
18825     {
18826       errmsg ("policer name too long");
18827       return -99;
18828     }
18829
18830   M (POLICER_ADD_DEL, mp);
18831
18832   clib_memcpy (mp->name, name, vec_len (name));
18833   vec_free (name);
18834   mp->is_add = is_add;
18835   mp->cir = ntohl (cir);
18836   mp->eir = ntohl (eir);
18837   mp->cb = clib_net_to_host_u64 (cb);
18838   mp->eb = clib_net_to_host_u64 (eb);
18839   mp->rate_type = rate_type;
18840   mp->round_type = round_type;
18841   mp->type = type;
18842   mp->conform_action_type = conform_action.action_type;
18843   mp->conform_dscp = conform_action.dscp;
18844   mp->exceed_action_type = exceed_action.action_type;
18845   mp->exceed_dscp = exceed_action.dscp;
18846   mp->violate_action_type = violate_action.action_type;
18847   mp->violate_dscp = violate_action.dscp;
18848   mp->color_aware = color_aware;
18849
18850   S (mp);
18851   W (ret);
18852   return ret;
18853 }
18854
18855 static int
18856 api_policer_dump (vat_main_t * vam)
18857 {
18858   unformat_input_t *i = vam->input;
18859   vl_api_policer_dump_t *mp;
18860   vl_api_control_ping_t *mp_ping;
18861   u8 *match_name = 0;
18862   u8 match_name_valid = 0;
18863   int ret;
18864
18865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18866     {
18867       if (unformat (i, "name %s", &match_name))
18868         {
18869           vec_add1 (match_name, 0);
18870           match_name_valid = 1;
18871         }
18872       else
18873         break;
18874     }
18875
18876   M (POLICER_DUMP, mp);
18877   mp->match_name_valid = match_name_valid;
18878   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18879   vec_free (match_name);
18880   /* send it... */
18881   S (mp);
18882
18883   /* Use a control ping for synchronization */
18884   MPING (CONTROL_PING, mp_ping);
18885   S (mp_ping);
18886
18887   /* Wait for a reply... */
18888   W (ret);
18889   return ret;
18890 }
18891
18892 static int
18893 api_policer_classify_set_interface (vat_main_t * vam)
18894 {
18895   unformat_input_t *i = vam->input;
18896   vl_api_policer_classify_set_interface_t *mp;
18897   u32 sw_if_index;
18898   int sw_if_index_set;
18899   u32 ip4_table_index = ~0;
18900   u32 ip6_table_index = ~0;
18901   u32 l2_table_index = ~0;
18902   u8 is_add = 1;
18903   int ret;
18904
18905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18906     {
18907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18908         sw_if_index_set = 1;
18909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18910         sw_if_index_set = 1;
18911       else if (unformat (i, "del"))
18912         is_add = 0;
18913       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18914         ;
18915       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18916         ;
18917       else if (unformat (i, "l2-table %d", &l2_table_index))
18918         ;
18919       else
18920         {
18921           clib_warning ("parse error '%U'", format_unformat_error, i);
18922           return -99;
18923         }
18924     }
18925
18926   if (sw_if_index_set == 0)
18927     {
18928       errmsg ("missing interface name or sw_if_index");
18929       return -99;
18930     }
18931
18932   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18933
18934   mp->sw_if_index = ntohl (sw_if_index);
18935   mp->ip4_table_index = ntohl (ip4_table_index);
18936   mp->ip6_table_index = ntohl (ip6_table_index);
18937   mp->l2_table_index = ntohl (l2_table_index);
18938   mp->is_add = is_add;
18939
18940   S (mp);
18941   W (ret);
18942   return ret;
18943 }
18944
18945 static int
18946 api_policer_classify_dump (vat_main_t * vam)
18947 {
18948   unformat_input_t *i = vam->input;
18949   vl_api_policer_classify_dump_t *mp;
18950   vl_api_control_ping_t *mp_ping;
18951   u8 type = POLICER_CLASSIFY_N_TABLES;
18952   int ret;
18953
18954   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18955     ;
18956   else
18957     {
18958       errmsg ("classify table type must be specified");
18959       return -99;
18960     }
18961
18962   if (!vam->json_output)
18963     {
18964       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18965     }
18966
18967   M (POLICER_CLASSIFY_DUMP, mp);
18968   mp->type = type;
18969   /* send it... */
18970   S (mp);
18971
18972   /* Use a control ping for synchronization */
18973   MPING (CONTROL_PING, mp_ping);
18974   S (mp_ping);
18975
18976   /* Wait for a reply... */
18977   W (ret);
18978   return ret;
18979 }
18980
18981 static int
18982 api_netmap_create (vat_main_t * vam)
18983 {
18984   unformat_input_t *i = vam->input;
18985   vl_api_netmap_create_t *mp;
18986   u8 *if_name = 0;
18987   u8 hw_addr[6];
18988   u8 random_hw_addr = 1;
18989   u8 is_pipe = 0;
18990   u8 is_master = 0;
18991   int ret;
18992
18993   clib_memset (hw_addr, 0, sizeof (hw_addr));
18994
18995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18996     {
18997       if (unformat (i, "name %s", &if_name))
18998         vec_add1 (if_name, 0);
18999       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19000         random_hw_addr = 0;
19001       else if (unformat (i, "pipe"))
19002         is_pipe = 1;
19003       else if (unformat (i, "master"))
19004         is_master = 1;
19005       else if (unformat (i, "slave"))
19006         is_master = 0;
19007       else
19008         break;
19009     }
19010
19011   if (!vec_len (if_name))
19012     {
19013       errmsg ("interface name must be specified");
19014       return -99;
19015     }
19016
19017   if (vec_len (if_name) > 64)
19018     {
19019       errmsg ("interface name too long");
19020       return -99;
19021     }
19022
19023   M (NETMAP_CREATE, mp);
19024
19025   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19026   clib_memcpy (mp->hw_addr, hw_addr, 6);
19027   mp->use_random_hw_addr = random_hw_addr;
19028   mp->is_pipe = is_pipe;
19029   mp->is_master = is_master;
19030   vec_free (if_name);
19031
19032   S (mp);
19033   W (ret);
19034   return ret;
19035 }
19036
19037 static int
19038 api_netmap_delete (vat_main_t * vam)
19039 {
19040   unformat_input_t *i = vam->input;
19041   vl_api_netmap_delete_t *mp;
19042   u8 *if_name = 0;
19043   int ret;
19044
19045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19046     {
19047       if (unformat (i, "name %s", &if_name))
19048         vec_add1 (if_name, 0);
19049       else
19050         break;
19051     }
19052
19053   if (!vec_len (if_name))
19054     {
19055       errmsg ("interface name must be specified");
19056       return -99;
19057     }
19058
19059   if (vec_len (if_name) > 64)
19060     {
19061       errmsg ("interface name too long");
19062       return -99;
19063     }
19064
19065   M (NETMAP_DELETE, mp);
19066
19067   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19068   vec_free (if_name);
19069
19070   S (mp);
19071   W (ret);
19072   return ret;
19073 }
19074
19075 static void
19076 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19077 {
19078   if (fp->afi == IP46_TYPE_IP6)
19079     print (vam->ofp,
19080            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19081            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19082            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19083            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19084            format_ip6_address, fp->next_hop);
19085   else if (fp->afi == IP46_TYPE_IP4)
19086     print (vam->ofp,
19087            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19088            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19089            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19090            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19091            format_ip4_address, fp->next_hop);
19092 }
19093
19094 static void
19095 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19096                                  vl_api_fib_path_t * fp)
19097 {
19098   struct in_addr ip4;
19099   struct in6_addr ip6;
19100
19101   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19102   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19103   vat_json_object_add_uint (node, "is_local", fp->is_local);
19104   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19105   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19106   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19107   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19108   if (fp->afi == IP46_TYPE_IP4)
19109     {
19110       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19111       vat_json_object_add_ip4 (node, "next_hop", ip4);
19112     }
19113   else if (fp->afi == IP46_TYPE_IP6)
19114     {
19115       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19116       vat_json_object_add_ip6 (node, "next_hop", ip6);
19117     }
19118 }
19119
19120 static void
19121 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19122 {
19123   vat_main_t *vam = &vat_main;
19124   int count = ntohl (mp->mt_count);
19125   vl_api_fib_path_t *fp;
19126   i32 i;
19127
19128   print (vam->ofp, "[%d]: sw_if_index %d via:",
19129          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19130   fp = mp->mt_paths;
19131   for (i = 0; i < count; i++)
19132     {
19133       vl_api_mpls_fib_path_print (vam, fp);
19134       fp++;
19135     }
19136
19137   print (vam->ofp, "");
19138 }
19139
19140 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19141 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19142
19143 static void
19144 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19145 {
19146   vat_main_t *vam = &vat_main;
19147   vat_json_node_t *node = NULL;
19148   int count = ntohl (mp->mt_count);
19149   vl_api_fib_path_t *fp;
19150   i32 i;
19151
19152   if (VAT_JSON_ARRAY != vam->json_tree.type)
19153     {
19154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19155       vat_json_init_array (&vam->json_tree);
19156     }
19157   node = vat_json_array_add (&vam->json_tree);
19158
19159   vat_json_init_object (node);
19160   vat_json_object_add_uint (node, "tunnel_index",
19161                             ntohl (mp->mt_tunnel_index));
19162   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19163
19164   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19165
19166   fp = mp->mt_paths;
19167   for (i = 0; i < count; i++)
19168     {
19169       vl_api_mpls_fib_path_json_print (node, fp);
19170       fp++;
19171     }
19172 }
19173
19174 static int
19175 api_mpls_tunnel_dump (vat_main_t * vam)
19176 {
19177   vl_api_mpls_tunnel_dump_t *mp;
19178   vl_api_control_ping_t *mp_ping;
19179   u32 sw_if_index = ~0;
19180   int ret;
19181
19182   /* Parse args required to build the message */
19183   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19184     {
19185       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19186         ;
19187     }
19188
19189   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19190
19191   M (MPLS_TUNNEL_DUMP, mp);
19192   mp->sw_if_index = htonl (sw_if_index);
19193   S (mp);
19194
19195   /* Use a control ping for synchronization */
19196   MPING (CONTROL_PING, mp_ping);
19197   S (mp_ping);
19198
19199   W (ret);
19200   return ret;
19201 }
19202
19203 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19204 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19205
19206
19207 static void
19208 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19209 {
19210   vat_main_t *vam = &vat_main;
19211   int count = ntohl (mp->count);
19212   vl_api_fib_path_t *fp;
19213   int i;
19214
19215   print (vam->ofp,
19216          "table-id %d, label %u, ess_bit %u",
19217          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19218   fp = mp->path;
19219   for (i = 0; i < count; i++)
19220     {
19221       vl_api_mpls_fib_path_print (vam, fp);
19222       fp++;
19223     }
19224 }
19225
19226 static void vl_api_mpls_fib_details_t_handler_json
19227   (vl_api_mpls_fib_details_t * mp)
19228 {
19229   vat_main_t *vam = &vat_main;
19230   int count = ntohl (mp->count);
19231   vat_json_node_t *node = NULL;
19232   vl_api_fib_path_t *fp;
19233   int i;
19234
19235   if (VAT_JSON_ARRAY != vam->json_tree.type)
19236     {
19237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19238       vat_json_init_array (&vam->json_tree);
19239     }
19240   node = vat_json_array_add (&vam->json_tree);
19241
19242   vat_json_init_object (node);
19243   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19244   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19245   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19246   vat_json_object_add_uint (node, "path_count", count);
19247   fp = mp->path;
19248   for (i = 0; i < count; i++)
19249     {
19250       vl_api_mpls_fib_path_json_print (node, fp);
19251       fp++;
19252     }
19253 }
19254
19255 static int
19256 api_mpls_fib_dump (vat_main_t * vam)
19257 {
19258   vl_api_mpls_fib_dump_t *mp;
19259   vl_api_control_ping_t *mp_ping;
19260   int ret;
19261
19262   M (MPLS_FIB_DUMP, mp);
19263   S (mp);
19264
19265   /* Use a control ping for synchronization */
19266   MPING (CONTROL_PING, mp_ping);
19267   S (mp_ping);
19268
19269   W (ret);
19270   return ret;
19271 }
19272
19273 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19274 #define vl_api_ip_fib_details_t_print vl_noop_handler
19275
19276 static void
19277 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19278 {
19279   vat_main_t *vam = &vat_main;
19280   int count = ntohl (mp->count);
19281   vl_api_fib_path_t *fp;
19282   int i;
19283
19284   print (vam->ofp,
19285          "table-id %d, prefix %U/%d stats-index %d",
19286          ntohl (mp->table_id), format_ip4_address, mp->address,
19287          mp->address_length, ntohl (mp->stats_index));
19288   fp = mp->path;
19289   for (i = 0; i < count; i++)
19290     {
19291       if (fp->afi == IP46_TYPE_IP6)
19292         print (vam->ofp,
19293                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19294                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19295                "next_hop_table %d",
19296                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19297                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19298                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19299       else if (fp->afi == IP46_TYPE_IP4)
19300         print (vam->ofp,
19301                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19302                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19303                "next_hop_table %d",
19304                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19305                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19306                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19307       fp++;
19308     }
19309 }
19310
19311 static void vl_api_ip_fib_details_t_handler_json
19312   (vl_api_ip_fib_details_t * mp)
19313 {
19314   vat_main_t *vam = &vat_main;
19315   int count = ntohl (mp->count);
19316   vat_json_node_t *node = NULL;
19317   struct in_addr ip4;
19318   struct in6_addr ip6;
19319   vl_api_fib_path_t *fp;
19320   int i;
19321
19322   if (VAT_JSON_ARRAY != vam->json_tree.type)
19323     {
19324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19325       vat_json_init_array (&vam->json_tree);
19326     }
19327   node = vat_json_array_add (&vam->json_tree);
19328
19329   vat_json_init_object (node);
19330   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19331   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19332   vat_json_object_add_ip4 (node, "prefix", ip4);
19333   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19334   vat_json_object_add_uint (node, "path_count", count);
19335   fp = mp->path;
19336   for (i = 0; i < count; i++)
19337     {
19338       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19339       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19340       vat_json_object_add_uint (node, "is_local", fp->is_local);
19341       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19342       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19343       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19344       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19345       if (fp->afi == IP46_TYPE_IP4)
19346         {
19347           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19348           vat_json_object_add_ip4 (node, "next_hop", ip4);
19349         }
19350       else if (fp->afi == IP46_TYPE_IP6)
19351         {
19352           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19353           vat_json_object_add_ip6 (node, "next_hop", ip6);
19354         }
19355     }
19356 }
19357
19358 static int
19359 api_ip_fib_dump (vat_main_t * vam)
19360 {
19361   vl_api_ip_fib_dump_t *mp;
19362   vl_api_control_ping_t *mp_ping;
19363   int ret;
19364
19365   M (IP_FIB_DUMP, mp);
19366   S (mp);
19367
19368   /* Use a control ping for synchronization */
19369   MPING (CONTROL_PING, mp_ping);
19370   S (mp_ping);
19371
19372   W (ret);
19373   return ret;
19374 }
19375
19376 static int
19377 api_ip_mfib_dump (vat_main_t * vam)
19378 {
19379   vl_api_ip_mfib_dump_t *mp;
19380   vl_api_control_ping_t *mp_ping;
19381   int ret;
19382
19383   M (IP_MFIB_DUMP, mp);
19384   S (mp);
19385
19386   /* Use a control ping for synchronization */
19387   MPING (CONTROL_PING, mp_ping);
19388   S (mp_ping);
19389
19390   W (ret);
19391   return ret;
19392 }
19393
19394 static void vl_api_ip_neighbor_details_t_handler
19395   (vl_api_ip_neighbor_details_t * mp)
19396 {
19397   vat_main_t *vam = &vat_main;
19398
19399   print (vam->ofp, "%c %U %U",
19400          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19401          format_vl_api_mac_address, &mp->neighbor.mac_address,
19402          format_vl_api_address, &mp->neighbor.ip_address);
19403 }
19404
19405 static void vl_api_ip_neighbor_details_t_handler_json
19406   (vl_api_ip_neighbor_details_t * mp)
19407 {
19408
19409   vat_main_t *vam = &vat_main;
19410   vat_json_node_t *node;
19411
19412   if (VAT_JSON_ARRAY != vam->json_tree.type)
19413     {
19414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19415       vat_json_init_array (&vam->json_tree);
19416     }
19417   node = vat_json_array_add (&vam->json_tree);
19418
19419   vat_json_init_object (node);
19420   vat_json_object_add_string_copy
19421     (node, "flag",
19422      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19423       (u8 *) "static" : (u8 *) "dynamic"));
19424
19425   vat_json_object_add_string_copy (node, "link_layer",
19426                                    format (0, "%U", format_vl_api_mac_address,
19427                                            &mp->neighbor.mac_address));
19428   vat_json_object_add_address (node, &mp->neighbor.ip_address);
19429 }
19430
19431 static int
19432 api_ip_neighbor_dump (vat_main_t * vam)
19433 {
19434   unformat_input_t *i = vam->input;
19435   vl_api_ip_neighbor_dump_t *mp;
19436   vl_api_control_ping_t *mp_ping;
19437   u8 is_ipv6 = 0;
19438   u32 sw_if_index = ~0;
19439   int ret;
19440
19441   /* Parse args required to build the message */
19442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19443     {
19444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19445         ;
19446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19447         ;
19448       else if (unformat (i, "ip6"))
19449         is_ipv6 = 1;
19450       else
19451         break;
19452     }
19453
19454   if (sw_if_index == ~0)
19455     {
19456       errmsg ("missing interface name or sw_if_index");
19457       return -99;
19458     }
19459
19460   M (IP_NEIGHBOR_DUMP, mp);
19461   mp->is_ipv6 = (u8) is_ipv6;
19462   mp->sw_if_index = ntohl (sw_if_index);
19463   S (mp);
19464
19465   /* Use a control ping for synchronization */
19466   MPING (CONTROL_PING, mp_ping);
19467   S (mp_ping);
19468
19469   W (ret);
19470   return ret;
19471 }
19472
19473 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19474 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19475
19476 static void
19477 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19478 {
19479   vat_main_t *vam = &vat_main;
19480   int count = ntohl (mp->count);
19481   vl_api_fib_path_t *fp;
19482   int i;
19483
19484   print (vam->ofp,
19485          "table-id %d, prefix %U/%d stats-index %d",
19486          ntohl (mp->table_id), format_ip6_address, mp->address,
19487          mp->address_length, ntohl (mp->stats_index));
19488   fp = mp->path;
19489   for (i = 0; i < count; i++)
19490     {
19491       if (fp->afi == IP46_TYPE_IP6)
19492         print (vam->ofp,
19493                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19494                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19495                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19496                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19497                format_ip6_address, fp->next_hop);
19498       else if (fp->afi == IP46_TYPE_IP4)
19499         print (vam->ofp,
19500                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19501                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19502                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19503                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19504                format_ip4_address, fp->next_hop);
19505       fp++;
19506     }
19507 }
19508
19509 static void vl_api_ip6_fib_details_t_handler_json
19510   (vl_api_ip6_fib_details_t * mp)
19511 {
19512   vat_main_t *vam = &vat_main;
19513   int count = ntohl (mp->count);
19514   vat_json_node_t *node = NULL;
19515   struct in_addr ip4;
19516   struct in6_addr ip6;
19517   vl_api_fib_path_t *fp;
19518   int i;
19519
19520   if (VAT_JSON_ARRAY != vam->json_tree.type)
19521     {
19522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19523       vat_json_init_array (&vam->json_tree);
19524     }
19525   node = vat_json_array_add (&vam->json_tree);
19526
19527   vat_json_init_object (node);
19528   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19529   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19530   vat_json_object_add_ip6 (node, "prefix", ip6);
19531   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19532   vat_json_object_add_uint (node, "path_count", count);
19533   fp = mp->path;
19534   for (i = 0; i < count; i++)
19535     {
19536       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19537       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19538       vat_json_object_add_uint (node, "is_local", fp->is_local);
19539       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19540       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19541       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19542       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19543       if (fp->afi == IP46_TYPE_IP4)
19544         {
19545           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19546           vat_json_object_add_ip4 (node, "next_hop", ip4);
19547         }
19548       else if (fp->afi == IP46_TYPE_IP6)
19549         {
19550           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19551           vat_json_object_add_ip6 (node, "next_hop", ip6);
19552         }
19553     }
19554 }
19555
19556 static int
19557 api_ip6_fib_dump (vat_main_t * vam)
19558 {
19559   vl_api_ip6_fib_dump_t *mp;
19560   vl_api_control_ping_t *mp_ping;
19561   int ret;
19562
19563   M (IP6_FIB_DUMP, mp);
19564   S (mp);
19565
19566   /* Use a control ping for synchronization */
19567   MPING (CONTROL_PING, mp_ping);
19568   S (mp_ping);
19569
19570   W (ret);
19571   return ret;
19572 }
19573
19574 static int
19575 api_ip6_mfib_dump (vat_main_t * vam)
19576 {
19577   vl_api_ip6_mfib_dump_t *mp;
19578   vl_api_control_ping_t *mp_ping;
19579   int ret;
19580
19581   M (IP6_MFIB_DUMP, mp);
19582   S (mp);
19583
19584   /* Use a control ping for synchronization */
19585   MPING (CONTROL_PING, mp_ping);
19586   S (mp_ping);
19587
19588   W (ret);
19589   return ret;
19590 }
19591
19592 int
19593 api_classify_table_ids (vat_main_t * vam)
19594 {
19595   vl_api_classify_table_ids_t *mp;
19596   int ret;
19597
19598   /* Construct the API message */
19599   M (CLASSIFY_TABLE_IDS, mp);
19600   mp->context = 0;
19601
19602   S (mp);
19603   W (ret);
19604   return ret;
19605 }
19606
19607 int
19608 api_classify_table_by_interface (vat_main_t * vam)
19609 {
19610   unformat_input_t *input = vam->input;
19611   vl_api_classify_table_by_interface_t *mp;
19612
19613   u32 sw_if_index = ~0;
19614   int ret;
19615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19616     {
19617       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19618         ;
19619       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19620         ;
19621       else
19622         break;
19623     }
19624   if (sw_if_index == ~0)
19625     {
19626       errmsg ("missing interface name or sw_if_index");
19627       return -99;
19628     }
19629
19630   /* Construct the API message */
19631   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19632   mp->context = 0;
19633   mp->sw_if_index = ntohl (sw_if_index);
19634
19635   S (mp);
19636   W (ret);
19637   return ret;
19638 }
19639
19640 int
19641 api_classify_table_info (vat_main_t * vam)
19642 {
19643   unformat_input_t *input = vam->input;
19644   vl_api_classify_table_info_t *mp;
19645
19646   u32 table_id = ~0;
19647   int ret;
19648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19649     {
19650       if (unformat (input, "table_id %d", &table_id))
19651         ;
19652       else
19653         break;
19654     }
19655   if (table_id == ~0)
19656     {
19657       errmsg ("missing table id");
19658       return -99;
19659     }
19660
19661   /* Construct the API message */
19662   M (CLASSIFY_TABLE_INFO, mp);
19663   mp->context = 0;
19664   mp->table_id = ntohl (table_id);
19665
19666   S (mp);
19667   W (ret);
19668   return ret;
19669 }
19670
19671 int
19672 api_classify_session_dump (vat_main_t * vam)
19673 {
19674   unformat_input_t *input = vam->input;
19675   vl_api_classify_session_dump_t *mp;
19676   vl_api_control_ping_t *mp_ping;
19677
19678   u32 table_id = ~0;
19679   int ret;
19680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19681     {
19682       if (unformat (input, "table_id %d", &table_id))
19683         ;
19684       else
19685         break;
19686     }
19687   if (table_id == ~0)
19688     {
19689       errmsg ("missing table id");
19690       return -99;
19691     }
19692
19693   /* Construct the API message */
19694   M (CLASSIFY_SESSION_DUMP, mp);
19695   mp->context = 0;
19696   mp->table_id = ntohl (table_id);
19697   S (mp);
19698
19699   /* Use a control ping for synchronization */
19700   MPING (CONTROL_PING, mp_ping);
19701   S (mp_ping);
19702
19703   W (ret);
19704   return ret;
19705 }
19706
19707 static void
19708 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19709 {
19710   vat_main_t *vam = &vat_main;
19711
19712   print (vam->ofp, "collector_address %U, collector_port %d, "
19713          "src_address %U, vrf_id %d, path_mtu %u, "
19714          "template_interval %u, udp_checksum %d",
19715          format_ip4_address, mp->collector_address,
19716          ntohs (mp->collector_port),
19717          format_ip4_address, mp->src_address,
19718          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19719          ntohl (mp->template_interval), mp->udp_checksum);
19720
19721   vam->retval = 0;
19722   vam->result_ready = 1;
19723 }
19724
19725 static void
19726   vl_api_ipfix_exporter_details_t_handler_json
19727   (vl_api_ipfix_exporter_details_t * mp)
19728 {
19729   vat_main_t *vam = &vat_main;
19730   vat_json_node_t node;
19731   struct in_addr collector_address;
19732   struct in_addr src_address;
19733
19734   vat_json_init_object (&node);
19735   clib_memcpy (&collector_address, &mp->collector_address,
19736                sizeof (collector_address));
19737   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19738   vat_json_object_add_uint (&node, "collector_port",
19739                             ntohs (mp->collector_port));
19740   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19741   vat_json_object_add_ip4 (&node, "src_address", src_address);
19742   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19743   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19744   vat_json_object_add_uint (&node, "template_interval",
19745                             ntohl (mp->template_interval));
19746   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19747
19748   vat_json_print (vam->ofp, &node);
19749   vat_json_free (&node);
19750   vam->retval = 0;
19751   vam->result_ready = 1;
19752 }
19753
19754 int
19755 api_ipfix_exporter_dump (vat_main_t * vam)
19756 {
19757   vl_api_ipfix_exporter_dump_t *mp;
19758   int ret;
19759
19760   /* Construct the API message */
19761   M (IPFIX_EXPORTER_DUMP, mp);
19762   mp->context = 0;
19763
19764   S (mp);
19765   W (ret);
19766   return ret;
19767 }
19768
19769 static int
19770 api_ipfix_classify_stream_dump (vat_main_t * vam)
19771 {
19772   vl_api_ipfix_classify_stream_dump_t *mp;
19773   int ret;
19774
19775   /* Construct the API message */
19776   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19777   mp->context = 0;
19778
19779   S (mp);
19780   W (ret);
19781   return ret;
19782   /* NOTREACHED */
19783   return 0;
19784 }
19785
19786 static void
19787   vl_api_ipfix_classify_stream_details_t_handler
19788   (vl_api_ipfix_classify_stream_details_t * mp)
19789 {
19790   vat_main_t *vam = &vat_main;
19791   print (vam->ofp, "domain_id %d, src_port %d",
19792          ntohl (mp->domain_id), ntohs (mp->src_port));
19793   vam->retval = 0;
19794   vam->result_ready = 1;
19795 }
19796
19797 static void
19798   vl_api_ipfix_classify_stream_details_t_handler_json
19799   (vl_api_ipfix_classify_stream_details_t * mp)
19800 {
19801   vat_main_t *vam = &vat_main;
19802   vat_json_node_t node;
19803
19804   vat_json_init_object (&node);
19805   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19806   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19807
19808   vat_json_print (vam->ofp, &node);
19809   vat_json_free (&node);
19810   vam->retval = 0;
19811   vam->result_ready = 1;
19812 }
19813
19814 static int
19815 api_ipfix_classify_table_dump (vat_main_t * vam)
19816 {
19817   vl_api_ipfix_classify_table_dump_t *mp;
19818   vl_api_control_ping_t *mp_ping;
19819   int ret;
19820
19821   if (!vam->json_output)
19822     {
19823       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19824              "transport_protocol");
19825     }
19826
19827   /* Construct the API message */
19828   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19829
19830   /* send it... */
19831   S (mp);
19832
19833   /* Use a control ping for synchronization */
19834   MPING (CONTROL_PING, mp_ping);
19835   S (mp_ping);
19836
19837   W (ret);
19838   return ret;
19839 }
19840
19841 static void
19842   vl_api_ipfix_classify_table_details_t_handler
19843   (vl_api_ipfix_classify_table_details_t * mp)
19844 {
19845   vat_main_t *vam = &vat_main;
19846   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19847          mp->transport_protocol);
19848 }
19849
19850 static void
19851   vl_api_ipfix_classify_table_details_t_handler_json
19852   (vl_api_ipfix_classify_table_details_t * mp)
19853 {
19854   vat_json_node_t *node = NULL;
19855   vat_main_t *vam = &vat_main;
19856
19857   if (VAT_JSON_ARRAY != vam->json_tree.type)
19858     {
19859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19860       vat_json_init_array (&vam->json_tree);
19861     }
19862
19863   node = vat_json_array_add (&vam->json_tree);
19864   vat_json_init_object (node);
19865
19866   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19867   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19868   vat_json_object_add_uint (node, "transport_protocol",
19869                             mp->transport_protocol);
19870 }
19871
19872 static int
19873 api_sw_interface_span_enable_disable (vat_main_t * vam)
19874 {
19875   unformat_input_t *i = vam->input;
19876   vl_api_sw_interface_span_enable_disable_t *mp;
19877   u32 src_sw_if_index = ~0;
19878   u32 dst_sw_if_index = ~0;
19879   u8 state = 3;
19880   int ret;
19881   u8 is_l2 = 0;
19882
19883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19884     {
19885       if (unformat
19886           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19887         ;
19888       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19889         ;
19890       else
19891         if (unformat
19892             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19893         ;
19894       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19895         ;
19896       else if (unformat (i, "disable"))
19897         state = 0;
19898       else if (unformat (i, "rx"))
19899         state = 1;
19900       else if (unformat (i, "tx"))
19901         state = 2;
19902       else if (unformat (i, "both"))
19903         state = 3;
19904       else if (unformat (i, "l2"))
19905         is_l2 = 1;
19906       else
19907         break;
19908     }
19909
19910   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19911
19912   mp->sw_if_index_from = htonl (src_sw_if_index);
19913   mp->sw_if_index_to = htonl (dst_sw_if_index);
19914   mp->state = state;
19915   mp->is_l2 = is_l2;
19916
19917   S (mp);
19918   W (ret);
19919   return ret;
19920 }
19921
19922 static void
19923 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19924                                             * mp)
19925 {
19926   vat_main_t *vam = &vat_main;
19927   u8 *sw_if_from_name = 0;
19928   u8 *sw_if_to_name = 0;
19929   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19930   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19931   char *states[] = { "none", "rx", "tx", "both" };
19932   hash_pair_t *p;
19933
19934   /* *INDENT-OFF* */
19935   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19936   ({
19937     if ((u32) p->value[0] == sw_if_index_from)
19938       {
19939         sw_if_from_name = (u8 *)(p->key);
19940         if (sw_if_to_name)
19941           break;
19942       }
19943     if ((u32) p->value[0] == sw_if_index_to)
19944       {
19945         sw_if_to_name = (u8 *)(p->key);
19946         if (sw_if_from_name)
19947           break;
19948       }
19949   }));
19950   /* *INDENT-ON* */
19951   print (vam->ofp, "%20s => %20s (%s) %s",
19952          sw_if_from_name, sw_if_to_name, states[mp->state],
19953          mp->is_l2 ? "l2" : "device");
19954 }
19955
19956 static void
19957   vl_api_sw_interface_span_details_t_handler_json
19958   (vl_api_sw_interface_span_details_t * mp)
19959 {
19960   vat_main_t *vam = &vat_main;
19961   vat_json_node_t *node = NULL;
19962   u8 *sw_if_from_name = 0;
19963   u8 *sw_if_to_name = 0;
19964   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19965   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19966   hash_pair_t *p;
19967
19968   /* *INDENT-OFF* */
19969   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19970   ({
19971     if ((u32) p->value[0] == sw_if_index_from)
19972       {
19973         sw_if_from_name = (u8 *)(p->key);
19974         if (sw_if_to_name)
19975           break;
19976       }
19977     if ((u32) p->value[0] == sw_if_index_to)
19978       {
19979         sw_if_to_name = (u8 *)(p->key);
19980         if (sw_if_from_name)
19981           break;
19982       }
19983   }));
19984   /* *INDENT-ON* */
19985
19986   if (VAT_JSON_ARRAY != vam->json_tree.type)
19987     {
19988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19989       vat_json_init_array (&vam->json_tree);
19990     }
19991   node = vat_json_array_add (&vam->json_tree);
19992
19993   vat_json_init_object (node);
19994   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19995   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19996   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19997   if (0 != sw_if_to_name)
19998     {
19999       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20000     }
20001   vat_json_object_add_uint (node, "state", mp->state);
20002   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20003 }
20004
20005 static int
20006 api_sw_interface_span_dump (vat_main_t * vam)
20007 {
20008   unformat_input_t *input = vam->input;
20009   vl_api_sw_interface_span_dump_t *mp;
20010   vl_api_control_ping_t *mp_ping;
20011   u8 is_l2 = 0;
20012   int ret;
20013
20014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20015     {
20016       if (unformat (input, "l2"))
20017         is_l2 = 1;
20018       else
20019         break;
20020     }
20021
20022   M (SW_INTERFACE_SPAN_DUMP, mp);
20023   mp->is_l2 = is_l2;
20024   S (mp);
20025
20026   /* Use a control ping for synchronization */
20027   MPING (CONTROL_PING, mp_ping);
20028   S (mp_ping);
20029
20030   W (ret);
20031   return ret;
20032 }
20033
20034 int
20035 api_pg_create_interface (vat_main_t * vam)
20036 {
20037   unformat_input_t *input = vam->input;
20038   vl_api_pg_create_interface_t *mp;
20039
20040   u32 if_id = ~0;
20041   int ret;
20042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20043     {
20044       if (unformat (input, "if_id %d", &if_id))
20045         ;
20046       else
20047         break;
20048     }
20049   if (if_id == ~0)
20050     {
20051       errmsg ("missing pg interface index");
20052       return -99;
20053     }
20054
20055   /* Construct the API message */
20056   M (PG_CREATE_INTERFACE, mp);
20057   mp->context = 0;
20058   mp->interface_id = ntohl (if_id);
20059
20060   S (mp);
20061   W (ret);
20062   return ret;
20063 }
20064
20065 int
20066 api_pg_capture (vat_main_t * vam)
20067 {
20068   unformat_input_t *input = vam->input;
20069   vl_api_pg_capture_t *mp;
20070
20071   u32 if_id = ~0;
20072   u8 enable = 1;
20073   u32 count = 1;
20074   u8 pcap_file_set = 0;
20075   u8 *pcap_file = 0;
20076   int ret;
20077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20078     {
20079       if (unformat (input, "if_id %d", &if_id))
20080         ;
20081       else if (unformat (input, "pcap %s", &pcap_file))
20082         pcap_file_set = 1;
20083       else if (unformat (input, "count %d", &count))
20084         ;
20085       else if (unformat (input, "disable"))
20086         enable = 0;
20087       else
20088         break;
20089     }
20090   if (if_id == ~0)
20091     {
20092       errmsg ("missing pg interface index");
20093       return -99;
20094     }
20095   if (pcap_file_set > 0)
20096     {
20097       if (vec_len (pcap_file) > 255)
20098         {
20099           errmsg ("pcap file name is too long");
20100           return -99;
20101         }
20102     }
20103
20104   u32 name_len = vec_len (pcap_file);
20105   /* Construct the API message */
20106   M (PG_CAPTURE, mp);
20107   mp->context = 0;
20108   mp->interface_id = ntohl (if_id);
20109   mp->is_enabled = enable;
20110   mp->count = ntohl (count);
20111   mp->pcap_name_length = ntohl (name_len);
20112   if (pcap_file_set != 0)
20113     {
20114       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20115     }
20116   vec_free (pcap_file);
20117
20118   S (mp);
20119   W (ret);
20120   return ret;
20121 }
20122
20123 int
20124 api_pg_enable_disable (vat_main_t * vam)
20125 {
20126   unformat_input_t *input = vam->input;
20127   vl_api_pg_enable_disable_t *mp;
20128
20129   u8 enable = 1;
20130   u8 stream_name_set = 0;
20131   u8 *stream_name = 0;
20132   int ret;
20133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20134     {
20135       if (unformat (input, "stream %s", &stream_name))
20136         stream_name_set = 1;
20137       else if (unformat (input, "disable"))
20138         enable = 0;
20139       else
20140         break;
20141     }
20142
20143   if (stream_name_set > 0)
20144     {
20145       if (vec_len (stream_name) > 255)
20146         {
20147           errmsg ("stream name too long");
20148           return -99;
20149         }
20150     }
20151
20152   u32 name_len = vec_len (stream_name);
20153   /* Construct the API message */
20154   M (PG_ENABLE_DISABLE, mp);
20155   mp->context = 0;
20156   mp->is_enabled = enable;
20157   if (stream_name_set != 0)
20158     {
20159       mp->stream_name_length = ntohl (name_len);
20160       clib_memcpy (mp->stream_name, stream_name, name_len);
20161     }
20162   vec_free (stream_name);
20163
20164   S (mp);
20165   W (ret);
20166   return ret;
20167 }
20168
20169 int
20170 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20171 {
20172   unformat_input_t *input = vam->input;
20173   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20174
20175   u16 *low_ports = 0;
20176   u16 *high_ports = 0;
20177   u16 this_low;
20178   u16 this_hi;
20179   vl_api_prefix_t prefix;
20180   u32 tmp, tmp2;
20181   u8 prefix_set = 0;
20182   u32 vrf_id = ~0;
20183   u8 is_add = 1;
20184   u8 is_ipv6 = 0;
20185   int ret;
20186
20187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20188     {
20189       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20190         prefix_set = 1;
20191       else if (unformat (input, "vrf %d", &vrf_id))
20192         ;
20193       else if (unformat (input, "del"))
20194         is_add = 0;
20195       else if (unformat (input, "port %d", &tmp))
20196         {
20197           if (tmp == 0 || tmp > 65535)
20198             {
20199               errmsg ("port %d out of range", tmp);
20200               return -99;
20201             }
20202           this_low = tmp;
20203           this_hi = this_low + 1;
20204           vec_add1 (low_ports, this_low);
20205           vec_add1 (high_ports, this_hi);
20206         }
20207       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20208         {
20209           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20210             {
20211               errmsg ("incorrect range parameters");
20212               return -99;
20213             }
20214           this_low = tmp;
20215           /* Note: in debug CLI +1 is added to high before
20216              passing to real fn that does "the work"
20217              (ip_source_and_port_range_check_add_del).
20218              This fn is a wrapper around the binary API fn a
20219              control plane will call, which expects this increment
20220              to have occurred. Hence letting the binary API control
20221              plane fn do the increment for consistency between VAT
20222              and other control planes.
20223            */
20224           this_hi = tmp2;
20225           vec_add1 (low_ports, this_low);
20226           vec_add1 (high_ports, this_hi);
20227         }
20228       else
20229         break;
20230     }
20231
20232   if (prefix_set == 0)
20233     {
20234       errmsg ("<address>/<mask> not specified");
20235       return -99;
20236     }
20237
20238   if (vrf_id == ~0)
20239     {
20240       errmsg ("VRF ID required, not specified");
20241       return -99;
20242     }
20243
20244   if (vrf_id == 0)
20245     {
20246       errmsg
20247         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20248       return -99;
20249     }
20250
20251   if (vec_len (low_ports) == 0)
20252     {
20253       errmsg ("At least one port or port range required");
20254       return -99;
20255     }
20256
20257   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20258
20259   mp->is_add = is_add;
20260
20261   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20262
20263   mp->number_of_ranges = vec_len (low_ports);
20264
20265   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20266   vec_free (low_ports);
20267
20268   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20269   vec_free (high_ports);
20270
20271   mp->vrf_id = ntohl (vrf_id);
20272
20273   S (mp);
20274   W (ret);
20275   return ret;
20276 }
20277
20278 int
20279 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20280 {
20281   unformat_input_t *input = vam->input;
20282   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20283   u32 sw_if_index = ~0;
20284   int vrf_set = 0;
20285   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20286   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20287   u8 is_add = 1;
20288   int ret;
20289
20290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20291     {
20292       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20293         ;
20294       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20295         ;
20296       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20297         vrf_set = 1;
20298       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20299         vrf_set = 1;
20300       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20301         vrf_set = 1;
20302       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20303         vrf_set = 1;
20304       else if (unformat (input, "del"))
20305         is_add = 0;
20306       else
20307         break;
20308     }
20309
20310   if (sw_if_index == ~0)
20311     {
20312       errmsg ("Interface required but not specified");
20313       return -99;
20314     }
20315
20316   if (vrf_set == 0)
20317     {
20318       errmsg ("VRF ID required but not specified");
20319       return -99;
20320     }
20321
20322   if (tcp_out_vrf_id == 0
20323       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20324     {
20325       errmsg
20326         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20327       return -99;
20328     }
20329
20330   /* Construct the API message */
20331   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20332
20333   mp->sw_if_index = ntohl (sw_if_index);
20334   mp->is_add = is_add;
20335   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20336   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20337   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20338   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20339
20340   /* send it... */
20341   S (mp);
20342
20343   /* Wait for a reply... */
20344   W (ret);
20345   return ret;
20346 }
20347
20348 static int
20349 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20350 {
20351   unformat_input_t *i = vam->input;
20352   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20353   u32 local_sa_id = 0;
20354   u32 remote_sa_id = 0;
20355   vl_api_ip4_address_t src_address;
20356   vl_api_ip4_address_t dst_address;
20357   u8 is_add = 1;
20358   int ret;
20359
20360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20361     {
20362       if (unformat (i, "local_sa %d", &local_sa_id))
20363         ;
20364       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20365         ;
20366       else
20367         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20368         ;
20369       else
20370         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20371         ;
20372       else if (unformat (i, "del"))
20373         is_add = 0;
20374       else
20375         {
20376           clib_warning ("parse error '%U'", format_unformat_error, i);
20377           return -99;
20378         }
20379     }
20380
20381   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20382
20383   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20384   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20385   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20386   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20387   mp->is_add = is_add;
20388
20389   S (mp);
20390   W (ret);
20391   return ret;
20392 }
20393
20394 static int
20395 api_set_punt (vat_main_t * vam)
20396 {
20397   unformat_input_t *i = vam->input;
20398   vl_api_set_punt_t *mp;
20399   u32 ipv = ~0;
20400   u32 protocol = ~0;
20401   u32 port = ~0;
20402   int is_add = 1;
20403   int ret;
20404
20405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20406     {
20407       if (unformat (i, "ip %d", &ipv))
20408         ;
20409       else if (unformat (i, "protocol %d", &protocol))
20410         ;
20411       else if (unformat (i, "port %d", &port))
20412         ;
20413       else if (unformat (i, "del"))
20414         is_add = 0;
20415       else
20416         {
20417           clib_warning ("parse error '%U'", format_unformat_error, i);
20418           return -99;
20419         }
20420     }
20421
20422   M (SET_PUNT, mp);
20423
20424   mp->is_add = (u8) is_add;
20425   mp->punt.ipv = (u8) ipv;
20426   mp->punt.l4_protocol = (u8) protocol;
20427   mp->punt.l4_port = htons ((u16) port);
20428
20429   S (mp);
20430   W (ret);
20431   return ret;
20432 }
20433
20434 static void vl_api_ipsec_gre_tunnel_details_t_handler
20435   (vl_api_ipsec_gre_tunnel_details_t * mp)
20436 {
20437   vat_main_t *vam = &vat_main;
20438
20439   print (vam->ofp, "%11d%15U%15U%14d%14d",
20440          ntohl (mp->tunnel.sw_if_index),
20441          format_vl_api_ip4_address, mp->tunnel.src,
20442          format_vl_api_ip4_address, mp->tunnel.dst,
20443          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20444 }
20445
20446 static void
20447 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20448                                 const char *name,
20449                                 const vl_api_ip4_address_t addr)
20450 {
20451   struct in_addr ip4;
20452
20453   clib_memcpy (&ip4, addr, sizeof (ip4));
20454   vat_json_object_add_ip4 (node, name, ip4);
20455 }
20456
20457 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20458   (vl_api_ipsec_gre_tunnel_details_t * mp)
20459 {
20460   vat_main_t *vam = &vat_main;
20461   vat_json_node_t *node = NULL;
20462   struct in_addr ip4;
20463
20464   if (VAT_JSON_ARRAY != vam->json_tree.type)
20465     {
20466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20467       vat_json_init_array (&vam->json_tree);
20468     }
20469   node = vat_json_array_add (&vam->json_tree);
20470
20471   vat_json_init_object (node);
20472   vat_json_object_add_uint (node, "sw_if_index",
20473                             ntohl (mp->tunnel.sw_if_index));
20474   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20475   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20476   vat_json_object_add_uint (node, "local_sa_id",
20477                             ntohl (mp->tunnel.local_sa_id));
20478   vat_json_object_add_uint (node, "remote_sa_id",
20479                             ntohl (mp->tunnel.remote_sa_id));
20480 }
20481
20482 static int
20483 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20484 {
20485   unformat_input_t *i = vam->input;
20486   vl_api_ipsec_gre_tunnel_dump_t *mp;
20487   vl_api_control_ping_t *mp_ping;
20488   u32 sw_if_index;
20489   u8 sw_if_index_set = 0;
20490   int ret;
20491
20492   /* Parse args required to build the message */
20493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20494     {
20495       if (unformat (i, "sw_if_index %d", &sw_if_index))
20496         sw_if_index_set = 1;
20497       else
20498         break;
20499     }
20500
20501   if (sw_if_index_set == 0)
20502     {
20503       sw_if_index = ~0;
20504     }
20505
20506   if (!vam->json_output)
20507     {
20508       print (vam->ofp, "%11s%15s%15s%14s%14s",
20509              "sw_if_index", "src_address", "dst_address",
20510              "local_sa_id", "remote_sa_id");
20511     }
20512
20513   /* Get list of gre-tunnel interfaces */
20514   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20515
20516   mp->sw_if_index = htonl (sw_if_index);
20517
20518   S (mp);
20519
20520   /* Use a control ping for synchronization */
20521   MPING (CONTROL_PING, mp_ping);
20522   S (mp_ping);
20523
20524   W (ret);
20525   return ret;
20526 }
20527
20528 static int
20529 api_delete_subif (vat_main_t * vam)
20530 {
20531   unformat_input_t *i = vam->input;
20532   vl_api_delete_subif_t *mp;
20533   u32 sw_if_index = ~0;
20534   int ret;
20535
20536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20537     {
20538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20539         ;
20540       if (unformat (i, "sw_if_index %d", &sw_if_index))
20541         ;
20542       else
20543         break;
20544     }
20545
20546   if (sw_if_index == ~0)
20547     {
20548       errmsg ("missing sw_if_index");
20549       return -99;
20550     }
20551
20552   /* Construct the API message */
20553   M (DELETE_SUBIF, mp);
20554   mp->sw_if_index = ntohl (sw_if_index);
20555
20556   S (mp);
20557   W (ret);
20558   return ret;
20559 }
20560
20561 #define foreach_pbb_vtr_op      \
20562 _("disable",  L2_VTR_DISABLED)  \
20563 _("pop",  L2_VTR_POP_2)         \
20564 _("push",  L2_VTR_PUSH_2)
20565
20566 static int
20567 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20568 {
20569   unformat_input_t *i = vam->input;
20570   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20571   u32 sw_if_index = ~0, vtr_op = ~0;
20572   u16 outer_tag = ~0;
20573   u8 dmac[6], smac[6];
20574   u8 dmac_set = 0, smac_set = 0;
20575   u16 vlanid = 0;
20576   u32 sid = ~0;
20577   u32 tmp;
20578   int ret;
20579
20580   /* Shut up coverity */
20581   clib_memset (dmac, 0, sizeof (dmac));
20582   clib_memset (smac, 0, sizeof (smac));
20583
20584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20585     {
20586       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20587         ;
20588       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20589         ;
20590       else if (unformat (i, "vtr_op %d", &vtr_op))
20591         ;
20592 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20593       foreach_pbb_vtr_op
20594 #undef _
20595         else if (unformat (i, "translate_pbb_stag"))
20596         {
20597           if (unformat (i, "%d", &tmp))
20598             {
20599               vtr_op = L2_VTR_TRANSLATE_2_1;
20600               outer_tag = tmp;
20601             }
20602           else
20603             {
20604               errmsg
20605                 ("translate_pbb_stag operation requires outer tag definition");
20606               return -99;
20607             }
20608         }
20609       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20610         dmac_set++;
20611       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20612         smac_set++;
20613       else if (unformat (i, "sid %d", &sid))
20614         ;
20615       else if (unformat (i, "vlanid %d", &tmp))
20616         vlanid = tmp;
20617       else
20618         {
20619           clib_warning ("parse error '%U'", format_unformat_error, i);
20620           return -99;
20621         }
20622     }
20623
20624   if ((sw_if_index == ~0) || (vtr_op == ~0))
20625     {
20626       errmsg ("missing sw_if_index or vtr operation");
20627       return -99;
20628     }
20629   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20630       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20631     {
20632       errmsg
20633         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20634       return -99;
20635     }
20636
20637   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20638   mp->sw_if_index = ntohl (sw_if_index);
20639   mp->vtr_op = ntohl (vtr_op);
20640   mp->outer_tag = ntohs (outer_tag);
20641   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20642   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20643   mp->b_vlanid = ntohs (vlanid);
20644   mp->i_sid = ntohl (sid);
20645
20646   S (mp);
20647   W (ret);
20648   return ret;
20649 }
20650
20651 static int
20652 api_flow_classify_set_interface (vat_main_t * vam)
20653 {
20654   unformat_input_t *i = vam->input;
20655   vl_api_flow_classify_set_interface_t *mp;
20656   u32 sw_if_index;
20657   int sw_if_index_set;
20658   u32 ip4_table_index = ~0;
20659   u32 ip6_table_index = ~0;
20660   u8 is_add = 1;
20661   int ret;
20662
20663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20664     {
20665       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20666         sw_if_index_set = 1;
20667       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20668         sw_if_index_set = 1;
20669       else if (unformat (i, "del"))
20670         is_add = 0;
20671       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20672         ;
20673       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20674         ;
20675       else
20676         {
20677           clib_warning ("parse error '%U'", format_unformat_error, i);
20678           return -99;
20679         }
20680     }
20681
20682   if (sw_if_index_set == 0)
20683     {
20684       errmsg ("missing interface name or sw_if_index");
20685       return -99;
20686     }
20687
20688   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20689
20690   mp->sw_if_index = ntohl (sw_if_index);
20691   mp->ip4_table_index = ntohl (ip4_table_index);
20692   mp->ip6_table_index = ntohl (ip6_table_index);
20693   mp->is_add = is_add;
20694
20695   S (mp);
20696   W (ret);
20697   return ret;
20698 }
20699
20700 static int
20701 api_flow_classify_dump (vat_main_t * vam)
20702 {
20703   unformat_input_t *i = vam->input;
20704   vl_api_flow_classify_dump_t *mp;
20705   vl_api_control_ping_t *mp_ping;
20706   u8 type = FLOW_CLASSIFY_N_TABLES;
20707   int ret;
20708
20709   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20710     ;
20711   else
20712     {
20713       errmsg ("classify table type must be specified");
20714       return -99;
20715     }
20716
20717   if (!vam->json_output)
20718     {
20719       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20720     }
20721
20722   M (FLOW_CLASSIFY_DUMP, mp);
20723   mp->type = type;
20724   /* send it... */
20725   S (mp);
20726
20727   /* Use a control ping for synchronization */
20728   MPING (CONTROL_PING, mp_ping);
20729   S (mp_ping);
20730
20731   /* Wait for a reply... */
20732   W (ret);
20733   return ret;
20734 }
20735
20736 static int
20737 api_feature_enable_disable (vat_main_t * vam)
20738 {
20739   unformat_input_t *i = vam->input;
20740   vl_api_feature_enable_disable_t *mp;
20741   u8 *arc_name = 0;
20742   u8 *feature_name = 0;
20743   u32 sw_if_index = ~0;
20744   u8 enable = 1;
20745   int ret;
20746
20747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20748     {
20749       if (unformat (i, "arc_name %s", &arc_name))
20750         ;
20751       else if (unformat (i, "feature_name %s", &feature_name))
20752         ;
20753       else
20754         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20755         ;
20756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20757         ;
20758       else if (unformat (i, "disable"))
20759         enable = 0;
20760       else
20761         break;
20762     }
20763
20764   if (arc_name == 0)
20765     {
20766       errmsg ("missing arc name");
20767       return -99;
20768     }
20769   if (vec_len (arc_name) > 63)
20770     {
20771       errmsg ("arc name too long");
20772     }
20773
20774   if (feature_name == 0)
20775     {
20776       errmsg ("missing feature name");
20777       return -99;
20778     }
20779   if (vec_len (feature_name) > 63)
20780     {
20781       errmsg ("feature name too long");
20782     }
20783
20784   if (sw_if_index == ~0)
20785     {
20786       errmsg ("missing interface name or sw_if_index");
20787       return -99;
20788     }
20789
20790   /* Construct the API message */
20791   M (FEATURE_ENABLE_DISABLE, mp);
20792   mp->sw_if_index = ntohl (sw_if_index);
20793   mp->enable = enable;
20794   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20795   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20796   vec_free (arc_name);
20797   vec_free (feature_name);
20798
20799   S (mp);
20800   W (ret);
20801   return ret;
20802 }
20803
20804 static int
20805 api_sw_interface_tag_add_del (vat_main_t * vam)
20806 {
20807   unformat_input_t *i = vam->input;
20808   vl_api_sw_interface_tag_add_del_t *mp;
20809   u32 sw_if_index = ~0;
20810   u8 *tag = 0;
20811   u8 enable = 1;
20812   int ret;
20813
20814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20815     {
20816       if (unformat (i, "tag %s", &tag))
20817         ;
20818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20819         ;
20820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20821         ;
20822       else if (unformat (i, "del"))
20823         enable = 0;
20824       else
20825         break;
20826     }
20827
20828   if (sw_if_index == ~0)
20829     {
20830       errmsg ("missing interface name or sw_if_index");
20831       return -99;
20832     }
20833
20834   if (enable && (tag == 0))
20835     {
20836       errmsg ("no tag specified");
20837       return -99;
20838     }
20839
20840   /* Construct the API message */
20841   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20842   mp->sw_if_index = ntohl (sw_if_index);
20843   mp->is_add = enable;
20844   if (enable)
20845     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20846   vec_free (tag);
20847
20848   S (mp);
20849   W (ret);
20850   return ret;
20851 }
20852
20853 static void vl_api_l2_xconnect_details_t_handler
20854   (vl_api_l2_xconnect_details_t * mp)
20855 {
20856   vat_main_t *vam = &vat_main;
20857
20858   print (vam->ofp, "%15d%15d",
20859          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20860 }
20861
20862 static void vl_api_l2_xconnect_details_t_handler_json
20863   (vl_api_l2_xconnect_details_t * mp)
20864 {
20865   vat_main_t *vam = &vat_main;
20866   vat_json_node_t *node = NULL;
20867
20868   if (VAT_JSON_ARRAY != vam->json_tree.type)
20869     {
20870       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20871       vat_json_init_array (&vam->json_tree);
20872     }
20873   node = vat_json_array_add (&vam->json_tree);
20874
20875   vat_json_init_object (node);
20876   vat_json_object_add_uint (node, "rx_sw_if_index",
20877                             ntohl (mp->rx_sw_if_index));
20878   vat_json_object_add_uint (node, "tx_sw_if_index",
20879                             ntohl (mp->tx_sw_if_index));
20880 }
20881
20882 static int
20883 api_l2_xconnect_dump (vat_main_t * vam)
20884 {
20885   vl_api_l2_xconnect_dump_t *mp;
20886   vl_api_control_ping_t *mp_ping;
20887   int ret;
20888
20889   if (!vam->json_output)
20890     {
20891       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20892     }
20893
20894   M (L2_XCONNECT_DUMP, mp);
20895
20896   S (mp);
20897
20898   /* Use a control ping for synchronization */
20899   MPING (CONTROL_PING, mp_ping);
20900   S (mp_ping);
20901
20902   W (ret);
20903   return ret;
20904 }
20905
20906 static int
20907 api_hw_interface_set_mtu (vat_main_t * vam)
20908 {
20909   unformat_input_t *i = vam->input;
20910   vl_api_hw_interface_set_mtu_t *mp;
20911   u32 sw_if_index = ~0;
20912   u32 mtu = 0;
20913   int ret;
20914
20915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20916     {
20917       if (unformat (i, "mtu %d", &mtu))
20918         ;
20919       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20920         ;
20921       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20922         ;
20923       else
20924         break;
20925     }
20926
20927   if (sw_if_index == ~0)
20928     {
20929       errmsg ("missing interface name or sw_if_index");
20930       return -99;
20931     }
20932
20933   if (mtu == 0)
20934     {
20935       errmsg ("no mtu specified");
20936       return -99;
20937     }
20938
20939   /* Construct the API message */
20940   M (HW_INTERFACE_SET_MTU, mp);
20941   mp->sw_if_index = ntohl (sw_if_index);
20942   mp->mtu = ntohs ((u16) mtu);
20943
20944   S (mp);
20945   W (ret);
20946   return ret;
20947 }
20948
20949 static int
20950 api_p2p_ethernet_add (vat_main_t * vam)
20951 {
20952   unformat_input_t *i = vam->input;
20953   vl_api_p2p_ethernet_add_t *mp;
20954   u32 parent_if_index = ~0;
20955   u32 sub_id = ~0;
20956   u8 remote_mac[6];
20957   u8 mac_set = 0;
20958   int ret;
20959
20960   clib_memset (remote_mac, 0, sizeof (remote_mac));
20961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20962     {
20963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20964         ;
20965       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20966         ;
20967       else
20968         if (unformat
20969             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20970         mac_set++;
20971       else if (unformat (i, "sub_id %d", &sub_id))
20972         ;
20973       else
20974         {
20975           clib_warning ("parse error '%U'", format_unformat_error, i);
20976           return -99;
20977         }
20978     }
20979
20980   if (parent_if_index == ~0)
20981     {
20982       errmsg ("missing interface name or sw_if_index");
20983       return -99;
20984     }
20985   if (mac_set == 0)
20986     {
20987       errmsg ("missing remote mac address");
20988       return -99;
20989     }
20990   if (sub_id == ~0)
20991     {
20992       errmsg ("missing sub-interface id");
20993       return -99;
20994     }
20995
20996   M (P2P_ETHERNET_ADD, mp);
20997   mp->parent_if_index = ntohl (parent_if_index);
20998   mp->subif_id = ntohl (sub_id);
20999   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21000
21001   S (mp);
21002   W (ret);
21003   return ret;
21004 }
21005
21006 static int
21007 api_p2p_ethernet_del (vat_main_t * vam)
21008 {
21009   unformat_input_t *i = vam->input;
21010   vl_api_p2p_ethernet_del_t *mp;
21011   u32 parent_if_index = ~0;
21012   u8 remote_mac[6];
21013   u8 mac_set = 0;
21014   int ret;
21015
21016   clib_memset (remote_mac, 0, sizeof (remote_mac));
21017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21018     {
21019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21020         ;
21021       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21022         ;
21023       else
21024         if (unformat
21025             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21026         mac_set++;
21027       else
21028         {
21029           clib_warning ("parse error '%U'", format_unformat_error, i);
21030           return -99;
21031         }
21032     }
21033
21034   if (parent_if_index == ~0)
21035     {
21036       errmsg ("missing interface name or sw_if_index");
21037       return -99;
21038     }
21039   if (mac_set == 0)
21040     {
21041       errmsg ("missing remote mac address");
21042       return -99;
21043     }
21044
21045   M (P2P_ETHERNET_DEL, mp);
21046   mp->parent_if_index = ntohl (parent_if_index);
21047   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21048
21049   S (mp);
21050   W (ret);
21051   return ret;
21052 }
21053
21054 static int
21055 api_lldp_config (vat_main_t * vam)
21056 {
21057   unformat_input_t *i = vam->input;
21058   vl_api_lldp_config_t *mp;
21059   int tx_hold = 0;
21060   int tx_interval = 0;
21061   u8 *sys_name = NULL;
21062   int ret;
21063
21064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21065     {
21066       if (unformat (i, "system-name %s", &sys_name))
21067         ;
21068       else if (unformat (i, "tx-hold %d", &tx_hold))
21069         ;
21070       else if (unformat (i, "tx-interval %d", &tx_interval))
21071         ;
21072       else
21073         {
21074           clib_warning ("parse error '%U'", format_unformat_error, i);
21075           return -99;
21076         }
21077     }
21078
21079   vec_add1 (sys_name, 0);
21080
21081   M (LLDP_CONFIG, mp);
21082   mp->tx_hold = htonl (tx_hold);
21083   mp->tx_interval = htonl (tx_interval);
21084   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21085   vec_free (sys_name);
21086
21087   S (mp);
21088   W (ret);
21089   return ret;
21090 }
21091
21092 static int
21093 api_sw_interface_set_lldp (vat_main_t * vam)
21094 {
21095   unformat_input_t *i = vam->input;
21096   vl_api_sw_interface_set_lldp_t *mp;
21097   u32 sw_if_index = ~0;
21098   u32 enable = 1;
21099   u8 *port_desc = NULL, *mgmt_oid = NULL;
21100   ip4_address_t ip4_addr;
21101   ip6_address_t ip6_addr;
21102   int ret;
21103
21104   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21105   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21106
21107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21108     {
21109       if (unformat (i, "disable"))
21110         enable = 0;
21111       else
21112         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21113         ;
21114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21115         ;
21116       else if (unformat (i, "port-desc %s", &port_desc))
21117         ;
21118       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21119         ;
21120       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21121         ;
21122       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21123         ;
21124       else
21125         break;
21126     }
21127
21128   if (sw_if_index == ~0)
21129     {
21130       errmsg ("missing interface name or sw_if_index");
21131       return -99;
21132     }
21133
21134   /* Construct the API message */
21135   vec_add1 (port_desc, 0);
21136   vec_add1 (mgmt_oid, 0);
21137   M (SW_INTERFACE_SET_LLDP, mp);
21138   mp->sw_if_index = ntohl (sw_if_index);
21139   mp->enable = enable;
21140   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21141   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21142   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21143   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21144   vec_free (port_desc);
21145   vec_free (mgmt_oid);
21146
21147   S (mp);
21148   W (ret);
21149   return ret;
21150 }
21151
21152 static int
21153 api_tcp_configure_src_addresses (vat_main_t * vam)
21154 {
21155   vl_api_tcp_configure_src_addresses_t *mp;
21156   unformat_input_t *i = vam->input;
21157   ip4_address_t v4first, v4last;
21158   ip6_address_t v6first, v6last;
21159   u8 range_set = 0;
21160   u32 vrf_id = 0;
21161   int ret;
21162
21163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21164     {
21165       if (unformat (i, "%U - %U",
21166                     unformat_ip4_address, &v4first,
21167                     unformat_ip4_address, &v4last))
21168         {
21169           if (range_set)
21170             {
21171               errmsg ("one range per message (range already set)");
21172               return -99;
21173             }
21174           range_set = 1;
21175         }
21176       else if (unformat (i, "%U - %U",
21177                          unformat_ip6_address, &v6first,
21178                          unformat_ip6_address, &v6last))
21179         {
21180           if (range_set)
21181             {
21182               errmsg ("one range per message (range already set)");
21183               return -99;
21184             }
21185           range_set = 2;
21186         }
21187       else if (unformat (i, "vrf %d", &vrf_id))
21188         ;
21189       else
21190         break;
21191     }
21192
21193   if (range_set == 0)
21194     {
21195       errmsg ("address range not set");
21196       return -99;
21197     }
21198
21199   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21200   mp->vrf_id = ntohl (vrf_id);
21201   /* ipv6? */
21202   if (range_set == 2)
21203     {
21204       mp->is_ipv6 = 1;
21205       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21206       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21207     }
21208   else
21209     {
21210       mp->is_ipv6 = 0;
21211       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21212       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21213     }
21214   S (mp);
21215   W (ret);
21216   return ret;
21217 }
21218
21219 static void vl_api_app_namespace_add_del_reply_t_handler
21220   (vl_api_app_namespace_add_del_reply_t * mp)
21221 {
21222   vat_main_t *vam = &vat_main;
21223   i32 retval = ntohl (mp->retval);
21224   if (vam->async_mode)
21225     {
21226       vam->async_errors += (retval < 0);
21227     }
21228   else
21229     {
21230       vam->retval = retval;
21231       if (retval == 0)
21232         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21233       vam->result_ready = 1;
21234     }
21235 }
21236
21237 static void vl_api_app_namespace_add_del_reply_t_handler_json
21238   (vl_api_app_namespace_add_del_reply_t * mp)
21239 {
21240   vat_main_t *vam = &vat_main;
21241   vat_json_node_t node;
21242
21243   vat_json_init_object (&node);
21244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21245   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21246
21247   vat_json_print (vam->ofp, &node);
21248   vat_json_free (&node);
21249
21250   vam->retval = ntohl (mp->retval);
21251   vam->result_ready = 1;
21252 }
21253
21254 static int
21255 api_app_namespace_add_del (vat_main_t * vam)
21256 {
21257   vl_api_app_namespace_add_del_t *mp;
21258   unformat_input_t *i = vam->input;
21259   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21260   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21261   u64 secret;
21262   int ret;
21263
21264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21265     {
21266       if (unformat (i, "id %_%v%_", &ns_id))
21267         ;
21268       else if (unformat (i, "secret %lu", &secret))
21269         secret_set = 1;
21270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21271         sw_if_index_set = 1;
21272       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21273         ;
21274       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21275         ;
21276       else
21277         break;
21278     }
21279   if (!ns_id || !secret_set || !sw_if_index_set)
21280     {
21281       errmsg ("namespace id, secret and sw_if_index must be set");
21282       return -99;
21283     }
21284   if (vec_len (ns_id) > 64)
21285     {
21286       errmsg ("namespace id too long");
21287       return -99;
21288     }
21289   M (APP_NAMESPACE_ADD_DEL, mp);
21290
21291   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21292   mp->namespace_id_len = vec_len (ns_id);
21293   mp->secret = clib_host_to_net_u64 (secret);
21294   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21295   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21296   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21297   vec_free (ns_id);
21298   S (mp);
21299   W (ret);
21300   return ret;
21301 }
21302
21303 static int
21304 api_sock_init_shm (vat_main_t * vam)
21305 {
21306 #if VPP_API_TEST_BUILTIN == 0
21307   unformat_input_t *i = vam->input;
21308   vl_api_shm_elem_config_t *config = 0;
21309   u64 size = 64 << 20;
21310   int rv;
21311
21312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21313     {
21314       if (unformat (i, "size %U", unformat_memory_size, &size))
21315         ;
21316       else
21317         break;
21318     }
21319
21320   /*
21321    * Canned custom ring allocator config.
21322    * Should probably parse all of this
21323    */
21324   vec_validate (config, 6);
21325   config[0].type = VL_API_VLIB_RING;
21326   config[0].size = 256;
21327   config[0].count = 32;
21328
21329   config[1].type = VL_API_VLIB_RING;
21330   config[1].size = 1024;
21331   config[1].count = 16;
21332
21333   config[2].type = VL_API_VLIB_RING;
21334   config[2].size = 4096;
21335   config[2].count = 2;
21336
21337   config[3].type = VL_API_CLIENT_RING;
21338   config[3].size = 256;
21339   config[3].count = 32;
21340
21341   config[4].type = VL_API_CLIENT_RING;
21342   config[4].size = 1024;
21343   config[4].count = 16;
21344
21345   config[5].type = VL_API_CLIENT_RING;
21346   config[5].size = 4096;
21347   config[5].count = 2;
21348
21349   config[6].type = VL_API_QUEUE;
21350   config[6].count = 128;
21351   config[6].size = sizeof (uword);
21352
21353   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21354   if (!rv)
21355     vam->client_index_invalid = 1;
21356   return rv;
21357 #else
21358   return -99;
21359 #endif
21360 }
21361
21362 static int
21363 api_dns_enable_disable (vat_main_t * vam)
21364 {
21365   unformat_input_t *line_input = vam->input;
21366   vl_api_dns_enable_disable_t *mp;
21367   u8 enable_disable = 1;
21368   int ret;
21369
21370   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21371     {
21372       if (unformat (line_input, "disable"))
21373         enable_disable = 0;
21374       if (unformat (line_input, "enable"))
21375         enable_disable = 1;
21376       else
21377         break;
21378     }
21379
21380   /* Construct the API message */
21381   M (DNS_ENABLE_DISABLE, mp);
21382   mp->enable = enable_disable;
21383
21384   /* send it... */
21385   S (mp);
21386   /* Wait for the reply */
21387   W (ret);
21388   return ret;
21389 }
21390
21391 static int
21392 api_dns_resolve_name (vat_main_t * vam)
21393 {
21394   unformat_input_t *line_input = vam->input;
21395   vl_api_dns_resolve_name_t *mp;
21396   u8 *name = 0;
21397   int ret;
21398
21399   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21400     {
21401       if (unformat (line_input, "%s", &name))
21402         ;
21403       else
21404         break;
21405     }
21406
21407   if (vec_len (name) > 127)
21408     {
21409       errmsg ("name too long");
21410       return -99;
21411     }
21412
21413   /* Construct the API message */
21414   M (DNS_RESOLVE_NAME, mp);
21415   memcpy (mp->name, name, vec_len (name));
21416   vec_free (name);
21417
21418   /* send it... */
21419   S (mp);
21420   /* Wait for the reply */
21421   W (ret);
21422   return ret;
21423 }
21424
21425 static int
21426 api_dns_resolve_ip (vat_main_t * vam)
21427 {
21428   unformat_input_t *line_input = vam->input;
21429   vl_api_dns_resolve_ip_t *mp;
21430   int is_ip6 = -1;
21431   ip4_address_t addr4;
21432   ip6_address_t addr6;
21433   int ret;
21434
21435   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21436     {
21437       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21438         is_ip6 = 1;
21439       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21440         is_ip6 = 0;
21441       else
21442         break;
21443     }
21444
21445   if (is_ip6 == -1)
21446     {
21447       errmsg ("missing address");
21448       return -99;
21449     }
21450
21451   /* Construct the API message */
21452   M (DNS_RESOLVE_IP, mp);
21453   mp->is_ip6 = is_ip6;
21454   if (is_ip6)
21455     memcpy (mp->address, &addr6, sizeof (addr6));
21456   else
21457     memcpy (mp->address, &addr4, sizeof (addr4));
21458
21459   /* send it... */
21460   S (mp);
21461   /* Wait for the reply */
21462   W (ret);
21463   return ret;
21464 }
21465
21466 static int
21467 api_dns_name_server_add_del (vat_main_t * vam)
21468 {
21469   unformat_input_t *i = vam->input;
21470   vl_api_dns_name_server_add_del_t *mp;
21471   u8 is_add = 1;
21472   ip6_address_t ip6_server;
21473   ip4_address_t ip4_server;
21474   int ip6_set = 0;
21475   int ip4_set = 0;
21476   int ret = 0;
21477
21478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21479     {
21480       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21481         ip6_set = 1;
21482       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21483         ip4_set = 1;
21484       else if (unformat (i, "del"))
21485         is_add = 0;
21486       else
21487         {
21488           clib_warning ("parse error '%U'", format_unformat_error, i);
21489           return -99;
21490         }
21491     }
21492
21493   if (ip4_set && ip6_set)
21494     {
21495       errmsg ("Only one server address allowed per message");
21496       return -99;
21497     }
21498   if ((ip4_set + ip6_set) == 0)
21499     {
21500       errmsg ("Server address required");
21501       return -99;
21502     }
21503
21504   /* Construct the API message */
21505   M (DNS_NAME_SERVER_ADD_DEL, mp);
21506
21507   if (ip6_set)
21508     {
21509       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21510       mp->is_ip6 = 1;
21511     }
21512   else
21513     {
21514       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21515       mp->is_ip6 = 0;
21516     }
21517
21518   mp->is_add = is_add;
21519
21520   /* send it... */
21521   S (mp);
21522
21523   /* Wait for a reply, return good/bad news  */
21524   W (ret);
21525   return ret;
21526 }
21527
21528 static void
21529 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21530 {
21531   vat_main_t *vam = &vat_main;
21532
21533   if (mp->is_ip4)
21534     {
21535       print (vam->ofp,
21536              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21537              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21538              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21539              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21540              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21541              clib_net_to_host_u32 (mp->action_index), mp->tag);
21542     }
21543   else
21544     {
21545       print (vam->ofp,
21546              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21547              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21548              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21549              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21550              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21551              clib_net_to_host_u32 (mp->action_index), mp->tag);
21552     }
21553 }
21554
21555 static void
21556 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21557                                              mp)
21558 {
21559   vat_main_t *vam = &vat_main;
21560   vat_json_node_t *node = NULL;
21561   struct in6_addr ip6;
21562   struct in_addr ip4;
21563
21564   if (VAT_JSON_ARRAY != vam->json_tree.type)
21565     {
21566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21567       vat_json_init_array (&vam->json_tree);
21568     }
21569   node = vat_json_array_add (&vam->json_tree);
21570   vat_json_init_object (node);
21571
21572   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21573   vat_json_object_add_uint (node, "appns_index",
21574                             clib_net_to_host_u32 (mp->appns_index));
21575   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21576   vat_json_object_add_uint (node, "scope", mp->scope);
21577   vat_json_object_add_uint (node, "action_index",
21578                             clib_net_to_host_u32 (mp->action_index));
21579   vat_json_object_add_uint (node, "lcl_port",
21580                             clib_net_to_host_u16 (mp->lcl_port));
21581   vat_json_object_add_uint (node, "rmt_port",
21582                             clib_net_to_host_u16 (mp->rmt_port));
21583   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21584   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21585   vat_json_object_add_string_copy (node, "tag", mp->tag);
21586   if (mp->is_ip4)
21587     {
21588       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21589       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21590       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21591       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21592     }
21593   else
21594     {
21595       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21596       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21597       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21598       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21599     }
21600 }
21601
21602 static int
21603 api_session_rule_add_del (vat_main_t * vam)
21604 {
21605   vl_api_session_rule_add_del_t *mp;
21606   unformat_input_t *i = vam->input;
21607   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21608   u32 appns_index = 0, scope = 0;
21609   ip4_address_t lcl_ip4, rmt_ip4;
21610   ip6_address_t lcl_ip6, rmt_ip6;
21611   u8 is_ip4 = 1, conn_set = 0;
21612   u8 is_add = 1, *tag = 0;
21613   int ret;
21614
21615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21616     {
21617       if (unformat (i, "del"))
21618         is_add = 0;
21619       else if (unformat (i, "add"))
21620         ;
21621       else if (unformat (i, "proto tcp"))
21622         proto = 0;
21623       else if (unformat (i, "proto udp"))
21624         proto = 1;
21625       else if (unformat (i, "appns %d", &appns_index))
21626         ;
21627       else if (unformat (i, "scope %d", &scope))
21628         ;
21629       else if (unformat (i, "tag %_%v%_", &tag))
21630         ;
21631       else
21632         if (unformat
21633             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21634              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21635              &rmt_port))
21636         {
21637           is_ip4 = 1;
21638           conn_set = 1;
21639         }
21640       else
21641         if (unformat
21642             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21643              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21644              &rmt_port))
21645         {
21646           is_ip4 = 0;
21647           conn_set = 1;
21648         }
21649       else if (unformat (i, "action %d", &action))
21650         ;
21651       else
21652         break;
21653     }
21654   if (proto == ~0 || !conn_set || action == ~0)
21655     {
21656       errmsg ("transport proto, connection and action must be set");
21657       return -99;
21658     }
21659
21660   if (scope > 3)
21661     {
21662       errmsg ("scope should be 0-3");
21663       return -99;
21664     }
21665
21666   M (SESSION_RULE_ADD_DEL, mp);
21667
21668   mp->is_ip4 = is_ip4;
21669   mp->transport_proto = proto;
21670   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21671   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21672   mp->lcl_plen = lcl_plen;
21673   mp->rmt_plen = rmt_plen;
21674   mp->action_index = clib_host_to_net_u32 (action);
21675   mp->appns_index = clib_host_to_net_u32 (appns_index);
21676   mp->scope = scope;
21677   mp->is_add = is_add;
21678   if (is_ip4)
21679     {
21680       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21681       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21682     }
21683   else
21684     {
21685       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21686       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21687     }
21688   if (tag)
21689     {
21690       clib_memcpy (mp->tag, tag, vec_len (tag));
21691       vec_free (tag);
21692     }
21693
21694   S (mp);
21695   W (ret);
21696   return ret;
21697 }
21698
21699 static int
21700 api_session_rules_dump (vat_main_t * vam)
21701 {
21702   vl_api_session_rules_dump_t *mp;
21703   vl_api_control_ping_t *mp_ping;
21704   int ret;
21705
21706   if (!vam->json_output)
21707     {
21708       print (vam->ofp, "%=20s", "Session Rules");
21709     }
21710
21711   M (SESSION_RULES_DUMP, mp);
21712   /* send it... */
21713   S (mp);
21714
21715   /* Use a control ping for synchronization */
21716   MPING (CONTROL_PING, mp_ping);
21717   S (mp_ping);
21718
21719   /* Wait for a reply... */
21720   W (ret);
21721   return ret;
21722 }
21723
21724 static int
21725 api_ip_container_proxy_add_del (vat_main_t * vam)
21726 {
21727   vl_api_ip_container_proxy_add_del_t *mp;
21728   unformat_input_t *i = vam->input;
21729   u32 sw_if_index = ~0;
21730   vl_api_prefix_t pfx = { };
21731   u8 is_add = 1;
21732   int ret;
21733
21734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21735     {
21736       if (unformat (i, "del"))
21737         is_add = 0;
21738       else if (unformat (i, "add"))
21739         ;
21740       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21741         ;
21742       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21743         ;
21744       else
21745         break;
21746     }
21747   if (sw_if_index == ~0 || pfx.address_length == 0)
21748     {
21749       errmsg ("address and sw_if_index must be set");
21750       return -99;
21751     }
21752
21753   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21754
21755   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21756   mp->is_add = is_add;
21757   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21758
21759   S (mp);
21760   W (ret);
21761   return ret;
21762 }
21763
21764 static int
21765 api_qos_record_enable_disable (vat_main_t * vam)
21766 {
21767   unformat_input_t *i = vam->input;
21768   vl_api_qos_record_enable_disable_t *mp;
21769   u32 sw_if_index, qs = 0xff;
21770   u8 sw_if_index_set = 0;
21771   u8 enable = 1;
21772   int ret;
21773
21774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21775     {
21776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21777         sw_if_index_set = 1;
21778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21779         sw_if_index_set = 1;
21780       else if (unformat (i, "%U", unformat_qos_source, &qs))
21781         ;
21782       else if (unformat (i, "disable"))
21783         enable = 0;
21784       else
21785         {
21786           clib_warning ("parse error '%U'", format_unformat_error, i);
21787           return -99;
21788         }
21789     }
21790
21791   if (sw_if_index_set == 0)
21792     {
21793       errmsg ("missing interface name or sw_if_index");
21794       return -99;
21795     }
21796   if (qs == 0xff)
21797     {
21798       errmsg ("input location must be specified");
21799       return -99;
21800     }
21801
21802   M (QOS_RECORD_ENABLE_DISABLE, mp);
21803
21804   mp->sw_if_index = ntohl (sw_if_index);
21805   mp->input_source = qs;
21806   mp->enable = enable;
21807
21808   S (mp);
21809   W (ret);
21810   return ret;
21811 }
21812
21813
21814 static int
21815 q_or_quit (vat_main_t * vam)
21816 {
21817 #if VPP_API_TEST_BUILTIN == 0
21818   longjmp (vam->jump_buf, 1);
21819 #endif
21820   return 0;                     /* not so much */
21821 }
21822
21823 static int
21824 q (vat_main_t * vam)
21825 {
21826   return q_or_quit (vam);
21827 }
21828
21829 static int
21830 quit (vat_main_t * vam)
21831 {
21832   return q_or_quit (vam);
21833 }
21834
21835 static int
21836 comment (vat_main_t * vam)
21837 {
21838   return 0;
21839 }
21840
21841 static int
21842 statseg (vat_main_t * vam)
21843 {
21844   ssvm_private_t *ssvmp = &vam->stat_segment;
21845   ssvm_shared_header_t *shared_header = ssvmp->sh;
21846   vlib_counter_t **counters;
21847   u64 thread0_index1_packets;
21848   u64 thread0_index1_bytes;
21849   f64 vector_rate, input_rate;
21850   uword *p;
21851
21852   uword *counter_vector_by_name;
21853   if (vam->stat_segment_lockp == 0)
21854     {
21855       errmsg ("Stat segment not mapped...");
21856       return -99;
21857     }
21858
21859   /* look up "/if/rx for sw_if_index 1 as a test */
21860
21861   clib_spinlock_lock (vam->stat_segment_lockp);
21862
21863   counter_vector_by_name = (uword *) shared_header->opaque[1];
21864
21865   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21866   if (p == 0)
21867     {
21868       clib_spinlock_unlock (vam->stat_segment_lockp);
21869       errmsg ("/if/tx not found?");
21870       return -99;
21871     }
21872
21873   /* Fish per-thread vector of combined counters from shared memory */
21874   counters = (vlib_counter_t **) p[0];
21875
21876   if (vec_len (counters[0]) < 2)
21877     {
21878       clib_spinlock_unlock (vam->stat_segment_lockp);
21879       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21880       return -99;
21881     }
21882
21883   /* Read thread 0 sw_if_index 1 counter */
21884   thread0_index1_packets = counters[0][1].packets;
21885   thread0_index1_bytes = counters[0][1].bytes;
21886
21887   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21888   if (p == 0)
21889     {
21890       clib_spinlock_unlock (vam->stat_segment_lockp);
21891       errmsg ("vector_rate not found?");
21892       return -99;
21893     }
21894
21895   vector_rate = *(f64 *) (p[0]);
21896   p = hash_get_mem (counter_vector_by_name, "input_rate");
21897   if (p == 0)
21898     {
21899       clib_spinlock_unlock (vam->stat_segment_lockp);
21900       errmsg ("input_rate not found?");
21901       return -99;
21902     }
21903   input_rate = *(f64 *) (p[0]);
21904
21905   clib_spinlock_unlock (vam->stat_segment_lockp);
21906
21907   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21908          vector_rate, input_rate);
21909   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21910          thread0_index1_packets, thread0_index1_bytes);
21911
21912   return 0;
21913 }
21914
21915 static int
21916 cmd_cmp (void *a1, void *a2)
21917 {
21918   u8 **c1 = a1;
21919   u8 **c2 = a2;
21920
21921   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21922 }
21923
21924 static int
21925 help (vat_main_t * vam)
21926 {
21927   u8 **cmds = 0;
21928   u8 *name = 0;
21929   hash_pair_t *p;
21930   unformat_input_t *i = vam->input;
21931   int j;
21932
21933   if (unformat (i, "%s", &name))
21934     {
21935       uword *hs;
21936
21937       vec_add1 (name, 0);
21938
21939       hs = hash_get_mem (vam->help_by_name, name);
21940       if (hs)
21941         print (vam->ofp, "usage: %s %s", name, hs[0]);
21942       else
21943         print (vam->ofp, "No such msg / command '%s'", name);
21944       vec_free (name);
21945       return 0;
21946     }
21947
21948   print (vam->ofp, "Help is available for the following:");
21949
21950     /* *INDENT-OFF* */
21951     hash_foreach_pair (p, vam->function_by_name,
21952     ({
21953       vec_add1 (cmds, (u8 *)(p->key));
21954     }));
21955     /* *INDENT-ON* */
21956
21957   vec_sort_with_function (cmds, cmd_cmp);
21958
21959   for (j = 0; j < vec_len (cmds); j++)
21960     print (vam->ofp, "%s", cmds[j]);
21961
21962   vec_free (cmds);
21963   return 0;
21964 }
21965
21966 static int
21967 set (vat_main_t * vam)
21968 {
21969   u8 *name = 0, *value = 0;
21970   unformat_input_t *i = vam->input;
21971
21972   if (unformat (i, "%s", &name))
21973     {
21974       /* The input buffer is a vector, not a string. */
21975       value = vec_dup (i->buffer);
21976       vec_delete (value, i->index, 0);
21977       /* Almost certainly has a trailing newline */
21978       if (value[vec_len (value) - 1] == '\n')
21979         value[vec_len (value) - 1] = 0;
21980       /* Make sure it's a proper string, one way or the other */
21981       vec_add1 (value, 0);
21982       (void) clib_macro_set_value (&vam->macro_main,
21983                                    (char *) name, (char *) value);
21984     }
21985   else
21986     errmsg ("usage: set <name> <value>");
21987
21988   vec_free (name);
21989   vec_free (value);
21990   return 0;
21991 }
21992
21993 static int
21994 unset (vat_main_t * vam)
21995 {
21996   u8 *name = 0;
21997
21998   if (unformat (vam->input, "%s", &name))
21999     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22000       errmsg ("unset: %s wasn't set", name);
22001   vec_free (name);
22002   return 0;
22003 }
22004
22005 typedef struct
22006 {
22007   u8 *name;
22008   u8 *value;
22009 } macro_sort_t;
22010
22011
22012 static int
22013 macro_sort_cmp (void *a1, void *a2)
22014 {
22015   macro_sort_t *s1 = a1;
22016   macro_sort_t *s2 = a2;
22017
22018   return strcmp ((char *) (s1->name), (char *) (s2->name));
22019 }
22020
22021 static int
22022 dump_macro_table (vat_main_t * vam)
22023 {
22024   macro_sort_t *sort_me = 0, *sm;
22025   int i;
22026   hash_pair_t *p;
22027
22028     /* *INDENT-OFF* */
22029     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22030     ({
22031       vec_add2 (sort_me, sm, 1);
22032       sm->name = (u8 *)(p->key);
22033       sm->value = (u8 *) (p->value[0]);
22034     }));
22035     /* *INDENT-ON* */
22036
22037   vec_sort_with_function (sort_me, macro_sort_cmp);
22038
22039   if (vec_len (sort_me))
22040     print (vam->ofp, "%-15s%s", "Name", "Value");
22041   else
22042     print (vam->ofp, "The macro table is empty...");
22043
22044   for (i = 0; i < vec_len (sort_me); i++)
22045     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22046   return 0;
22047 }
22048
22049 static int
22050 dump_node_table (vat_main_t * vam)
22051 {
22052   int i, j;
22053   vlib_node_t *node, *next_node;
22054
22055   if (vec_len (vam->graph_nodes) == 0)
22056     {
22057       print (vam->ofp, "Node table empty, issue get_node_graph...");
22058       return 0;
22059     }
22060
22061   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22062     {
22063       node = vam->graph_nodes[0][i];
22064       print (vam->ofp, "[%d] %s", i, node->name);
22065       for (j = 0; j < vec_len (node->next_nodes); j++)
22066         {
22067           if (node->next_nodes[j] != ~0)
22068             {
22069               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22070               print (vam->ofp, "  [%d] %s", j, next_node->name);
22071             }
22072         }
22073     }
22074   return 0;
22075 }
22076
22077 static int
22078 value_sort_cmp (void *a1, void *a2)
22079 {
22080   name_sort_t *n1 = a1;
22081   name_sort_t *n2 = a2;
22082
22083   if (n1->value < n2->value)
22084     return -1;
22085   if (n1->value > n2->value)
22086     return 1;
22087   return 0;
22088 }
22089
22090
22091 static int
22092 dump_msg_api_table (vat_main_t * vam)
22093 {
22094   api_main_t *am = &api_main;
22095   name_sort_t *nses = 0, *ns;
22096   hash_pair_t *hp;
22097   int i;
22098
22099   /* *INDENT-OFF* */
22100   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22101   ({
22102     vec_add2 (nses, ns, 1);
22103     ns->name = (u8 *)(hp->key);
22104     ns->value = (u32) hp->value[0];
22105   }));
22106   /* *INDENT-ON* */
22107
22108   vec_sort_with_function (nses, value_sort_cmp);
22109
22110   for (i = 0; i < vec_len (nses); i++)
22111     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22112   vec_free (nses);
22113   return 0;
22114 }
22115
22116 static int
22117 get_msg_id (vat_main_t * vam)
22118 {
22119   u8 *name_and_crc;
22120   u32 message_index;
22121
22122   if (unformat (vam->input, "%s", &name_and_crc))
22123     {
22124       message_index = vl_msg_api_get_msg_index (name_and_crc);
22125       if (message_index == ~0)
22126         {
22127           print (vam->ofp, " '%s' not found", name_and_crc);
22128           return 0;
22129         }
22130       print (vam->ofp, " '%s' has message index %d",
22131              name_and_crc, message_index);
22132       return 0;
22133     }
22134   errmsg ("name_and_crc required...");
22135   return 0;
22136 }
22137
22138 static int
22139 search_node_table (vat_main_t * vam)
22140 {
22141   unformat_input_t *line_input = vam->input;
22142   u8 *node_to_find;
22143   int j;
22144   vlib_node_t *node, *next_node;
22145   uword *p;
22146
22147   if (vam->graph_node_index_by_name == 0)
22148     {
22149       print (vam->ofp, "Node table empty, issue get_node_graph...");
22150       return 0;
22151     }
22152
22153   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22154     {
22155       if (unformat (line_input, "%s", &node_to_find))
22156         {
22157           vec_add1 (node_to_find, 0);
22158           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22159           if (p == 0)
22160             {
22161               print (vam->ofp, "%s not found...", node_to_find);
22162               goto out;
22163             }
22164           node = vam->graph_nodes[0][p[0]];
22165           print (vam->ofp, "[%d] %s", p[0], node->name);
22166           for (j = 0; j < vec_len (node->next_nodes); j++)
22167             {
22168               if (node->next_nodes[j] != ~0)
22169                 {
22170                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22171                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22172                 }
22173             }
22174         }
22175
22176       else
22177         {
22178           clib_warning ("parse error '%U'", format_unformat_error,
22179                         line_input);
22180           return -99;
22181         }
22182
22183     out:
22184       vec_free (node_to_find);
22185
22186     }
22187
22188   return 0;
22189 }
22190
22191
22192 static int
22193 script (vat_main_t * vam)
22194 {
22195 #if (VPP_API_TEST_BUILTIN==0)
22196   u8 *s = 0;
22197   char *save_current_file;
22198   unformat_input_t save_input;
22199   jmp_buf save_jump_buf;
22200   u32 save_line_number;
22201
22202   FILE *new_fp, *save_ifp;
22203
22204   if (unformat (vam->input, "%s", &s))
22205     {
22206       new_fp = fopen ((char *) s, "r");
22207       if (new_fp == 0)
22208         {
22209           errmsg ("Couldn't open script file %s", s);
22210           vec_free (s);
22211           return -99;
22212         }
22213     }
22214   else
22215     {
22216       errmsg ("Missing script name");
22217       return -99;
22218     }
22219
22220   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22221   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22222   save_ifp = vam->ifp;
22223   save_line_number = vam->input_line_number;
22224   save_current_file = (char *) vam->current_file;
22225
22226   vam->input_line_number = 0;
22227   vam->ifp = new_fp;
22228   vam->current_file = s;
22229   do_one_file (vam);
22230
22231   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22232   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22233   vam->ifp = save_ifp;
22234   vam->input_line_number = save_line_number;
22235   vam->current_file = (u8 *) save_current_file;
22236   vec_free (s);
22237
22238   return 0;
22239 #else
22240   clib_warning ("use the exec command...");
22241   return -99;
22242 #endif
22243 }
22244
22245 static int
22246 echo (vat_main_t * vam)
22247 {
22248   print (vam->ofp, "%v", vam->input->buffer);
22249   return 0;
22250 }
22251
22252 /* List of API message constructors, CLI names map to api_xxx */
22253 #define foreach_vpe_api_msg                                             \
22254 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22255 _(sw_interface_dump,"")                                                 \
22256 _(sw_interface_set_flags,                                               \
22257   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22258 _(sw_interface_add_del_address,                                         \
22259   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22260 _(sw_interface_set_rx_mode,                                             \
22261   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22262 _(sw_interface_set_rx_placement,                                        \
22263   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22264 _(sw_interface_rx_placement_dump,                                       \
22265   "[<intfc> | sw_if_index <id>]")                                         \
22266 _(sw_interface_set_table,                                               \
22267   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22268 _(sw_interface_set_mpls_enable,                                         \
22269   "<intfc> | sw_if_index [disable | dis]")                              \
22270 _(sw_interface_set_vpath,                                               \
22271   "<intfc> | sw_if_index <id> enable | disable")                        \
22272 _(sw_interface_set_vxlan_bypass,                                        \
22273   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22274 _(sw_interface_set_geneve_bypass,                                       \
22275   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22276 _(sw_interface_set_l2_xconnect,                                         \
22277   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22278   "enable | disable")                                                   \
22279 _(sw_interface_set_l2_bridge,                                           \
22280   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22281   "[shg <split-horizon-group>] [bvi]\n"                                 \
22282   "enable | disable")                                                   \
22283 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22284 _(bridge_domain_add_del,                                                \
22285   "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") \
22286 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22287 _(l2fib_add_del,                                                        \
22288   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22289 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22290 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22291 _(l2_flags,                                                             \
22292   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22293 _(bridge_flags,                                                         \
22294   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22295 _(tap_create_v2,                                                        \
22296   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22297 _(tap_delete_v2,                                                        \
22298   "<vpp-if-name> | sw_if_index <id>")                                   \
22299 _(sw_interface_tap_v2_dump, "")                                         \
22300 _(virtio_pci_create,                                                    \
22301   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22302 _(virtio_pci_delete,                                                    \
22303   "<vpp-if-name> | sw_if_index <id>")                                   \
22304 _(sw_interface_virtio_pci_dump, "")                                     \
22305 _(bond_create,                                                          \
22306   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22307   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22308   "[id <if-id>]")                                                       \
22309 _(bond_delete,                                                          \
22310   "<vpp-if-name> | sw_if_index <id>")                                   \
22311 _(bond_enslave,                                                         \
22312   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22313 _(bond_detach_slave,                                                    \
22314   "sw_if_index <n>")                                                    \
22315 _(sw_interface_bond_dump, "")                                           \
22316 _(sw_interface_slave_dump,                                              \
22317   "<vpp-if-name> | sw_if_index <id>")                                   \
22318 _(ip_table_add_del,                                                     \
22319   "table <n> [ipv6] [add | del]\n")                                     \
22320 _(ip_add_del_route,                                                     \
22321   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22322   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22323   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22324   "[multipath] [count <n>] [del]")                                      \
22325 _(ip_mroute_add_del,                                                    \
22326   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22327   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22328 _(mpls_table_add_del,                                                   \
22329   "table <n> [add | del]\n")                                            \
22330 _(mpls_route_add_del,                                                   \
22331   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22332   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22333   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22334   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22335   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22336   "[count <n>] [del]")                                                  \
22337 _(mpls_ip_bind_unbind,                                                  \
22338   "<label> <addr/len>")                                                 \
22339 _(mpls_tunnel_add_del,                                                  \
22340   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22341   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22342   "[l2-only]  [out-label <n>]")                                         \
22343 _(sr_mpls_policy_add,                                                   \
22344   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22345 _(sr_mpls_policy_del,                                                   \
22346   "bsid <id>")                                                          \
22347 _(bier_table_add_del,                                                   \
22348   "<label> <sub-domain> <set> <bsl> [del]")                             \
22349 _(bier_route_add_del,                                                   \
22350   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22351   "[<intfc> | sw_if_index <id>]"                                        \
22352   "[weight <n>] [del] [multipath]")                                     \
22353 _(proxy_arp_add_del,                                                    \
22354   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22355 _(proxy_arp_intfc_enable_disable,                                       \
22356   "<intfc> | sw_if_index <id> enable | disable")                        \
22357 _(sw_interface_set_unnumbered,                                          \
22358   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22359 _(ip_neighbor_add_del,                                                  \
22360   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22361   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22362 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22363 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22364   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22365   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22366   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22367 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22368 _(reset_fib, "vrf <n> [ipv6]")                                          \
22369 _(dhcp_proxy_config,                                                    \
22370   "svr <v46-address> src <v46-address>\n"                               \
22371    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22372 _(dhcp_proxy_set_vss,                                                   \
22373   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22374 _(dhcp_proxy_dump, "ip6")                                               \
22375 _(dhcp_client_config,                                                   \
22376   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22377 _(set_ip_flow_hash,                                                     \
22378   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22379 _(sw_interface_ip6_enable_disable,                                      \
22380   "<intfc> | sw_if_index <id> enable | disable")                        \
22381 _(ip6nd_proxy_add_del,                                                  \
22382   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22383 _(ip6nd_proxy_dump, "")                                                 \
22384 _(sw_interface_ip6nd_ra_prefix,                                         \
22385   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22386   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22387   "[nolink] [isno]")                                                    \
22388 _(sw_interface_ip6nd_ra_config,                                         \
22389   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22390   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22391   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22392 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22393 _(l2_patch_add_del,                                                     \
22394   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22395   "enable | disable")                                                   \
22396 _(sr_localsid_add_del,                                                  \
22397   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22398   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22399 _(classify_add_del_table,                                               \
22400   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22401   " [del] [del-chain] mask <mask-value>\n"                              \
22402   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22403   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22404 _(classify_add_del_session,                                             \
22405   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22406   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22407   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22408   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22409 _(classify_set_interface_ip_table,                                      \
22410   "<intfc> | sw_if_index <nn> table <nn>")                              \
22411 _(classify_set_interface_l2_tables,                                     \
22412   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22413   "  [other-table <nn>]")                                               \
22414 _(get_node_index, "node <node-name")                                    \
22415 _(add_node_next, "node <node-name> next <next-node-name>")              \
22416 _(l2tpv3_create_tunnel,                                                 \
22417   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22418   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22419   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22420 _(l2tpv3_set_tunnel_cookies,                                            \
22421   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22422   "[new_remote_cookie <nn>]\n")                                         \
22423 _(l2tpv3_interface_enable_disable,                                      \
22424   "<intfc> | sw_if_index <nn> enable | disable")                        \
22425 _(l2tpv3_set_lookup_key,                                                \
22426   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22427 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22428 _(vxlan_offload_rx,                                                     \
22429   "hw { <interface name> | hw_if_index <nn>} "                          \
22430   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22431 _(vxlan_add_del_tunnel,                                                 \
22432   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22433   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22434   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22435 _(geneve_add_del_tunnel,                                                \
22436   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22437   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22438   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22439 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22440 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22441 _(gre_add_del_tunnel,                                                   \
22442   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22443   "[teb | erspan <session-id>] [del]")                                  \
22444 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22445 _(l2_fib_clear_table, "")                                               \
22446 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22447 _(l2_interface_vlan_tag_rewrite,                                        \
22448   "<intfc> | sw_if_index <nn> \n"                                       \
22449   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22450   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22451 _(create_vhost_user_if,                                                 \
22452         "socket <filename> [server] [renumber <dev_instance>] "         \
22453         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22454         "[mac <mac_address>]")                                          \
22455 _(modify_vhost_user_if,                                                 \
22456         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22457         "[server] [renumber <dev_instance>]")                           \
22458 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22459 _(sw_interface_vhost_user_dump, "")                                     \
22460 _(show_version, "")                                                     \
22461 _(show_threads, "")                                                     \
22462 _(vxlan_gpe_add_del_tunnel,                                             \
22463   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22464   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22465   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22466   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22467 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22468 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22469 _(interface_name_renumber,                                              \
22470   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22471 _(input_acl_set_interface,                                              \
22472   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22473   "  [l2-table <nn>] [del]")                                            \
22474 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22475 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22476   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22477 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22478 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22479 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22480 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22481 _(ip_dump, "ipv4 | ipv6")                                               \
22482 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22483 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22484   "  spid_id <n> ")                                                     \
22485 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22486   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22487   "  integ_alg <alg> integ_key <hex>")                                  \
22488 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22489   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22490   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22491   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22492 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22493 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22494   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22495   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22496   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22497   "  [instance <n>]")     \
22498 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22499 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22500   "  <alg> <hex>\n")                                                    \
22501 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22502 _(delete_loopback,"sw_if_index <nn>")                                   \
22503 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22504 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22505 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22506 _(want_interface_events,  "enable|disable")                             \
22507 _(get_first_msg_id, "client <name>")                                    \
22508 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22509 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22510   "fib-id <nn> [ip4][ip6][default]")                                    \
22511 _(get_node_graph, " ")                                                  \
22512 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22513 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22514 _(ioam_disable, "")                                                     \
22515 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22516                             " sw_if_index <sw_if_index> p <priority> "  \
22517                             "w <weight>] [del]")                        \
22518 _(one_add_del_locator, "locator-set <locator_name> "                    \
22519                         "iface <intf> | sw_if_index <sw_if_index> "     \
22520                         "p <priority> w <weight> [del]")                \
22521 _(one_add_del_local_eid,"vni <vni> eid "                                \
22522                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22523                          "locator-set <locator_name> [del]"             \
22524                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22525 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22526 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22527 _(one_enable_disable, "enable|disable")                                 \
22528 _(one_map_register_enable_disable, "enable|disable")                    \
22529 _(one_map_register_fallback_threshold, "<value>")                       \
22530 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22531 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22532                                "[seid <seid>] "                         \
22533                                "rloc <locator> p <prio> "               \
22534                                "w <weight> [rloc <loc> ... ] "          \
22535                                "action <action> [del-all]")             \
22536 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22537                           "<local-eid>")                                \
22538 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22539 _(one_use_petr, "ip-address> | disable")                                \
22540 _(one_map_request_mode, "src-dst|dst-only")                             \
22541 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22542 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22543 _(one_locator_set_dump, "[local | remote]")                             \
22544 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22545 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22546                        "[local] | [remote]")                            \
22547 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22548 _(one_ndp_bd_get, "")                                                   \
22549 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22550 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22551 _(one_l2_arp_bd_get, "")                                                \
22552 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22553 _(one_stats_enable_disable, "enable|disable")                           \
22554 _(show_one_stats_enable_disable, "")                                    \
22555 _(one_eid_table_vni_dump, "")                                           \
22556 _(one_eid_table_map_dump, "l2|l3")                                      \
22557 _(one_map_resolver_dump, "")                                            \
22558 _(one_map_server_dump, "")                                              \
22559 _(one_adjacencies_get, "vni <vni>")                                     \
22560 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22561 _(show_one_rloc_probe_state, "")                                        \
22562 _(show_one_map_register_state, "")                                      \
22563 _(show_one_status, "")                                                  \
22564 _(one_stats_dump, "")                                                   \
22565 _(one_stats_flush, "")                                                  \
22566 _(one_get_map_request_itr_rlocs, "")                                    \
22567 _(one_map_register_set_ttl, "<ttl>")                                    \
22568 _(one_set_transport_protocol, "udp|api")                                \
22569 _(one_get_transport_protocol, "")                                       \
22570 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22571 _(one_show_xtr_mode, "")                                                \
22572 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22573 _(one_show_pitr_mode, "")                                               \
22574 _(one_enable_disable_petr_mode, "enable|disable")                       \
22575 _(one_show_petr_mode, "")                                               \
22576 _(show_one_nsh_mapping, "")                                             \
22577 _(show_one_pitr, "")                                                    \
22578 _(show_one_use_petr, "")                                                \
22579 _(show_one_map_request_mode, "")                                        \
22580 _(show_one_map_register_ttl, "")                                        \
22581 _(show_one_map_register_fallback_threshold, "")                         \
22582 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22583                             " sw_if_index <sw_if_index> p <priority> "  \
22584                             "w <weight>] [del]")                        \
22585 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22586                         "iface <intf> | sw_if_index <sw_if_index> "     \
22587                         "p <priority> w <weight> [del]")                \
22588 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22589                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22590                          "locator-set <locator_name> [del]"             \
22591                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22592 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22593 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22594 _(lisp_enable_disable, "enable|disable")                                \
22595 _(lisp_map_register_enable_disable, "enable|disable")                   \
22596 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22597 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22598                                "[seid <seid>] "                         \
22599                                "rloc <locator> p <prio> "               \
22600                                "w <weight> [rloc <loc> ... ] "          \
22601                                "action <action> [del-all]")             \
22602 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22603                           "<local-eid>")                                \
22604 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22605 _(lisp_use_petr, "<ip-address> | disable")                              \
22606 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22607 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22608 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22609 _(lisp_locator_set_dump, "[local | remote]")                            \
22610 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22611 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22612                        "[local] | [remote]")                            \
22613 _(lisp_eid_table_vni_dump, "")                                          \
22614 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22615 _(lisp_map_resolver_dump, "")                                           \
22616 _(lisp_map_server_dump, "")                                             \
22617 _(lisp_adjacencies_get, "vni <vni>")                                    \
22618 _(gpe_fwd_entry_vnis_get, "")                                           \
22619 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22620 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22621                                 "[table <table-id>]")                   \
22622 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22623 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22624 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22625 _(gpe_get_encap_mode, "")                                               \
22626 _(lisp_gpe_add_del_iface, "up|down")                                    \
22627 _(lisp_gpe_enable_disable, "enable|disable")                            \
22628 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22629   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22630 _(show_lisp_rloc_probe_state, "")                                       \
22631 _(show_lisp_map_register_state, "")                                     \
22632 _(show_lisp_status, "")                                                 \
22633 _(lisp_get_map_request_itr_rlocs, "")                                   \
22634 _(show_lisp_pitr, "")                                                   \
22635 _(show_lisp_use_petr, "")                                               \
22636 _(show_lisp_map_request_mode, "")                                       \
22637 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22638 _(af_packet_delete, "name <host interface name>")                       \
22639 _(af_packet_dump, "")                                                   \
22640 _(policer_add_del, "name <policer name> <params> [del]")                \
22641 _(policer_dump, "[name <policer name>]")                                \
22642 _(policer_classify_set_interface,                                       \
22643   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22644   "  [l2-table <nn>] [del]")                                            \
22645 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22646 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22647     "[master|slave]")                                                   \
22648 _(netmap_delete, "name <interface name>")                               \
22649 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22650 _(mpls_fib_dump, "")                                                    \
22651 _(classify_table_ids, "")                                               \
22652 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22653 _(classify_table_info, "table_id <nn>")                                 \
22654 _(classify_session_dump, "table_id <nn>")                               \
22655 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22656     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22657     "[template_interval <nn>] [udp_checksum]")                          \
22658 _(ipfix_exporter_dump, "")                                              \
22659 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22660 _(ipfix_classify_stream_dump, "")                                       \
22661 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22662 _(ipfix_classify_table_dump, "")                                        \
22663 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22664 _(sw_interface_span_dump, "[l2]")                                           \
22665 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22666 _(pg_create_interface, "if_id <nn>")                                    \
22667 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22668 _(pg_enable_disable, "[stream <id>] disable")                           \
22669 _(ip_source_and_port_range_check_add_del,                               \
22670   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22671 _(ip_source_and_port_range_check_interface_add_del,                     \
22672   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22673   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22674 _(ipsec_gre_tunnel_add_del,                                             \
22675   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22676 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22677 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22678 _(l2_interface_pbb_tag_rewrite,                                         \
22679   "<intfc> | sw_if_index <nn> \n"                                       \
22680   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22681   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22682 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22683 _(flow_classify_set_interface,                                          \
22684   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22685 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22686 _(ip_fib_dump, "")                                                      \
22687 _(ip_mfib_dump, "")                                                     \
22688 _(ip6_fib_dump, "")                                                     \
22689 _(ip6_mfib_dump, "")                                                    \
22690 _(feature_enable_disable, "arc_name <arc_name> "                        \
22691   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22692 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22693 "[disable]")                                                            \
22694 _(l2_xconnect_dump, "")                                                 \
22695 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22696 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22697 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22698 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22699 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22700 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22701 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22702   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22703 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22704 _(sock_init_shm, "size <nnn>")                                          \
22705 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22706 _(dns_enable_disable, "[enable][disable]")                              \
22707 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22708 _(dns_resolve_name, "<hostname>")                                       \
22709 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22710 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22711 _(dns_resolve_name, "<hostname>")                                       \
22712 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22713   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22714 _(session_rules_dump, "")                                               \
22715 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22716 _(output_acl_set_interface,                                             \
22717   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22718   "  [l2-table <nn>] [del]")                                            \
22719 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22720
22721 /* List of command functions, CLI names map directly to functions */
22722 #define foreach_cli_function                                    \
22723 _(comment, "usage: comment <ignore-rest-of-line>")              \
22724 _(dump_interface_table, "usage: dump_interface_table")          \
22725 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22726 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22727 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22728 _(dump_macro_table, "usage: dump_macro_table ")                 \
22729 _(dump_node_table, "usage: dump_node_table")                    \
22730 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22731 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22732 _(echo, "usage: echo <message>")                                \
22733 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22734 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22735 _(help, "usage: help")                                          \
22736 _(q, "usage: quit")                                             \
22737 _(quit, "usage: quit")                                          \
22738 _(search_node_table, "usage: search_node_table <name>...")      \
22739 _(set, "usage: set <variable-name> <value>")                    \
22740 _(script, "usage: script <file-name>")                          \
22741 _(statseg, "usage: statseg");                                   \
22742 _(unset, "usage: unset <variable-name>")
22743
22744 #define _(N,n)                                  \
22745     static void vl_api_##n##_t_handler_uni      \
22746     (vl_api_##n##_t * mp)                       \
22747     {                                           \
22748         vat_main_t * vam = &vat_main;           \
22749         if (vam->json_output) {                 \
22750             vl_api_##n##_t_handler_json(mp);    \
22751         } else {                                \
22752             vl_api_##n##_t_handler(mp);         \
22753         }                                       \
22754     }
22755 foreach_vpe_api_reply_msg;
22756 #if VPP_API_TEST_BUILTIN == 0
22757 foreach_standalone_reply_msg;
22758 #endif
22759 #undef _
22760
22761 void
22762 vat_api_hookup (vat_main_t * vam)
22763 {
22764 #define _(N,n)                                                  \
22765     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22766                            vl_api_##n##_t_handler_uni,          \
22767                            vl_noop_handler,                     \
22768                            vl_api_##n##_t_endian,               \
22769                            vl_api_##n##_t_print,                \
22770                            sizeof(vl_api_##n##_t), 1);
22771   foreach_vpe_api_reply_msg;
22772 #if VPP_API_TEST_BUILTIN == 0
22773   foreach_standalone_reply_msg;
22774 #endif
22775 #undef _
22776
22777 #if (VPP_API_TEST_BUILTIN==0)
22778   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22779
22780   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22781
22782   vam->function_by_name = hash_create_string (0, sizeof (uword));
22783
22784   vam->help_by_name = hash_create_string (0, sizeof (uword));
22785 #endif
22786
22787   /* API messages we can send */
22788 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22789   foreach_vpe_api_msg;
22790 #undef _
22791
22792   /* Help strings */
22793 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22794   foreach_vpe_api_msg;
22795 #undef _
22796
22797   /* CLI functions */
22798 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22799   foreach_cli_function;
22800 #undef _
22801
22802   /* Help strings */
22803 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22804   foreach_cli_function;
22805 #undef _
22806 }
22807
22808 #if VPP_API_TEST_BUILTIN
22809 static clib_error_t *
22810 vat_api_hookup_shim (vlib_main_t * vm)
22811 {
22812   vat_api_hookup (&vat_main);
22813   return 0;
22814 }
22815
22816 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22817 #endif
22818
22819 /*
22820  * fd.io coding-style-patch-verification: ON
22821  *
22822  * Local Variables:
22823  * eval: (c-set-style "gnu")
22824  * End:
22825  */