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