API: Cleanup APIs interface.api
[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->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
938
939       sub->sub_number_of_tags = mp->sub_number_of_tags;
940       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
941       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
942
943       /* vlan tag rewrite */
944       sub->vtr_op = ntohl (mp->vtr_op);
945       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
946       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
947       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
948     }
949 }
950
951 static void vl_api_sw_interface_details_t_handler_json
952   (vl_api_sw_interface_details_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t *node = NULL;
956
957   if (VAT_JSON_ARRAY != vam->json_tree.type)
958     {
959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
960       vat_json_init_array (&vam->json_tree);
961     }
962   node = vat_json_array_add (&vam->json_tree);
963
964   vat_json_init_object (node);
965   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
966   vat_json_object_add_uint (node, "sup_sw_if_index",
967                             ntohl (mp->sup_sw_if_index));
968   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
969                              sizeof (mp->l2_address));
970   vat_json_object_add_string_copy (node, "interface_name",
971                                    mp->interface_name.buf);
972   vat_json_object_add_uint (node, "flags", mp->flags);
973   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
974   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
975   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
976   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
977   vat_json_object_add_uint (node, "sub_number_of_tags",
978                             mp->sub_number_of_tags);
979   vat_json_object_add_uint (node, "sub_outer_vlan_id",
980                             ntohs (mp->sub_outer_vlan_id));
981   vat_json_object_add_uint (node, "sub_inner_vlan_id",
982                             ntohs (mp->sub_inner_vlan_id));
983   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
984   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
985   vat_json_object_add_uint (node, "vtr_push_dot1q",
986                             ntohl (mp->vtr_push_dot1q));
987   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
988   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
989   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
990     {
991       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
992                                        format (0, "%U",
993                                                format_ethernet_address,
994                                                &mp->b_dmac));
995       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
996                                        format (0, "%U",
997                                                format_ethernet_address,
998                                                &mp->b_smac));
999       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1000       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1001     }
1002 }
1003
1004 #if VPP_API_TEST_BUILTIN == 0
1005 static void vl_api_sw_interface_event_t_handler
1006   (vl_api_sw_interface_event_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   if (vam->interface_event_display)
1010     errmsg ("interface flags: sw_if_index %d %s %s",
1011             ntohl (mp->sw_if_index),
1012             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1013             "admin-up" : "admin-down",
1014             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1015             "link-up" : "link-down");
1016 }
1017 #endif
1018
1019 static void vl_api_sw_interface_event_t_handler_json
1020   (vl_api_sw_interface_event_t * mp)
1021 {
1022   /* JSON output not supported */
1023 }
1024
1025 static void
1026 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1027 {
1028   vat_main_t *vam = &vat_main;
1029   i32 retval = ntohl (mp->retval);
1030
1031   vam->retval = retval;
1032   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1033   vam->result_ready = 1;
1034 }
1035
1036 static void
1037 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   vat_json_node_t node;
1041   api_main_t *am = &api_main;
1042   void *oldheap;
1043   u8 *reply;
1044
1045   vat_json_init_object (&node);
1046   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1047   vat_json_object_add_uint (&node, "reply_in_shmem",
1048                             ntohl (mp->reply_in_shmem));
1049   /* Toss the shared-memory original... */
1050   pthread_mutex_lock (&am->vlib_rp->mutex);
1051   oldheap = svm_push_data_heap (am->vlib_rp);
1052
1053   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1054   vec_free (reply);
1055
1056   svm_pop_heap (oldheap);
1057   pthread_mutex_unlock (&am->vlib_rp->mutex);
1058
1059   vat_json_print (vam->ofp, &node);
1060   vat_json_free (&node);
1061
1062   vam->retval = ntohl (mp->retval);
1063   vam->result_ready = 1;
1064 }
1065
1066 static void
1067 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1068 {
1069   vat_main_t *vam = &vat_main;
1070   i32 retval = ntohl (mp->retval);
1071   u32 length = vl_api_string_len (&mp->reply);
1072
1073   vec_reset_length (vam->cmd_reply);
1074
1075   vam->retval = retval;
1076   if (retval == 0)
1077     {
1078       vec_validate (vam->cmd_reply, length);
1079       clib_memcpy ((char *) (vam->cmd_reply),
1080                    vl_api_from_api_string (&mp->reply), length);
1081       vam->cmd_reply[length] = 0;
1082     }
1083   vam->result_ready = 1;
1084 }
1085
1086 static void
1087 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1088 {
1089   vat_main_t *vam = &vat_main;
1090   vat_json_node_t node;
1091
1092   vec_reset_length (vam->cmd_reply);
1093
1094   vat_json_init_object (&node);
1095   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1096   vat_json_object_add_string_copy (&node, "reply",
1097                                    vl_api_from_api_string (&mp->reply));
1098
1099   vat_json_print (vam->ofp, &node);
1100   vat_json_free (&node);
1101
1102   vam->retval = ntohl (mp->retval);
1103   vam->result_ready = 1;
1104 }
1105
1106 static void vl_api_classify_add_del_table_reply_t_handler
1107   (vl_api_classify_add_del_table_reply_t * mp)
1108 {
1109   vat_main_t *vam = &vat_main;
1110   i32 retval = ntohl (mp->retval);
1111   if (vam->async_mode)
1112     {
1113       vam->async_errors += (retval < 0);
1114     }
1115   else
1116     {
1117       vam->retval = retval;
1118       if (retval == 0 &&
1119           ((mp->new_table_index != 0xFFFFFFFF) ||
1120            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1121            (mp->match_n_vectors != 0xFFFFFFFF)))
1122         /*
1123          * Note: this is just barely thread-safe, depends on
1124          * the main thread spinning waiting for an answer...
1125          */
1126         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1127                 ntohl (mp->new_table_index),
1128                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1129       vam->result_ready = 1;
1130     }
1131 }
1132
1133 static void vl_api_classify_add_del_table_reply_t_handler_json
1134   (vl_api_classify_add_del_table_reply_t * mp)
1135 {
1136   vat_main_t *vam = &vat_main;
1137   vat_json_node_t node;
1138
1139   vat_json_init_object (&node);
1140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1141   vat_json_object_add_uint (&node, "new_table_index",
1142                             ntohl (mp->new_table_index));
1143   vat_json_object_add_uint (&node, "skip_n_vectors",
1144                             ntohl (mp->skip_n_vectors));
1145   vat_json_object_add_uint (&node, "match_n_vectors",
1146                             ntohl (mp->match_n_vectors));
1147
1148   vat_json_print (vam->ofp, &node);
1149   vat_json_free (&node);
1150
1151   vam->retval = ntohl (mp->retval);
1152   vam->result_ready = 1;
1153 }
1154
1155 static void vl_api_get_node_index_reply_t_handler
1156   (vl_api_get_node_index_reply_t * mp)
1157 {
1158   vat_main_t *vam = &vat_main;
1159   i32 retval = ntohl (mp->retval);
1160   if (vam->async_mode)
1161     {
1162       vam->async_errors += (retval < 0);
1163     }
1164   else
1165     {
1166       vam->retval = retval;
1167       if (retval == 0)
1168         errmsg ("node index %d", ntohl (mp->node_index));
1169       vam->result_ready = 1;
1170     }
1171 }
1172
1173 static void vl_api_get_node_index_reply_t_handler_json
1174   (vl_api_get_node_index_reply_t * mp)
1175 {
1176   vat_main_t *vam = &vat_main;
1177   vat_json_node_t node;
1178
1179   vat_json_init_object (&node);
1180   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1181   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_get_next_index_reply_t_handler
1191   (vl_api_get_next_index_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0)
1203         errmsg ("next node index %d", ntohl (mp->next_index));
1204       vam->result_ready = 1;
1205     }
1206 }
1207
1208 static void vl_api_get_next_index_reply_t_handler_json
1209   (vl_api_get_next_index_reply_t * mp)
1210 {
1211   vat_main_t *vam = &vat_main;
1212   vat_json_node_t node;
1213
1214   vat_json_init_object (&node);
1215   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1216   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void vl_api_add_node_next_reply_t_handler
1226   (vl_api_add_node_next_reply_t * mp)
1227 {
1228   vat_main_t *vam = &vat_main;
1229   i32 retval = ntohl (mp->retval);
1230   if (vam->async_mode)
1231     {
1232       vam->async_errors += (retval < 0);
1233     }
1234   else
1235     {
1236       vam->retval = retval;
1237       if (retval == 0)
1238         errmsg ("next index %d", ntohl (mp->next_index));
1239       vam->result_ready = 1;
1240     }
1241 }
1242
1243 static void vl_api_add_node_next_reply_t_handler_json
1244   (vl_api_add_node_next_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t node;
1248
1249   vat_json_init_object (&node);
1250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1251   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1252
1253   vat_json_print (vam->ofp, &node);
1254   vat_json_free (&node);
1255
1256   vam->retval = ntohl (mp->retval);
1257   vam->result_ready = 1;
1258 }
1259
1260 static void vl_api_show_version_reply_t_handler
1261   (vl_api_show_version_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   i32 retval = ntohl (mp->retval);
1265
1266   if (retval >= 0)
1267     {
1268       char *s;
1269       char *p = (char *) &mp->program;
1270
1271       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1272       errmsg ("        program: %s\n", s);
1273       free (s);
1274
1275       p +=
1276         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1277       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1278       errmsg ("        version: %s\n", s);
1279       free (s);
1280
1281       p +=
1282         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1283       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1284       errmsg ("     build date: %s\n", s);
1285       free (s);
1286
1287       p +=
1288         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1289       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1290       errmsg ("build directory: %s\n", s);
1291       free (s);
1292     }
1293   vam->retval = retval;
1294   vam->result_ready = 1;
1295 }
1296
1297 static void vl_api_show_version_reply_t_handler_json
1298   (vl_api_show_version_reply_t * mp)
1299 {
1300   vat_main_t *vam = &vat_main;
1301   vat_json_node_t node;
1302
1303   vat_json_init_object (&node);
1304   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1305   char *p = (char *) &mp->program;
1306   vat_json_object_add_string_copy (&node, "program",
1307                                    vl_api_from_api_string ((vl_api_string_t *)
1308                                                            p));
1309   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1310   vat_json_object_add_string_copy (&node, "version",
1311                                    vl_api_from_api_string ((vl_api_string_t *)
1312                                                            p));
1313   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1314   vat_json_object_add_string_copy (&node, "build_date",
1315                                    vl_api_from_api_string ((vl_api_string_t *)
1316                                                            p));
1317   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1318   vat_json_object_add_string_copy (&node, "build_directory",
1319                                    vl_api_from_api_string ((vl_api_string_t *)
1320                                                            p));
1321
1322   vat_json_print (vam->ofp, &node);
1323   vat_json_free (&node);
1324
1325   vam->retval = ntohl (mp->retval);
1326   vam->result_ready = 1;
1327 }
1328
1329 static void vl_api_show_threads_reply_t_handler
1330   (vl_api_show_threads_reply_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   i32 retval = ntohl (mp->retval);
1334   int i, count = 0;
1335
1336   if (retval >= 0)
1337     count = ntohl (mp->count);
1338
1339   for (i = 0; i < count; i++)
1340     print (vam->ofp,
1341            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1342            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1343            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1344            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1345            ntohl (mp->thread_data[i].cpu_socket));
1346
1347   vam->retval = retval;
1348   vam->result_ready = 1;
1349 }
1350
1351 static void vl_api_show_threads_reply_t_handler_json
1352   (vl_api_show_threads_reply_t * mp)
1353 {
1354   vat_main_t *vam = &vat_main;
1355   vat_json_node_t node;
1356   vl_api_thread_data_t *td;
1357   i32 retval = ntohl (mp->retval);
1358   int i, count = 0;
1359
1360   if (retval >= 0)
1361     count = ntohl (mp->count);
1362
1363   vat_json_init_object (&node);
1364   vat_json_object_add_int (&node, "retval", retval);
1365   vat_json_object_add_uint (&node, "count", count);
1366
1367   for (i = 0; i < count; i++)
1368     {
1369       td = &mp->thread_data[i];
1370       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1371       vat_json_object_add_string_copy (&node, "name", td->name);
1372       vat_json_object_add_string_copy (&node, "type", td->type);
1373       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1374       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1375       vat_json_object_add_int (&node, "core", ntohl (td->id));
1376       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1377     }
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = retval;
1383   vam->result_ready = 1;
1384 }
1385
1386 static int
1387 api_show_threads (vat_main_t * vam)
1388 {
1389   vl_api_show_threads_t *mp;
1390   int ret;
1391
1392   print (vam->ofp,
1393          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1394          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1395
1396   M (SHOW_THREADS, mp);
1397
1398   S (mp);
1399   W (ret);
1400   return ret;
1401 }
1402
1403 static void
1404 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1405 {
1406   u32 sw_if_index = ntohl (mp->sw_if_index);
1407   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1408           mp->mac_ip ? "mac/ip binding" : "address resolution",
1409           ntohl (mp->pid), format_ip4_address, mp->ip,
1410           format_vl_api_mac_address, &mp->mac, sw_if_index);
1411 }
1412
1413 static void
1414 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1415 {
1416   /* JSON output not supported */
1417 }
1418
1419 static void
1420 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1421 {
1422   u32 sw_if_index = ntohl (mp->sw_if_index);
1423   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1424           mp->mac_ip ? "mac/ip binding" : "address resolution",
1425           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1426           format_vl_api_mac_address, mp->mac, sw_if_index);
1427 }
1428
1429 static void
1430 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1431 {
1432   /* JSON output not supported */
1433 }
1434
1435 static void
1436 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1437 {
1438   u32 n_macs = ntohl (mp->n_macs);
1439   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1440           ntohl (mp->pid), mp->client_index, n_macs);
1441   int i;
1442   for (i = 0; i < n_macs; i++)
1443     {
1444       vl_api_mac_entry_t *mac = &mp->mac[i];
1445       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1446               i + 1, ntohl (mac->sw_if_index),
1447               format_ethernet_address, mac->mac_addr, mac->action);
1448       if (i == 1000)
1449         break;
1450     }
1451 }
1452
1453 static void
1454 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1455 {
1456   /* JSON output not supported */
1457 }
1458
1459 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1460 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1461
1462 /*
1463  * Special-case: build the bridge domain table, maintain
1464  * the next bd id vbl.
1465  */
1466 static void vl_api_bridge_domain_details_t_handler
1467   (vl_api_bridge_domain_details_t * mp)
1468 {
1469   vat_main_t *vam = &vat_main;
1470   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1471   int i;
1472
1473   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1474          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1475
1476   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1477          ntohl (mp->bd_id), mp->learn, mp->forward,
1478          mp->flood, ntohl (mp->bvi_sw_if_index),
1479          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1480
1481   if (n_sw_ifs)
1482     {
1483       vl_api_bridge_domain_sw_if_t *sw_ifs;
1484       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1485              "Interface Name");
1486
1487       sw_ifs = mp->sw_if_details;
1488       for (i = 0; i < n_sw_ifs; i++)
1489         {
1490           u8 *sw_if_name = 0;
1491           u32 sw_if_index;
1492           hash_pair_t *p;
1493
1494           sw_if_index = ntohl (sw_ifs->sw_if_index);
1495
1496           /* *INDENT-OFF* */
1497           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1498                              ({
1499                                if ((u32) p->value[0] == sw_if_index)
1500                                  {
1501                                    sw_if_name = (u8 *)(p->key);
1502                                    break;
1503                                  }
1504                              }));
1505           /* *INDENT-ON* */
1506           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1507                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1508                  "sw_if_index not found!");
1509
1510           sw_ifs++;
1511         }
1512     }
1513 }
1514
1515 static void vl_api_bridge_domain_details_t_handler_json
1516   (vl_api_bridge_domain_details_t * mp)
1517 {
1518   vat_main_t *vam = &vat_main;
1519   vat_json_node_t *node, *array = NULL;
1520   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1521
1522   if (VAT_JSON_ARRAY != vam->json_tree.type)
1523     {
1524       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1525       vat_json_init_array (&vam->json_tree);
1526     }
1527   node = vat_json_array_add (&vam->json_tree);
1528
1529   vat_json_init_object (node);
1530   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1531   vat_json_object_add_uint (node, "flood", mp->flood);
1532   vat_json_object_add_uint (node, "forward", mp->forward);
1533   vat_json_object_add_uint (node, "learn", mp->learn);
1534   vat_json_object_add_uint (node, "bvi_sw_if_index",
1535                             ntohl (mp->bvi_sw_if_index));
1536   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1537   array = vat_json_object_add (node, "sw_if");
1538   vat_json_init_array (array);
1539
1540
1541
1542   if (n_sw_ifs)
1543     {
1544       vl_api_bridge_domain_sw_if_t *sw_ifs;
1545       int i;
1546
1547       sw_ifs = mp->sw_if_details;
1548       for (i = 0; i < n_sw_ifs; i++)
1549         {
1550           node = vat_json_array_add (array);
1551           vat_json_init_object (node);
1552           vat_json_object_add_uint (node, "sw_if_index",
1553                                     ntohl (sw_ifs->sw_if_index));
1554           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1555           sw_ifs++;
1556         }
1557     }
1558 }
1559
1560 static void vl_api_control_ping_reply_t_handler
1561   (vl_api_control_ping_reply_t * mp)
1562 {
1563   vat_main_t *vam = &vat_main;
1564   i32 retval = ntohl (mp->retval);
1565   if (vam->async_mode)
1566     {
1567       vam->async_errors += (retval < 0);
1568     }
1569   else
1570     {
1571       vam->retval = retval;
1572       vam->result_ready = 1;
1573     }
1574   if (vam->socket_client_main)
1575     vam->socket_client_main->control_pings_outstanding--;
1576 }
1577
1578 static void vl_api_control_ping_reply_t_handler_json
1579   (vl_api_control_ping_reply_t * mp)
1580 {
1581   vat_main_t *vam = &vat_main;
1582   i32 retval = ntohl (mp->retval);
1583
1584   if (VAT_JSON_NONE != vam->json_tree.type)
1585     {
1586       vat_json_print (vam->ofp, &vam->json_tree);
1587       vat_json_free (&vam->json_tree);
1588       vam->json_tree.type = VAT_JSON_NONE;
1589     }
1590   else
1591     {
1592       /* just print [] */
1593       vat_json_init_array (&vam->json_tree);
1594       vat_json_print (vam->ofp, &vam->json_tree);
1595       vam->json_tree.type = VAT_JSON_NONE;
1596     }
1597
1598   vam->retval = retval;
1599   vam->result_ready = 1;
1600 }
1601
1602 static void
1603   vl_api_bridge_domain_set_mac_age_reply_t_handler
1604   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608   if (vam->async_mode)
1609     {
1610       vam->async_errors += (retval < 0);
1611     }
1612   else
1613     {
1614       vam->retval = retval;
1615       vam->result_ready = 1;
1616     }
1617 }
1618
1619 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1620   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1621 {
1622   vat_main_t *vam = &vat_main;
1623   vat_json_node_t node;
1624
1625   vat_json_init_object (&node);
1626   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1627
1628   vat_json_print (vam->ofp, &node);
1629   vat_json_free (&node);
1630
1631   vam->retval = ntohl (mp->retval);
1632   vam->result_ready = 1;
1633 }
1634
1635 static void
1636 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1637 {
1638   vat_main_t *vam = &vat_main;
1639   i32 retval = ntohl (mp->retval);
1640   if (vam->async_mode)
1641     {
1642       vam->async_errors += (retval < 0);
1643     }
1644   else
1645     {
1646       vam->retval = retval;
1647       vam->result_ready = 1;
1648     }
1649 }
1650
1651 static void vl_api_l2_flags_reply_t_handler_json
1652   (vl_api_l2_flags_reply_t * mp)
1653 {
1654   vat_main_t *vam = &vat_main;
1655   vat_json_node_t node;
1656
1657   vat_json_init_object (&node);
1658   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1659   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1660                             ntohl (mp->resulting_feature_bitmap));
1661
1662   vat_json_print (vam->ofp, &node);
1663   vat_json_free (&node);
1664
1665   vam->retval = ntohl (mp->retval);
1666   vam->result_ready = 1;
1667 }
1668
1669 static void vl_api_bridge_flags_reply_t_handler
1670   (vl_api_bridge_flags_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   i32 retval = ntohl (mp->retval);
1674   if (vam->async_mode)
1675     {
1676       vam->async_errors += (retval < 0);
1677     }
1678   else
1679     {
1680       vam->retval = retval;
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_bridge_flags_reply_t_handler_json
1686   (vl_api_bridge_flags_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1694                             ntohl (mp->resulting_feature_bitmap));
1695
1696   vat_json_print (vam->ofp, &node);
1697   vat_json_free (&node);
1698
1699   vam->retval = ntohl (mp->retval);
1700   vam->result_ready = 1;
1701 }
1702
1703 static void
1704 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1705 {
1706   vat_main_t *vam = &vat_main;
1707   i32 retval = ntohl (mp->retval);
1708   if (vam->async_mode)
1709     {
1710       vam->async_errors += (retval < 0);
1711     }
1712   else
1713     {
1714       vam->retval = retval;
1715       vam->sw_if_index = ntohl (mp->sw_if_index);
1716       vam->result_ready = 1;
1717     }
1718
1719 }
1720
1721 static void vl_api_tap_create_v2_reply_t_handler_json
1722   (vl_api_tap_create_v2_reply_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   vat_json_node_t node;
1726
1727   vat_json_init_object (&node);
1728   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1729   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1730
1731   vat_json_print (vam->ofp, &node);
1732   vat_json_free (&node);
1733
1734   vam->retval = ntohl (mp->retval);
1735   vam->result_ready = 1;
1736
1737 }
1738
1739 static void
1740 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   i32 retval = ntohl (mp->retval);
1744   if (vam->async_mode)
1745     {
1746       vam->async_errors += (retval < 0);
1747     }
1748   else
1749     {
1750       vam->retval = retval;
1751       vam->result_ready = 1;
1752     }
1753 }
1754
1755 static void vl_api_tap_delete_v2_reply_t_handler_json
1756   (vl_api_tap_delete_v2_reply_t * mp)
1757 {
1758   vat_main_t *vam = &vat_main;
1759   vat_json_node_t node;
1760
1761   vat_json_init_object (&node);
1762   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1763
1764   vat_json_print (vam->ofp, &node);
1765   vat_json_free (&node);
1766
1767   vam->retval = ntohl (mp->retval);
1768   vam->result_ready = 1;
1769 }
1770
1771 static void
1772 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1773                                           mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   i32 retval = ntohl (mp->retval);
1777   if (vam->async_mode)
1778     {
1779       vam->async_errors += (retval < 0);
1780     }
1781   else
1782     {
1783       vam->retval = retval;
1784       vam->sw_if_index = ntohl (mp->sw_if_index);
1785       vam->result_ready = 1;
1786     }
1787 }
1788
1789 static void vl_api_virtio_pci_create_reply_t_handler_json
1790   (vl_api_virtio_pci_create_reply_t * mp)
1791 {
1792   vat_main_t *vam = &vat_main;
1793   vat_json_node_t node;
1794
1795   vat_json_init_object (&node);
1796   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1797   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1798
1799   vat_json_print (vam->ofp, &node);
1800   vat_json_free (&node);
1801
1802   vam->retval = ntohl (mp->retval);
1803   vam->result_ready = 1;
1804
1805 }
1806
1807 static void
1808 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1809                                           mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812   i32 retval = ntohl (mp->retval);
1813   if (vam->async_mode)
1814     {
1815       vam->async_errors += (retval < 0);
1816     }
1817   else
1818     {
1819       vam->retval = retval;
1820       vam->result_ready = 1;
1821     }
1822 }
1823
1824 static void vl_api_virtio_pci_delete_reply_t_handler_json
1825   (vl_api_virtio_pci_delete_reply_t * mp)
1826 {
1827   vat_main_t *vam = &vat_main;
1828   vat_json_node_t node;
1829
1830   vat_json_init_object (&node);
1831   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1832
1833   vat_json_print (vam->ofp, &node);
1834   vat_json_free (&node);
1835
1836   vam->retval = ntohl (mp->retval);
1837   vam->result_ready = 1;
1838 }
1839
1840 static void
1841 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   i32 retval = ntohl (mp->retval);
1845
1846   if (vam->async_mode)
1847     {
1848       vam->async_errors += (retval < 0);
1849     }
1850   else
1851     {
1852       vam->retval = retval;
1853       vam->sw_if_index = ntohl (mp->sw_if_index);
1854       vam->result_ready = 1;
1855     }
1856 }
1857
1858 static void vl_api_bond_create_reply_t_handler_json
1859   (vl_api_bond_create_reply_t * mp)
1860 {
1861   vat_main_t *vam = &vat_main;
1862   vat_json_node_t node;
1863
1864   vat_json_init_object (&node);
1865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1867
1868   vat_json_print (vam->ofp, &node);
1869   vat_json_free (&node);
1870
1871   vam->retval = ntohl (mp->retval);
1872   vam->result_ready = 1;
1873 }
1874
1875 static void
1876 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1877 {
1878   vat_main_t *vam = &vat_main;
1879   i32 retval = ntohl (mp->retval);
1880
1881   if (vam->async_mode)
1882     {
1883       vam->async_errors += (retval < 0);
1884     }
1885   else
1886     {
1887       vam->retval = retval;
1888       vam->result_ready = 1;
1889     }
1890 }
1891
1892 static void vl_api_bond_delete_reply_t_handler_json
1893   (vl_api_bond_delete_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   vat_json_node_t node;
1897
1898   vat_json_init_object (&node);
1899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1900
1901   vat_json_print (vam->ofp, &node);
1902   vat_json_free (&node);
1903
1904   vam->retval = ntohl (mp->retval);
1905   vam->result_ready = 1;
1906 }
1907
1908 static void
1909 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1910 {
1911   vat_main_t *vam = &vat_main;
1912   i32 retval = ntohl (mp->retval);
1913
1914   if (vam->async_mode)
1915     {
1916       vam->async_errors += (retval < 0);
1917     }
1918   else
1919     {
1920       vam->retval = retval;
1921       vam->result_ready = 1;
1922     }
1923 }
1924
1925 static void vl_api_bond_enslave_reply_t_handler_json
1926   (vl_api_bond_enslave_reply_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   vat_json_node_t node;
1930
1931   vat_json_init_object (&node);
1932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1933
1934   vat_json_print (vam->ofp, &node);
1935   vat_json_free (&node);
1936
1937   vam->retval = ntohl (mp->retval);
1938   vam->result_ready = 1;
1939 }
1940
1941 static void
1942 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1943                                           mp)
1944 {
1945   vat_main_t *vam = &vat_main;
1946   i32 retval = ntohl (mp->retval);
1947
1948   if (vam->async_mode)
1949     {
1950       vam->async_errors += (retval < 0);
1951     }
1952   else
1953     {
1954       vam->retval = retval;
1955       vam->result_ready = 1;
1956     }
1957 }
1958
1959 static void vl_api_bond_detach_slave_reply_t_handler_json
1960   (vl_api_bond_detach_slave_reply_t * mp)
1961 {
1962   vat_main_t *vam = &vat_main;
1963   vat_json_node_t node;
1964
1965   vat_json_init_object (&node);
1966   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1967
1968   vat_json_print (vam->ofp, &node);
1969   vat_json_free (&node);
1970
1971   vam->retval = ntohl (mp->retval);
1972   vam->result_ready = 1;
1973 }
1974
1975 static void vl_api_sw_interface_bond_details_t_handler
1976   (vl_api_sw_interface_bond_details_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979
1980   print (vam->ofp,
1981          "%-16s %-12d %-12U %-13U %-14u %-14u",
1982          mp->interface_name, ntohl (mp->sw_if_index),
1983          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1984          ntohl (mp->active_slaves), ntohl (mp->slaves));
1985 }
1986
1987 static void vl_api_sw_interface_bond_details_t_handler_json
1988   (vl_api_sw_interface_bond_details_t * mp)
1989 {
1990   vat_main_t *vam = &vat_main;
1991   vat_json_node_t *node = NULL;
1992
1993   if (VAT_JSON_ARRAY != vam->json_tree.type)
1994     {
1995       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1996       vat_json_init_array (&vam->json_tree);
1997     }
1998   node = vat_json_array_add (&vam->json_tree);
1999
2000   vat_json_init_object (node);
2001   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2002   vat_json_object_add_string_copy (node, "interface_name",
2003                                    mp->interface_name);
2004   vat_json_object_add_uint (node, "mode", mp->mode);
2005   vat_json_object_add_uint (node, "load_balance", mp->lb);
2006   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2007   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2008 }
2009
2010 static int
2011 api_sw_interface_bond_dump (vat_main_t * vam)
2012 {
2013   vl_api_sw_interface_bond_dump_t *mp;
2014   vl_api_control_ping_t *mp_ping;
2015   int ret;
2016
2017   print (vam->ofp,
2018          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2019          "interface name", "sw_if_index", "mode", "load balance",
2020          "active slaves", "slaves");
2021
2022   /* Get list of bond interfaces */
2023   M (SW_INTERFACE_BOND_DUMP, mp);
2024   S (mp);
2025
2026   /* Use a control ping for synchronization */
2027   MPING (CONTROL_PING, mp_ping);
2028   S (mp_ping);
2029
2030   W (ret);
2031   return ret;
2032 }
2033
2034 static void vl_api_sw_interface_slave_details_t_handler
2035   (vl_api_sw_interface_slave_details_t * mp)
2036 {
2037   vat_main_t *vam = &vat_main;
2038
2039   print (vam->ofp,
2040          "%-25s %-12d %-12d %d", mp->interface_name,
2041          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2042 }
2043
2044 static void vl_api_sw_interface_slave_details_t_handler_json
2045   (vl_api_sw_interface_slave_details_t * mp)
2046 {
2047   vat_main_t *vam = &vat_main;
2048   vat_json_node_t *node = NULL;
2049
2050   if (VAT_JSON_ARRAY != vam->json_tree.type)
2051     {
2052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2053       vat_json_init_array (&vam->json_tree);
2054     }
2055   node = vat_json_array_add (&vam->json_tree);
2056
2057   vat_json_init_object (node);
2058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2059   vat_json_object_add_string_copy (node, "interface_name",
2060                                    mp->interface_name);
2061   vat_json_object_add_uint (node, "passive", mp->is_passive);
2062   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2063 }
2064
2065 static int
2066 api_sw_interface_slave_dump (vat_main_t * vam)
2067 {
2068   unformat_input_t *i = vam->input;
2069   vl_api_sw_interface_slave_dump_t *mp;
2070   vl_api_control_ping_t *mp_ping;
2071   u32 sw_if_index = ~0;
2072   u8 sw_if_index_set = 0;
2073   int ret;
2074
2075   /* Parse args required to build the message */
2076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2077     {
2078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2079         sw_if_index_set = 1;
2080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2081         sw_if_index_set = 1;
2082       else
2083         break;
2084     }
2085
2086   if (sw_if_index_set == 0)
2087     {
2088       errmsg ("missing vpp interface name. ");
2089       return -99;
2090     }
2091
2092   print (vam->ofp,
2093          "\n%-25s %-12s %-12s %s",
2094          "slave interface name", "sw_if_index", "passive", "long_timeout");
2095
2096   /* Get list of bond interfaces */
2097   M (SW_INTERFACE_SLAVE_DUMP, mp);
2098   mp->sw_if_index = ntohl (sw_if_index);
2099   S (mp);
2100
2101   /* Use a control ping for synchronization */
2102   MPING (CONTROL_PING, mp_ping);
2103   S (mp_ping);
2104
2105   W (ret);
2106   return ret;
2107 }
2108
2109 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2110   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2111 {
2112   vat_main_t *vam = &vat_main;
2113   i32 retval = ntohl (mp->retval);
2114   if (vam->async_mode)
2115     {
2116       vam->async_errors += (retval < 0);
2117     }
2118   else
2119     {
2120       vam->retval = retval;
2121       vam->sw_if_index = ntohl (mp->sw_if_index);
2122       vam->result_ready = 1;
2123     }
2124   vam->regenerate_interface_table = 1;
2125 }
2126
2127 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2128   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2129 {
2130   vat_main_t *vam = &vat_main;
2131   vat_json_node_t node;
2132
2133   vat_json_init_object (&node);
2134   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2135   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2136                             ntohl (mp->sw_if_index));
2137
2138   vat_json_print (vam->ofp, &node);
2139   vat_json_free (&node);
2140
2141   vam->retval = ntohl (mp->retval);
2142   vam->result_ready = 1;
2143 }
2144
2145 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2146   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2147 {
2148   vat_main_t *vam = &vat_main;
2149   i32 retval = ntohl (mp->retval);
2150   if (vam->async_mode)
2151     {
2152       vam->async_errors += (retval < 0);
2153     }
2154   else
2155     {
2156       vam->retval = retval;
2157       vam->sw_if_index = ntohl (mp->sw_if_index);
2158       vam->result_ready = 1;
2159     }
2160 }
2161
2162 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2163   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2164 {
2165   vat_main_t *vam = &vat_main;
2166   vat_json_node_t node;
2167
2168   vat_json_init_object (&node);
2169   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2170   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2171
2172   vat_json_print (vam->ofp, &node);
2173   vat_json_free (&node);
2174
2175   vam->retval = ntohl (mp->retval);
2176   vam->result_ready = 1;
2177 }
2178
2179 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2180   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       vam->retval = retval;
2191       vam->result_ready = 1;
2192     }
2193 }
2194
2195 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2196   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vat_json_node_t node;
2200
2201   vat_json_init_object (&node);
2202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2203   vat_json_object_add_uint (&node, "fwd_entry_index",
2204                             clib_net_to_host_u32 (mp->fwd_entry_index));
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 u8 *
2214 format_lisp_transport_protocol (u8 * s, va_list * args)
2215 {
2216   u32 proto = va_arg (*args, u32);
2217
2218   switch (proto)
2219     {
2220     case 1:
2221       return format (s, "udp");
2222     case 2:
2223       return format (s, "api");
2224     default:
2225       return 0;
2226     }
2227   return 0;
2228 }
2229
2230 static void vl_api_one_get_transport_protocol_reply_t_handler
2231   (vl_api_one_get_transport_protocol_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   i32 retval = ntohl (mp->retval);
2235   if (vam->async_mode)
2236     {
2237       vam->async_errors += (retval < 0);
2238     }
2239   else
2240     {
2241       u32 proto = mp->protocol;
2242       print (vam->ofp, "Transport protocol: %U",
2243              format_lisp_transport_protocol, proto);
2244       vam->retval = retval;
2245       vam->result_ready = 1;
2246     }
2247 }
2248
2249 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2250   (vl_api_one_get_transport_protocol_reply_t * mp)
2251 {
2252   vat_main_t *vam = &vat_main;
2253   vat_json_node_t node;
2254   u8 *s;
2255
2256   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2257   vec_add1 (s, 0);
2258
2259   vat_json_init_object (&node);
2260   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2261   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2262
2263   vec_free (s);
2264   vat_json_print (vam->ofp, &node);
2265   vat_json_free (&node);
2266
2267   vam->retval = ntohl (mp->retval);
2268   vam->result_ready = 1;
2269 }
2270
2271 static void vl_api_one_add_del_locator_set_reply_t_handler
2272   (vl_api_one_add_del_locator_set_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   i32 retval = ntohl (mp->retval);
2276   if (vam->async_mode)
2277     {
2278       vam->async_errors += (retval < 0);
2279     }
2280   else
2281     {
2282       vam->retval = retval;
2283       vam->result_ready = 1;
2284     }
2285 }
2286
2287 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2288   (vl_api_one_add_del_locator_set_reply_t * mp)
2289 {
2290   vat_main_t *vam = &vat_main;
2291   vat_json_node_t node;
2292
2293   vat_json_init_object (&node);
2294   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2295   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2296
2297   vat_json_print (vam->ofp, &node);
2298   vat_json_free (&node);
2299
2300   vam->retval = ntohl (mp->retval);
2301   vam->result_ready = 1;
2302 }
2303
2304 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2305   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   i32 retval = ntohl (mp->retval);
2309   if (vam->async_mode)
2310     {
2311       vam->async_errors += (retval < 0);
2312     }
2313   else
2314     {
2315       vam->retval = retval;
2316       vam->sw_if_index = ntohl (mp->sw_if_index);
2317       vam->result_ready = 1;
2318     }
2319   vam->regenerate_interface_table = 1;
2320 }
2321
2322 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2323   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   vat_json_node_t node;
2327
2328   vat_json_init_object (&node);
2329   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2330   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2331
2332   vat_json_print (vam->ofp, &node);
2333   vat_json_free (&node);
2334
2335   vam->retval = ntohl (mp->retval);
2336   vam->result_ready = 1;
2337 }
2338
2339 static void vl_api_vxlan_offload_rx_reply_t_handler
2340   (vl_api_vxlan_offload_rx_reply_t * mp)
2341 {
2342   vat_main_t *vam = &vat_main;
2343   i32 retval = ntohl (mp->retval);
2344   if (vam->async_mode)
2345     {
2346       vam->async_errors += (retval < 0);
2347     }
2348   else
2349     {
2350       vam->retval = retval;
2351       vam->result_ready = 1;
2352     }
2353 }
2354
2355 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2356   (vl_api_vxlan_offload_rx_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   vat_json_node_t node;
2360
2361   vat_json_init_object (&node);
2362   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2363
2364   vat_json_print (vam->ofp, &node);
2365   vat_json_free (&node);
2366
2367   vam->retval = ntohl (mp->retval);
2368   vam->result_ready = 1;
2369 }
2370
2371 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2372   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2373 {
2374   vat_main_t *vam = &vat_main;
2375   i32 retval = ntohl (mp->retval);
2376   if (vam->async_mode)
2377     {
2378       vam->async_errors += (retval < 0);
2379     }
2380   else
2381     {
2382       vam->retval = retval;
2383       vam->sw_if_index = ntohl (mp->sw_if_index);
2384       vam->result_ready = 1;
2385     }
2386 }
2387
2388 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2389   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2390 {
2391   vat_main_t *vam = &vat_main;
2392   vat_json_node_t node;
2393
2394   vat_json_init_object (&node);
2395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2397
2398   vat_json_print (vam->ofp, &node);
2399   vat_json_free (&node);
2400
2401   vam->retval = ntohl (mp->retval);
2402   vam->result_ready = 1;
2403 }
2404
2405 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2406   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2407 {
2408   vat_main_t *vam = &vat_main;
2409   i32 retval = ntohl (mp->retval);
2410   if (vam->async_mode)
2411     {
2412       vam->async_errors += (retval < 0);
2413     }
2414   else
2415     {
2416       vam->retval = retval;
2417       vam->sw_if_index = ntohl (mp->sw_if_index);
2418       vam->result_ready = 1;
2419     }
2420   vam->regenerate_interface_table = 1;
2421 }
2422
2423 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2424   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   vat_json_node_t node;
2428
2429   vat_json_init_object (&node);
2430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2431   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2432
2433   vat_json_print (vam->ofp, &node);
2434   vat_json_free (&node);
2435
2436   vam->retval = ntohl (mp->retval);
2437   vam->result_ready = 1;
2438 }
2439
2440 static void vl_api_gre_add_del_tunnel_reply_t_handler
2441   (vl_api_gre_add_del_tunnel_reply_t * mp)
2442 {
2443   vat_main_t *vam = &vat_main;
2444   i32 retval = ntohl (mp->retval);
2445   if (vam->async_mode)
2446     {
2447       vam->async_errors += (retval < 0);
2448     }
2449   else
2450     {
2451       vam->retval = retval;
2452       vam->sw_if_index = ntohl (mp->sw_if_index);
2453       vam->result_ready = 1;
2454     }
2455 }
2456
2457 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2458   (vl_api_gre_add_del_tunnel_reply_t * mp)
2459 {
2460   vat_main_t *vam = &vat_main;
2461   vat_json_node_t node;
2462
2463   vat_json_init_object (&node);
2464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2465   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2466
2467   vat_json_print (vam->ofp, &node);
2468   vat_json_free (&node);
2469
2470   vam->retval = ntohl (mp->retval);
2471   vam->result_ready = 1;
2472 }
2473
2474 static void vl_api_create_vhost_user_if_reply_t_handler
2475   (vl_api_create_vhost_user_if_reply_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   i32 retval = ntohl (mp->retval);
2479   if (vam->async_mode)
2480     {
2481       vam->async_errors += (retval < 0);
2482     }
2483   else
2484     {
2485       vam->retval = retval;
2486       vam->sw_if_index = ntohl (mp->sw_if_index);
2487       vam->result_ready = 1;
2488     }
2489   vam->regenerate_interface_table = 1;
2490 }
2491
2492 static void vl_api_create_vhost_user_if_reply_t_handler_json
2493   (vl_api_create_vhost_user_if_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   vat_json_node_t node;
2497
2498   vat_json_init_object (&node);
2499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2500   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2501
2502   vat_json_print (vam->ofp, &node);
2503   vat_json_free (&node);
2504
2505   vam->retval = ntohl (mp->retval);
2506   vam->result_ready = 1;
2507 }
2508
2509 static void vl_api_dns_resolve_name_reply_t_handler
2510   (vl_api_dns_resolve_name_reply_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   i32 retval = ntohl (mp->retval);
2514   if (vam->async_mode)
2515     {
2516       vam->async_errors += (retval < 0);
2517     }
2518   else
2519     {
2520       vam->retval = retval;
2521       vam->result_ready = 1;
2522
2523       if (retval == 0)
2524         {
2525           if (mp->ip4_set)
2526             clib_warning ("ip4 address %U", format_ip4_address,
2527                           (ip4_address_t *) mp->ip4_address);
2528           if (mp->ip6_set)
2529             clib_warning ("ip6 address %U", format_ip6_address,
2530                           (ip6_address_t *) mp->ip6_address);
2531         }
2532       else
2533         clib_warning ("retval %d", retval);
2534     }
2535 }
2536
2537 static void vl_api_dns_resolve_name_reply_t_handler_json
2538   (vl_api_dns_resolve_name_reply_t * mp)
2539 {
2540   clib_warning ("not implemented");
2541 }
2542
2543 static void vl_api_dns_resolve_ip_reply_t_handler
2544   (vl_api_dns_resolve_ip_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   i32 retval = ntohl (mp->retval);
2548   if (vam->async_mode)
2549     {
2550       vam->async_errors += (retval < 0);
2551     }
2552   else
2553     {
2554       vam->retval = retval;
2555       vam->result_ready = 1;
2556
2557       if (retval == 0)
2558         {
2559           clib_warning ("canonical name %s", mp->name);
2560         }
2561       else
2562         clib_warning ("retval %d", retval);
2563     }
2564 }
2565
2566 static void vl_api_dns_resolve_ip_reply_t_handler_json
2567   (vl_api_dns_resolve_ip_reply_t * mp)
2568 {
2569   clib_warning ("not implemented");
2570 }
2571
2572
2573 static void vl_api_ip_address_details_t_handler
2574   (vl_api_ip_address_details_t * mp)
2575 {
2576   vat_main_t *vam = &vat_main;
2577   static ip_address_details_t empty_ip_address_details = { {0} };
2578   ip_address_details_t *address = NULL;
2579   ip_details_t *current_ip_details = NULL;
2580   ip_details_t *details = NULL;
2581
2582   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2583
2584   if (!details || vam->current_sw_if_index >= vec_len (details)
2585       || !details[vam->current_sw_if_index].present)
2586     {
2587       errmsg ("ip address details arrived but not stored");
2588       errmsg ("ip_dump should be called first");
2589       return;
2590     }
2591
2592   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2593
2594 #define addresses (current_ip_details->addr)
2595
2596   vec_validate_init_empty (addresses, vec_len (addresses),
2597                            empty_ip_address_details);
2598
2599   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2600
2601   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2602   address->prefix_length = mp->prefix_length;
2603 #undef addresses
2604 }
2605
2606 static void vl_api_ip_address_details_t_handler_json
2607   (vl_api_ip_address_details_t * mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   vat_json_node_t *node = NULL;
2611   struct in6_addr ip6;
2612   struct in_addr ip4;
2613
2614   if (VAT_JSON_ARRAY != vam->json_tree.type)
2615     {
2616       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2617       vat_json_init_array (&vam->json_tree);
2618     }
2619   node = vat_json_array_add (&vam->json_tree);
2620
2621   vat_json_init_object (node);
2622   if (vam->is_ipv6)
2623     {
2624       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2625       vat_json_object_add_ip6 (node, "ip", ip6);
2626     }
2627   else
2628     {
2629       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2630       vat_json_object_add_ip4 (node, "ip", ip4);
2631     }
2632   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2633 }
2634
2635 static void
2636 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   static ip_details_t empty_ip_details = { 0 };
2640   ip_details_t *ip = NULL;
2641   u32 sw_if_index = ~0;
2642
2643   sw_if_index = ntohl (mp->sw_if_index);
2644
2645   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2646                            sw_if_index, empty_ip_details);
2647
2648   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2649                          sw_if_index);
2650
2651   ip->present = 1;
2652 }
2653
2654 static void
2655 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2656 {
2657   vat_main_t *vam = &vat_main;
2658
2659   if (VAT_JSON_ARRAY != vam->json_tree.type)
2660     {
2661       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2662       vat_json_init_array (&vam->json_tree);
2663     }
2664   vat_json_array_add_uint (&vam->json_tree,
2665                            clib_net_to_host_u32 (mp->sw_if_index));
2666 }
2667
2668 static void
2669 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2670 {
2671   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2672           "router_addr %U host_mac %U",
2673           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2674           mp->lease.hostname,
2675           format_ip4_address, &mp->lease.host_address,
2676           format_ip4_address, &mp->lease.router_address,
2677           format_ethernet_address, mp->lease.host_mac);
2678 }
2679
2680 static void vl_api_dhcp_compl_event_t_handler_json
2681   (vl_api_dhcp_compl_event_t * mp)
2682 {
2683   /* JSON output not supported */
2684 }
2685
2686 static void vl_api_get_first_msg_id_reply_t_handler
2687   (vl_api_get_first_msg_id_reply_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   i32 retval = ntohl (mp->retval);
2691
2692   if (vam->async_mode)
2693     {
2694       vam->async_errors += (retval < 0);
2695     }
2696   else
2697     {
2698       vam->retval = retval;
2699       vam->result_ready = 1;
2700     }
2701   if (retval >= 0)
2702     {
2703       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2704     }
2705 }
2706
2707 static void vl_api_get_first_msg_id_reply_t_handler_json
2708   (vl_api_get_first_msg_id_reply_t * mp)
2709 {
2710   vat_main_t *vam = &vat_main;
2711   vat_json_node_t node;
2712
2713   vat_json_init_object (&node);
2714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2715   vat_json_object_add_uint (&node, "first_msg_id",
2716                             (uint) ntohs (mp->first_msg_id));
2717
2718   vat_json_print (vam->ofp, &node);
2719   vat_json_free (&node);
2720
2721   vam->retval = ntohl (mp->retval);
2722   vam->result_ready = 1;
2723 }
2724
2725 static void vl_api_get_node_graph_reply_t_handler
2726   (vl_api_get_node_graph_reply_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   api_main_t *am = &api_main;
2730   i32 retval = ntohl (mp->retval);
2731   u8 *pvt_copy, *reply;
2732   void *oldheap;
2733   vlib_node_t *node;
2734   int i;
2735
2736   if (vam->async_mode)
2737     {
2738       vam->async_errors += (retval < 0);
2739     }
2740   else
2741     {
2742       vam->retval = retval;
2743       vam->result_ready = 1;
2744     }
2745
2746   /* "Should never happen..." */
2747   if (retval != 0)
2748     return;
2749
2750   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2751   pvt_copy = vec_dup (reply);
2752
2753   /* Toss the shared-memory original... */
2754   pthread_mutex_lock (&am->vlib_rp->mutex);
2755   oldheap = svm_push_data_heap (am->vlib_rp);
2756
2757   vec_free (reply);
2758
2759   svm_pop_heap (oldheap);
2760   pthread_mutex_unlock (&am->vlib_rp->mutex);
2761
2762   if (vam->graph_nodes)
2763     {
2764       hash_free (vam->graph_node_index_by_name);
2765
2766       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2767         {
2768           node = vam->graph_nodes[0][i];
2769           vec_free (node->name);
2770           vec_free (node->next_nodes);
2771           vec_free (node);
2772         }
2773       vec_free (vam->graph_nodes[0]);
2774       vec_free (vam->graph_nodes);
2775     }
2776
2777   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2778   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2779   vec_free (pvt_copy);
2780
2781   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2782     {
2783       node = vam->graph_nodes[0][i];
2784       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2785     }
2786 }
2787
2788 static void vl_api_get_node_graph_reply_t_handler_json
2789   (vl_api_get_node_graph_reply_t * mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   api_main_t *am = &api_main;
2793   void *oldheap;
2794   vat_json_node_t node;
2795   u8 *reply;
2796
2797   /* $$$$ make this real? */
2798   vat_json_init_object (&node);
2799   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2800   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2801
2802   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2803
2804   /* Toss the shared-memory original... */
2805   pthread_mutex_lock (&am->vlib_rp->mutex);
2806   oldheap = svm_push_data_heap (am->vlib_rp);
2807
2808   vec_free (reply);
2809
2810   svm_pop_heap (oldheap);
2811   pthread_mutex_unlock (&am->vlib_rp->mutex);
2812
2813   vat_json_print (vam->ofp, &node);
2814   vat_json_free (&node);
2815
2816   vam->retval = ntohl (mp->retval);
2817   vam->result_ready = 1;
2818 }
2819
2820 static void
2821 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2822 {
2823   vat_main_t *vam = &vat_main;
2824   u8 *s = 0;
2825
2826   if (mp->local)
2827     {
2828       s = format (s, "%=16d%=16d%=16d",
2829                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2830     }
2831   else
2832     {
2833       s = format (s, "%=16U%=16d%=16d",
2834                   mp->is_ipv6 ? format_ip6_address :
2835                   format_ip4_address,
2836                   mp->ip_address, mp->priority, mp->weight);
2837     }
2838
2839   print (vam->ofp, "%v", s);
2840   vec_free (s);
2841 }
2842
2843 static void
2844 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   vat_json_node_t *node = NULL;
2848   struct in6_addr ip6;
2849   struct in_addr ip4;
2850
2851   if (VAT_JSON_ARRAY != vam->json_tree.type)
2852     {
2853       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2854       vat_json_init_array (&vam->json_tree);
2855     }
2856   node = vat_json_array_add (&vam->json_tree);
2857   vat_json_init_object (node);
2858
2859   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2860   vat_json_object_add_uint (node, "priority", mp->priority);
2861   vat_json_object_add_uint (node, "weight", mp->weight);
2862
2863   if (mp->local)
2864     vat_json_object_add_uint (node, "sw_if_index",
2865                               clib_net_to_host_u32 (mp->sw_if_index));
2866   else
2867     {
2868       if (mp->is_ipv6)
2869         {
2870           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2871           vat_json_object_add_ip6 (node, "address", ip6);
2872         }
2873       else
2874         {
2875           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2876           vat_json_object_add_ip4 (node, "address", ip4);
2877         }
2878     }
2879 }
2880
2881 static void
2882 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2883                                           mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886   u8 *ls_name = 0;
2887
2888   ls_name = format (0, "%s", mp->ls_name);
2889
2890   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2891          ls_name);
2892   vec_free (ls_name);
2893 }
2894
2895 static void
2896   vl_api_one_locator_set_details_t_handler_json
2897   (vl_api_one_locator_set_details_t * mp)
2898 {
2899   vat_main_t *vam = &vat_main;
2900   vat_json_node_t *node = 0;
2901   u8 *ls_name = 0;
2902
2903   ls_name = format (0, "%s", mp->ls_name);
2904   vec_add1 (ls_name, 0);
2905
2906   if (VAT_JSON_ARRAY != vam->json_tree.type)
2907     {
2908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2909       vat_json_init_array (&vam->json_tree);
2910     }
2911   node = vat_json_array_add (&vam->json_tree);
2912
2913   vat_json_init_object (node);
2914   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2915   vat_json_object_add_uint (node, "ls_index",
2916                             clib_net_to_host_u32 (mp->ls_index));
2917   vec_free (ls_name);
2918 }
2919
2920 typedef struct
2921 {
2922   u32 spi;
2923   u8 si;
2924 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2925
2926 uword
2927 unformat_nsh_address (unformat_input_t * input, va_list * args)
2928 {
2929   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2930   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2931 }
2932
2933 u8 *
2934 format_nsh_address_vat (u8 * s, va_list * args)
2935 {
2936   nsh_t *a = va_arg (*args, nsh_t *);
2937   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2938 }
2939
2940 static u8 *
2941 format_lisp_flat_eid (u8 * s, va_list * args)
2942 {
2943   u32 type = va_arg (*args, u32);
2944   u8 *eid = va_arg (*args, u8 *);
2945   u32 eid_len = va_arg (*args, u32);
2946
2947   switch (type)
2948     {
2949     case 0:
2950       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2951     case 1:
2952       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2953     case 2:
2954       return format (s, "%U", format_ethernet_address, eid);
2955     case 3:
2956       return format (s, "%U", format_nsh_address_vat, eid);
2957     }
2958   return 0;
2959 }
2960
2961 static u8 *
2962 format_lisp_eid_vat (u8 * s, va_list * args)
2963 {
2964   u32 type = va_arg (*args, u32);
2965   u8 *eid = va_arg (*args, u8 *);
2966   u32 eid_len = va_arg (*args, u32);
2967   u8 *seid = va_arg (*args, u8 *);
2968   u32 seid_len = va_arg (*args, u32);
2969   u32 is_src_dst = va_arg (*args, u32);
2970
2971   if (is_src_dst)
2972     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2973
2974   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2975
2976   return s;
2977 }
2978
2979 static void
2980 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2981 {
2982   vat_main_t *vam = &vat_main;
2983   u8 *s = 0, *eid = 0;
2984
2985   if (~0 == mp->locator_set_index)
2986     s = format (0, "action: %d", mp->action);
2987   else
2988     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2989
2990   eid = format (0, "%U", format_lisp_eid_vat,
2991                 mp->eid_type,
2992                 mp->eid,
2993                 mp->eid_prefix_len,
2994                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2995   vec_add1 (eid, 0);
2996
2997   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2998          clib_net_to_host_u32 (mp->vni),
2999          eid,
3000          mp->is_local ? "local" : "remote",
3001          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3002          clib_net_to_host_u16 (mp->key_id), mp->key);
3003
3004   vec_free (s);
3005   vec_free (eid);
3006 }
3007
3008 static void
3009 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3010                                              * mp)
3011 {
3012   vat_main_t *vam = &vat_main;
3013   vat_json_node_t *node = 0;
3014   u8 *eid = 0;
3015
3016   if (VAT_JSON_ARRAY != vam->json_tree.type)
3017     {
3018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3019       vat_json_init_array (&vam->json_tree);
3020     }
3021   node = vat_json_array_add (&vam->json_tree);
3022
3023   vat_json_init_object (node);
3024   if (~0 == mp->locator_set_index)
3025     vat_json_object_add_uint (node, "action", mp->action);
3026   else
3027     vat_json_object_add_uint (node, "locator_set_index",
3028                               clib_net_to_host_u32 (mp->locator_set_index));
3029
3030   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3031   if (mp->eid_type == 3)
3032     {
3033       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3034       vat_json_init_object (nsh_json);
3035       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3036       vat_json_object_add_uint (nsh_json, "spi",
3037                                 clib_net_to_host_u32 (nsh->spi));
3038       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3039     }
3040   else
3041     {
3042       eid = format (0, "%U", format_lisp_eid_vat,
3043                     mp->eid_type,
3044                     mp->eid,
3045                     mp->eid_prefix_len,
3046                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3047       vec_add1 (eid, 0);
3048       vat_json_object_add_string_copy (node, "eid", eid);
3049       vec_free (eid);
3050     }
3051   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3052   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3053   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3054
3055   if (mp->key_id)
3056     {
3057       vat_json_object_add_uint (node, "key_id",
3058                                 clib_net_to_host_u16 (mp->key_id));
3059       vat_json_object_add_string_copy (node, "key", mp->key);
3060     }
3061 }
3062
3063 static void
3064 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3065 {
3066   vat_main_t *vam = &vat_main;
3067   u8 *seid = 0, *deid = 0;
3068   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3069
3070   deid = format (0, "%U", format_lisp_eid_vat,
3071                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3072
3073   seid = format (0, "%U", format_lisp_eid_vat,
3074                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3075
3076   vec_add1 (deid, 0);
3077   vec_add1 (seid, 0);
3078
3079   if (mp->is_ip4)
3080     format_ip_address_fcn = format_ip4_address;
3081   else
3082     format_ip_address_fcn = format_ip6_address;
3083
3084
3085   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3086          clib_net_to_host_u32 (mp->vni),
3087          seid, deid,
3088          format_ip_address_fcn, mp->lloc,
3089          format_ip_address_fcn, mp->rloc,
3090          clib_net_to_host_u32 (mp->pkt_count),
3091          clib_net_to_host_u32 (mp->bytes));
3092
3093   vec_free (deid);
3094   vec_free (seid);
3095 }
3096
3097 static void
3098 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3099 {
3100   struct in6_addr ip6;
3101   struct in_addr ip4;
3102   vat_main_t *vam = &vat_main;
3103   vat_json_node_t *node = 0;
3104   u8 *deid = 0, *seid = 0;
3105
3106   if (VAT_JSON_ARRAY != vam->json_tree.type)
3107     {
3108       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3109       vat_json_init_array (&vam->json_tree);
3110     }
3111   node = vat_json_array_add (&vam->json_tree);
3112
3113   vat_json_init_object (node);
3114   deid = format (0, "%U", format_lisp_eid_vat,
3115                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3116
3117   seid = format (0, "%U", format_lisp_eid_vat,
3118                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3119
3120   vec_add1 (deid, 0);
3121   vec_add1 (seid, 0);
3122
3123   vat_json_object_add_string_copy (node, "seid", seid);
3124   vat_json_object_add_string_copy (node, "deid", deid);
3125   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3126
3127   if (mp->is_ip4)
3128     {
3129       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3130       vat_json_object_add_ip4 (node, "lloc", ip4);
3131       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3132       vat_json_object_add_ip4 (node, "rloc", ip4);
3133     }
3134   else
3135     {
3136       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3137       vat_json_object_add_ip6 (node, "lloc", ip6);
3138       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3139       vat_json_object_add_ip6 (node, "rloc", ip6);
3140     }
3141   vat_json_object_add_uint (node, "pkt_count",
3142                             clib_net_to_host_u32 (mp->pkt_count));
3143   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3144
3145   vec_free (deid);
3146   vec_free (seid);
3147 }
3148
3149 static void
3150   vl_api_one_eid_table_map_details_t_handler
3151   (vl_api_one_eid_table_map_details_t * mp)
3152 {
3153   vat_main_t *vam = &vat_main;
3154
3155   u8 *line = format (0, "%=10d%=10d",
3156                      clib_net_to_host_u32 (mp->vni),
3157                      clib_net_to_host_u32 (mp->dp_table));
3158   print (vam->ofp, "%v", line);
3159   vec_free (line);
3160 }
3161
3162 static void
3163   vl_api_one_eid_table_map_details_t_handler_json
3164   (vl_api_one_eid_table_map_details_t * mp)
3165 {
3166   vat_main_t *vam = &vat_main;
3167   vat_json_node_t *node = NULL;
3168
3169   if (VAT_JSON_ARRAY != vam->json_tree.type)
3170     {
3171       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3172       vat_json_init_array (&vam->json_tree);
3173     }
3174   node = vat_json_array_add (&vam->json_tree);
3175   vat_json_init_object (node);
3176   vat_json_object_add_uint (node, "dp_table",
3177                             clib_net_to_host_u32 (mp->dp_table));
3178   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3179 }
3180
3181 static void
3182   vl_api_one_eid_table_vni_details_t_handler
3183   (vl_api_one_eid_table_vni_details_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186
3187   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3188   print (vam->ofp, "%v", line);
3189   vec_free (line);
3190 }
3191
3192 static void
3193   vl_api_one_eid_table_vni_details_t_handler_json
3194   (vl_api_one_eid_table_vni_details_t * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   vat_json_node_t *node = NULL;
3198
3199   if (VAT_JSON_ARRAY != vam->json_tree.type)
3200     {
3201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3202       vat_json_init_array (&vam->json_tree);
3203     }
3204   node = vat_json_array_add (&vam->json_tree);
3205   vat_json_init_object (node);
3206   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3207 }
3208
3209 static void
3210   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3211   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   int retval = clib_net_to_host_u32 (mp->retval);
3215
3216   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3217   print (vam->ofp, "fallback threshold value: %d", mp->value);
3218
3219   vam->retval = retval;
3220   vam->result_ready = 1;
3221 }
3222
3223 static void
3224   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3225   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3226 {
3227   vat_main_t *vam = &vat_main;
3228   vat_json_node_t _node, *node = &_node;
3229   int retval = clib_net_to_host_u32 (mp->retval);
3230
3231   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3232   vat_json_init_object (node);
3233   vat_json_object_add_uint (node, "value", mp->value);
3234
3235   vat_json_print (vam->ofp, node);
3236   vat_json_free (node);
3237
3238   vam->retval = retval;
3239   vam->result_ready = 1;
3240 }
3241
3242 static void
3243   vl_api_show_one_map_register_state_reply_t_handler
3244   (vl_api_show_one_map_register_state_reply_t * mp)
3245 {
3246   vat_main_t *vam = &vat_main;
3247   int retval = clib_net_to_host_u32 (mp->retval);
3248
3249   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3250
3251   vam->retval = retval;
3252   vam->result_ready = 1;
3253 }
3254
3255 static void
3256   vl_api_show_one_map_register_state_reply_t_handler_json
3257   (vl_api_show_one_map_register_state_reply_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   vat_json_node_t _node, *node = &_node;
3261   int retval = clib_net_to_host_u32 (mp->retval);
3262
3263   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3264
3265   vat_json_init_object (node);
3266   vat_json_object_add_string_copy (node, "state", s);
3267
3268   vat_json_print (vam->ofp, node);
3269   vat_json_free (node);
3270
3271   vam->retval = retval;
3272   vam->result_ready = 1;
3273   vec_free (s);
3274 }
3275
3276 static void
3277   vl_api_show_one_rloc_probe_state_reply_t_handler
3278   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   int retval = clib_net_to_host_u32 (mp->retval);
3282
3283   if (retval)
3284     goto end;
3285
3286   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3287 end:
3288   vam->retval = retval;
3289   vam->result_ready = 1;
3290 }
3291
3292 static void
3293   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3294   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   vat_json_node_t _node, *node = &_node;
3298   int retval = clib_net_to_host_u32 (mp->retval);
3299
3300   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3301   vat_json_init_object (node);
3302   vat_json_object_add_string_copy (node, "state", s);
3303
3304   vat_json_print (vam->ofp, node);
3305   vat_json_free (node);
3306
3307   vam->retval = retval;
3308   vam->result_ready = 1;
3309   vec_free (s);
3310 }
3311
3312 static void
3313   vl_api_show_one_stats_enable_disable_reply_t_handler
3314   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   int retval = clib_net_to_host_u32 (mp->retval);
3318
3319   if (retval)
3320     goto end;
3321
3322   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3323 end:
3324   vam->retval = retval;
3325   vam->result_ready = 1;
3326 }
3327
3328 static void
3329   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3330   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3331 {
3332   vat_main_t *vam = &vat_main;
3333   vat_json_node_t _node, *node = &_node;
3334   int retval = clib_net_to_host_u32 (mp->retval);
3335
3336   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3337   vat_json_init_object (node);
3338   vat_json_object_add_string_copy (node, "state", s);
3339
3340   vat_json_print (vam->ofp, node);
3341   vat_json_free (node);
3342
3343   vam->retval = retval;
3344   vam->result_ready = 1;
3345   vec_free (s);
3346 }
3347
3348 static void
3349 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3350 {
3351   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3352   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3353   e->vni = clib_net_to_host_u32 (e->vni);
3354 }
3355
3356 static void
3357   gpe_fwd_entries_get_reply_t_net_to_host
3358   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3359 {
3360   u32 i;
3361
3362   mp->count = clib_net_to_host_u32 (mp->count);
3363   for (i = 0; i < mp->count; i++)
3364     {
3365       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3366     }
3367 }
3368
3369 static u8 *
3370 format_gpe_encap_mode (u8 * s, va_list * args)
3371 {
3372   u32 mode = va_arg (*args, u32);
3373
3374   switch (mode)
3375     {
3376     case 0:
3377       return format (s, "lisp");
3378     case 1:
3379       return format (s, "vxlan");
3380     }
3381   return 0;
3382 }
3383
3384 static void
3385   vl_api_gpe_get_encap_mode_reply_t_handler
3386   (vl_api_gpe_get_encap_mode_reply_t * mp)
3387 {
3388   vat_main_t *vam = &vat_main;
3389
3390   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3391   vam->retval = ntohl (mp->retval);
3392   vam->result_ready = 1;
3393 }
3394
3395 static void
3396   vl_api_gpe_get_encap_mode_reply_t_handler_json
3397   (vl_api_gpe_get_encap_mode_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   vat_json_node_t node;
3401
3402   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3403   vec_add1 (encap_mode, 0);
3404
3405   vat_json_init_object (&node);
3406   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3407
3408   vec_free (encap_mode);
3409   vat_json_print (vam->ofp, &node);
3410   vat_json_free (&node);
3411
3412   vam->retval = ntohl (mp->retval);
3413   vam->result_ready = 1;
3414 }
3415
3416 static void
3417   vl_api_gpe_fwd_entry_path_details_t_handler
3418   (vl_api_gpe_fwd_entry_path_details_t * mp)
3419 {
3420   vat_main_t *vam = &vat_main;
3421   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3422
3423   if (mp->lcl_loc.is_ip4)
3424     format_ip_address_fcn = format_ip4_address;
3425   else
3426     format_ip_address_fcn = format_ip6_address;
3427
3428   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3429          format_ip_address_fcn, &mp->lcl_loc,
3430          format_ip_address_fcn, &mp->rmt_loc);
3431 }
3432
3433 static void
3434 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3435 {
3436   struct in6_addr ip6;
3437   struct in_addr ip4;
3438
3439   if (loc->is_ip4)
3440     {
3441       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3442       vat_json_object_add_ip4 (n, "address", ip4);
3443     }
3444   else
3445     {
3446       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3447       vat_json_object_add_ip6 (n, "address", ip6);
3448     }
3449   vat_json_object_add_uint (n, "weight", loc->weight);
3450 }
3451
3452 static void
3453   vl_api_gpe_fwd_entry_path_details_t_handler_json
3454   (vl_api_gpe_fwd_entry_path_details_t * mp)
3455 {
3456   vat_main_t *vam = &vat_main;
3457   vat_json_node_t *node = NULL;
3458   vat_json_node_t *loc_node;
3459
3460   if (VAT_JSON_ARRAY != vam->json_tree.type)
3461     {
3462       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3463       vat_json_init_array (&vam->json_tree);
3464     }
3465   node = vat_json_array_add (&vam->json_tree);
3466   vat_json_init_object (node);
3467
3468   loc_node = vat_json_object_add (node, "local_locator");
3469   vat_json_init_object (loc_node);
3470   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3471
3472   loc_node = vat_json_object_add (node, "remote_locator");
3473   vat_json_init_object (loc_node);
3474   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3475 }
3476
3477 static void
3478   vl_api_gpe_fwd_entries_get_reply_t_handler
3479   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3480 {
3481   vat_main_t *vam = &vat_main;
3482   u32 i;
3483   int retval = clib_net_to_host_u32 (mp->retval);
3484   vl_api_gpe_fwd_entry_t *e;
3485
3486   if (retval)
3487     goto end;
3488
3489   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3490
3491   for (i = 0; i < mp->count; i++)
3492     {
3493       e = &mp->entries[i];
3494       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3495              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3496              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3497     }
3498
3499 end:
3500   vam->retval = retval;
3501   vam->result_ready = 1;
3502 }
3503
3504 static void
3505   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3506   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3507 {
3508   u8 *s = 0;
3509   vat_main_t *vam = &vat_main;
3510   vat_json_node_t *e = 0, root;
3511   u32 i;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513   vl_api_gpe_fwd_entry_t *fwd;
3514
3515   if (retval)
3516     goto end;
3517
3518   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3519   vat_json_init_array (&root);
3520
3521   for (i = 0; i < mp->count; i++)
3522     {
3523       e = vat_json_array_add (&root);
3524       fwd = &mp->entries[i];
3525
3526       vat_json_init_object (e);
3527       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3528       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3529       vat_json_object_add_int (e, "vni", fwd->vni);
3530       vat_json_object_add_int (e, "action", fwd->action);
3531
3532       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3533                   fwd->leid_prefix_len);
3534       vec_add1 (s, 0);
3535       vat_json_object_add_string_copy (e, "leid", s);
3536       vec_free (s);
3537
3538       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3539                   fwd->reid_prefix_len);
3540       vec_add1 (s, 0);
3541       vat_json_object_add_string_copy (e, "reid", s);
3542       vec_free (s);
3543     }
3544
3545   vat_json_print (vam->ofp, &root);
3546   vat_json_free (&root);
3547
3548 end:
3549   vam->retval = retval;
3550   vam->result_ready = 1;
3551 }
3552
3553 static void
3554   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3555   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3556 {
3557   vat_main_t *vam = &vat_main;
3558   u32 i, n;
3559   int retval = clib_net_to_host_u32 (mp->retval);
3560   vl_api_gpe_native_fwd_rpath_t *r;
3561
3562   if (retval)
3563     goto end;
3564
3565   n = clib_net_to_host_u32 (mp->count);
3566
3567   for (i = 0; i < n; i++)
3568     {
3569       r = &mp->entries[i];
3570       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3571              clib_net_to_host_u32 (r->fib_index),
3572              clib_net_to_host_u32 (r->nh_sw_if_index),
3573              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3574     }
3575
3576 end:
3577   vam->retval = retval;
3578   vam->result_ready = 1;
3579 }
3580
3581 static void
3582   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3583   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3584 {
3585   vat_main_t *vam = &vat_main;
3586   vat_json_node_t root, *e;
3587   u32 i, n;
3588   int retval = clib_net_to_host_u32 (mp->retval);
3589   vl_api_gpe_native_fwd_rpath_t *r;
3590   u8 *s;
3591
3592   if (retval)
3593     goto end;
3594
3595   n = clib_net_to_host_u32 (mp->count);
3596   vat_json_init_array (&root);
3597
3598   for (i = 0; i < n; i++)
3599     {
3600       e = vat_json_array_add (&root);
3601       vat_json_init_object (e);
3602       r = &mp->entries[i];
3603       s =
3604         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3605                 r->nh_addr);
3606       vec_add1 (s, 0);
3607       vat_json_object_add_string_copy (e, "ip4", s);
3608       vec_free (s);
3609
3610       vat_json_object_add_uint (e, "fib_index",
3611                                 clib_net_to_host_u32 (r->fib_index));
3612       vat_json_object_add_uint (e, "nh_sw_if_index",
3613                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3614     }
3615
3616   vat_json_print (vam->ofp, &root);
3617   vat_json_free (&root);
3618
3619 end:
3620   vam->retval = retval;
3621   vam->result_ready = 1;
3622 }
3623
3624 static void
3625   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3626   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3627 {
3628   vat_main_t *vam = &vat_main;
3629   u32 i, n;
3630   int retval = clib_net_to_host_u32 (mp->retval);
3631
3632   if (retval)
3633     goto end;
3634
3635   n = clib_net_to_host_u32 (mp->count);
3636
3637   for (i = 0; i < n; i++)
3638     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3639
3640 end:
3641   vam->retval = retval;
3642   vam->result_ready = 1;
3643 }
3644
3645 static void
3646   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3647   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3648 {
3649   vat_main_t *vam = &vat_main;
3650   vat_json_node_t root;
3651   u32 i, n;
3652   int retval = clib_net_to_host_u32 (mp->retval);
3653
3654   if (retval)
3655     goto end;
3656
3657   n = clib_net_to_host_u32 (mp->count);
3658   vat_json_init_array (&root);
3659
3660   for (i = 0; i < n; i++)
3661     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3662
3663   vat_json_print (vam->ofp, &root);
3664   vat_json_free (&root);
3665
3666 end:
3667   vam->retval = retval;
3668   vam->result_ready = 1;
3669 }
3670
3671 static void
3672   vl_api_one_ndp_entries_get_reply_t_handler
3673   (vl_api_one_ndp_entries_get_reply_t * mp)
3674 {
3675   vat_main_t *vam = &vat_main;
3676   u32 i, n;
3677   int retval = clib_net_to_host_u32 (mp->retval);
3678
3679   if (retval)
3680     goto end;
3681
3682   n = clib_net_to_host_u32 (mp->count);
3683
3684   for (i = 0; i < n; i++)
3685     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3686            format_ethernet_address, mp->entries[i].mac);
3687
3688 end:
3689   vam->retval = retval;
3690   vam->result_ready = 1;
3691 }
3692
3693 static void
3694   vl_api_one_ndp_entries_get_reply_t_handler_json
3695   (vl_api_one_ndp_entries_get_reply_t * mp)
3696 {
3697   u8 *s = 0;
3698   vat_main_t *vam = &vat_main;
3699   vat_json_node_t *e = 0, root;
3700   u32 i, n;
3701   int retval = clib_net_to_host_u32 (mp->retval);
3702   vl_api_one_ndp_entry_t *arp_entry;
3703
3704   if (retval)
3705     goto end;
3706
3707   n = clib_net_to_host_u32 (mp->count);
3708   vat_json_init_array (&root);
3709
3710   for (i = 0; i < n; i++)
3711     {
3712       e = vat_json_array_add (&root);
3713       arp_entry = &mp->entries[i];
3714
3715       vat_json_init_object (e);
3716       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3717       vec_add1 (s, 0);
3718
3719       vat_json_object_add_string_copy (e, "mac", s);
3720       vec_free (s);
3721
3722       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3723       vec_add1 (s, 0);
3724       vat_json_object_add_string_copy (e, "ip6", s);
3725       vec_free (s);
3726     }
3727
3728   vat_json_print (vam->ofp, &root);
3729   vat_json_free (&root);
3730
3731 end:
3732   vam->retval = retval;
3733   vam->result_ready = 1;
3734 }
3735
3736 static void
3737   vl_api_one_l2_arp_entries_get_reply_t_handler
3738   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3739 {
3740   vat_main_t *vam = &vat_main;
3741   u32 i, n;
3742   int retval = clib_net_to_host_u32 (mp->retval);
3743
3744   if (retval)
3745     goto end;
3746
3747   n = clib_net_to_host_u32 (mp->count);
3748
3749   for (i = 0; i < n; i++)
3750     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3751            format_ethernet_address, mp->entries[i].mac);
3752
3753 end:
3754   vam->retval = retval;
3755   vam->result_ready = 1;
3756 }
3757
3758 static void
3759   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3760   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3761 {
3762   u8 *s = 0;
3763   vat_main_t *vam = &vat_main;
3764   vat_json_node_t *e = 0, root;
3765   u32 i, n;
3766   int retval = clib_net_to_host_u32 (mp->retval);
3767   vl_api_one_l2_arp_entry_t *arp_entry;
3768
3769   if (retval)
3770     goto end;
3771
3772   n = clib_net_to_host_u32 (mp->count);
3773   vat_json_init_array (&root);
3774
3775   for (i = 0; i < n; i++)
3776     {
3777       e = vat_json_array_add (&root);
3778       arp_entry = &mp->entries[i];
3779
3780       vat_json_init_object (e);
3781       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3782       vec_add1 (s, 0);
3783
3784       vat_json_object_add_string_copy (e, "mac", s);
3785       vec_free (s);
3786
3787       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3788       vec_add1 (s, 0);
3789       vat_json_object_add_string_copy (e, "ip4", s);
3790       vec_free (s);
3791     }
3792
3793   vat_json_print (vam->ofp, &root);
3794   vat_json_free (&root);
3795
3796 end:
3797   vam->retval = retval;
3798   vam->result_ready = 1;
3799 }
3800
3801 static void
3802 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812
3813   for (i = 0; i < n; i++)
3814     {
3815       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3816     }
3817
3818 end:
3819   vam->retval = retval;
3820   vam->result_ready = 1;
3821 }
3822
3823 static void
3824   vl_api_one_ndp_bd_get_reply_t_handler_json
3825   (vl_api_one_ndp_bd_get_reply_t * mp)
3826 {
3827   vat_main_t *vam = &vat_main;
3828   vat_json_node_t root;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831
3832   if (retval)
3833     goto end;
3834
3835   n = clib_net_to_host_u32 (mp->count);
3836   vat_json_init_array (&root);
3837
3838   for (i = 0; i < n; i++)
3839     {
3840       vat_json_array_add_uint (&root,
3841                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3842     }
3843
3844   vat_json_print (vam->ofp, &root);
3845   vat_json_free (&root);
3846
3847 end:
3848   vam->retval = retval;
3849   vam->result_ready = 1;
3850 }
3851
3852 static void
3853   vl_api_one_l2_arp_bd_get_reply_t_handler
3854   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3855 {
3856   vat_main_t *vam = &vat_main;
3857   u32 i, n;
3858   int retval = clib_net_to_host_u32 (mp->retval);
3859
3860   if (retval)
3861     goto end;
3862
3863   n = clib_net_to_host_u32 (mp->count);
3864
3865   for (i = 0; i < n; i++)
3866     {
3867       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3868     }
3869
3870 end:
3871   vam->retval = retval;
3872   vam->result_ready = 1;
3873 }
3874
3875 static void
3876   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3877   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3878 {
3879   vat_main_t *vam = &vat_main;
3880   vat_json_node_t root;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883
3884   if (retval)
3885     goto end;
3886
3887   n = clib_net_to_host_u32 (mp->count);
3888   vat_json_init_array (&root);
3889
3890   for (i = 0; i < n; i++)
3891     {
3892       vat_json_array_add_uint (&root,
3893                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3894     }
3895
3896   vat_json_print (vam->ofp, &root);
3897   vat_json_free (&root);
3898
3899 end:
3900   vam->retval = retval;
3901   vam->result_ready = 1;
3902 }
3903
3904 static void
3905   vl_api_one_adjacencies_get_reply_t_handler
3906   (vl_api_one_adjacencies_get_reply_t * mp)
3907 {
3908   vat_main_t *vam = &vat_main;
3909   u32 i, n;
3910   int retval = clib_net_to_host_u32 (mp->retval);
3911   vl_api_one_adjacency_t *a;
3912
3913   if (retval)
3914     goto end;
3915
3916   n = clib_net_to_host_u32 (mp->count);
3917
3918   for (i = 0; i < n; i++)
3919     {
3920       a = &mp->adjacencies[i];
3921       print (vam->ofp, "%U %40U",
3922              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3923              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3924     }
3925
3926 end:
3927   vam->retval = retval;
3928   vam->result_ready = 1;
3929 }
3930
3931 static void
3932   vl_api_one_adjacencies_get_reply_t_handler_json
3933   (vl_api_one_adjacencies_get_reply_t * mp)
3934 {
3935   u8 *s = 0;
3936   vat_main_t *vam = &vat_main;
3937   vat_json_node_t *e = 0, root;
3938   u32 i, n;
3939   int retval = clib_net_to_host_u32 (mp->retval);
3940   vl_api_one_adjacency_t *a;
3941
3942   if (retval)
3943     goto end;
3944
3945   n = clib_net_to_host_u32 (mp->count);
3946   vat_json_init_array (&root);
3947
3948   for (i = 0; i < n; i++)
3949     {
3950       e = vat_json_array_add (&root);
3951       a = &mp->adjacencies[i];
3952
3953       vat_json_init_object (e);
3954       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3955                   a->leid_prefix_len);
3956       vec_add1 (s, 0);
3957       vat_json_object_add_string_copy (e, "leid", s);
3958       vec_free (s);
3959
3960       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3961                   a->reid_prefix_len);
3962       vec_add1 (s, 0);
3963       vat_json_object_add_string_copy (e, "reid", s);
3964       vec_free (s);
3965     }
3966
3967   vat_json_print (vam->ofp, &root);
3968   vat_json_free (&root);
3969
3970 end:
3971   vam->retval = retval;
3972   vam->result_ready = 1;
3973 }
3974
3975 static void
3976 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3977 {
3978   vat_main_t *vam = &vat_main;
3979
3980   print (vam->ofp, "%=20U",
3981          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3982          mp->ip_address);
3983 }
3984
3985 static void
3986   vl_api_one_map_server_details_t_handler_json
3987   (vl_api_one_map_server_details_t * mp)
3988 {
3989   vat_main_t *vam = &vat_main;
3990   vat_json_node_t *node = NULL;
3991   struct in6_addr ip6;
3992   struct in_addr ip4;
3993
3994   if (VAT_JSON_ARRAY != vam->json_tree.type)
3995     {
3996       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3997       vat_json_init_array (&vam->json_tree);
3998     }
3999   node = vat_json_array_add (&vam->json_tree);
4000
4001   vat_json_init_object (node);
4002   if (mp->is_ipv6)
4003     {
4004       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4005       vat_json_object_add_ip6 (node, "map-server", ip6);
4006     }
4007   else
4008     {
4009       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4010       vat_json_object_add_ip4 (node, "map-server", ip4);
4011     }
4012 }
4013
4014 static void
4015 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4016                                            * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019
4020   print (vam->ofp, "%=20U",
4021          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4022          mp->ip_address);
4023 }
4024
4025 static void
4026   vl_api_one_map_resolver_details_t_handler_json
4027   (vl_api_one_map_resolver_details_t * mp)
4028 {
4029   vat_main_t *vam = &vat_main;
4030   vat_json_node_t *node = NULL;
4031   struct in6_addr ip6;
4032   struct in_addr ip4;
4033
4034   if (VAT_JSON_ARRAY != vam->json_tree.type)
4035     {
4036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4037       vat_json_init_array (&vam->json_tree);
4038     }
4039   node = vat_json_array_add (&vam->json_tree);
4040
4041   vat_json_init_object (node);
4042   if (mp->is_ipv6)
4043     {
4044       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4045       vat_json_object_add_ip6 (node, "map resolver", ip6);
4046     }
4047   else
4048     {
4049       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4050       vat_json_object_add_ip4 (node, "map resolver", ip4);
4051     }
4052 }
4053
4054 static void
4055 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4056 {
4057   vat_main_t *vam = &vat_main;
4058   i32 retval = ntohl (mp->retval);
4059
4060   if (0 <= retval)
4061     {
4062       print (vam->ofp, "feature: %s\ngpe: %s",
4063              mp->feature_status ? "enabled" : "disabled",
4064              mp->gpe_status ? "enabled" : "disabled");
4065     }
4066
4067   vam->retval = retval;
4068   vam->result_ready = 1;
4069 }
4070
4071 static void
4072   vl_api_show_one_status_reply_t_handler_json
4073   (vl_api_show_one_status_reply_t * mp)
4074 {
4075   vat_main_t *vam = &vat_main;
4076   vat_json_node_t node;
4077   u8 *gpe_status = NULL;
4078   u8 *feature_status = NULL;
4079
4080   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4081   feature_status = format (0, "%s",
4082                            mp->feature_status ? "enabled" : "disabled");
4083   vec_add1 (gpe_status, 0);
4084   vec_add1 (feature_status, 0);
4085
4086   vat_json_init_object (&node);
4087   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4088   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4089
4090   vec_free (gpe_status);
4091   vec_free (feature_status);
4092
4093   vat_json_print (vam->ofp, &node);
4094   vat_json_free (&node);
4095
4096   vam->retval = ntohl (mp->retval);
4097   vam->result_ready = 1;
4098 }
4099
4100 static void
4101   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4102   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4103 {
4104   vat_main_t *vam = &vat_main;
4105   i32 retval = ntohl (mp->retval);
4106
4107   if (retval >= 0)
4108     {
4109       print (vam->ofp, "%=20s", mp->locator_set_name);
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4118   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t *node = NULL;
4122
4123   if (VAT_JSON_ARRAY != vam->json_tree.type)
4124     {
4125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4126       vat_json_init_array (&vam->json_tree);
4127     }
4128   node = vat_json_array_add (&vam->json_tree);
4129
4130   vat_json_init_object (node);
4131   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4132
4133   vat_json_print (vam->ofp, node);
4134   vat_json_free (node);
4135
4136   vam->retval = ntohl (mp->retval);
4137   vam->result_ready = 1;
4138 }
4139
4140 static u8 *
4141 format_lisp_map_request_mode (u8 * s, va_list * args)
4142 {
4143   u32 mode = va_arg (*args, u32);
4144
4145   switch (mode)
4146     {
4147     case 0:
4148       return format (0, "dst-only");
4149     case 1:
4150       return format (0, "src-dst");
4151     }
4152   return 0;
4153 }
4154
4155 static void
4156   vl_api_show_one_map_request_mode_reply_t_handler
4157   (vl_api_show_one_map_request_mode_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   i32 retval = ntohl (mp->retval);
4161
4162   if (0 <= retval)
4163     {
4164       u32 mode = mp->mode;
4165       print (vam->ofp, "map_request_mode: %U",
4166              format_lisp_map_request_mode, mode);
4167     }
4168
4169   vam->retval = retval;
4170   vam->result_ready = 1;
4171 }
4172
4173 static void
4174   vl_api_show_one_map_request_mode_reply_t_handler_json
4175   (vl_api_show_one_map_request_mode_reply_t * mp)
4176 {
4177   vat_main_t *vam = &vat_main;
4178   vat_json_node_t node;
4179   u8 *s = 0;
4180   u32 mode;
4181
4182   mode = mp->mode;
4183   s = format (0, "%U", format_lisp_map_request_mode, mode);
4184   vec_add1 (s, 0);
4185
4186   vat_json_init_object (&node);
4187   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4188   vat_json_print (vam->ofp, &node);
4189   vat_json_free (&node);
4190
4191   vec_free (s);
4192   vam->retval = ntohl (mp->retval);
4193   vam->result_ready = 1;
4194 }
4195
4196 static void
4197   vl_api_one_show_xtr_mode_reply_t_handler
4198   (vl_api_one_show_xtr_mode_reply_t * mp)
4199 {
4200   vat_main_t *vam = &vat_main;
4201   i32 retval = ntohl (mp->retval);
4202
4203   if (0 <= retval)
4204     {
4205       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4206     }
4207
4208   vam->retval = retval;
4209   vam->result_ready = 1;
4210 }
4211
4212 static void
4213   vl_api_one_show_xtr_mode_reply_t_handler_json
4214   (vl_api_one_show_xtr_mode_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   vat_json_node_t node;
4218   u8 *status = 0;
4219
4220   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4221   vec_add1 (status, 0);
4222
4223   vat_json_init_object (&node);
4224   vat_json_object_add_string_copy (&node, "status", status);
4225
4226   vec_free (status);
4227
4228   vat_json_print (vam->ofp, &node);
4229   vat_json_free (&node);
4230
4231   vam->retval = ntohl (mp->retval);
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_one_show_pitr_mode_reply_t_handler
4237   (vl_api_one_show_pitr_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   i32 retval = ntohl (mp->retval);
4241
4242   if (0 <= retval)
4243     {
4244       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4245     }
4246
4247   vam->retval = retval;
4248   vam->result_ready = 1;
4249 }
4250
4251 static void
4252   vl_api_one_show_pitr_mode_reply_t_handler_json
4253   (vl_api_one_show_pitr_mode_reply_t * mp)
4254 {
4255   vat_main_t *vam = &vat_main;
4256   vat_json_node_t node;
4257   u8 *status = 0;
4258
4259   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4260   vec_add1 (status, 0);
4261
4262   vat_json_init_object (&node);
4263   vat_json_object_add_string_copy (&node, "status", status);
4264
4265   vec_free (status);
4266
4267   vat_json_print (vam->ofp, &node);
4268   vat_json_free (&node);
4269
4270   vam->retval = ntohl (mp->retval);
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_petr_mode_reply_t_handler
4276   (vl_api_one_show_petr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   i32 retval = ntohl (mp->retval);
4280
4281   if (0 <= retval)
4282     {
4283       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4284     }
4285
4286   vam->retval = retval;
4287   vam->result_ready = 1;
4288 }
4289
4290 static void
4291   vl_api_one_show_petr_mode_reply_t_handler_json
4292   (vl_api_one_show_petr_mode_reply_t * mp)
4293 {
4294   vat_main_t *vam = &vat_main;
4295   vat_json_node_t node;
4296   u8 *status = 0;
4297
4298   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4299   vec_add1 (status, 0);
4300
4301   vat_json_init_object (&node);
4302   vat_json_object_add_string_copy (&node, "status", status);
4303
4304   vec_free (status);
4305
4306   vat_json_print (vam->ofp, &node);
4307   vat_json_free (&node);
4308
4309   vam->retval = ntohl (mp->retval);
4310   vam->result_ready = 1;
4311 }
4312
4313 static void
4314   vl_api_show_one_use_petr_reply_t_handler
4315   (vl_api_show_one_use_petr_reply_t * mp)
4316 {
4317   vat_main_t *vam = &vat_main;
4318   i32 retval = ntohl (mp->retval);
4319
4320   if (0 <= retval)
4321     {
4322       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4323       if (mp->status)
4324         {
4325           print (vam->ofp, "Proxy-ETR address; %U",
4326                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4327                  mp->address);
4328         }
4329     }
4330
4331   vam->retval = retval;
4332   vam->result_ready = 1;
4333 }
4334
4335 static void
4336   vl_api_show_one_use_petr_reply_t_handler_json
4337   (vl_api_show_one_use_petr_reply_t * mp)
4338 {
4339   vat_main_t *vam = &vat_main;
4340   vat_json_node_t node;
4341   u8 *status = 0;
4342   struct in_addr ip4;
4343   struct in6_addr ip6;
4344
4345   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4346   vec_add1 (status, 0);
4347
4348   vat_json_init_object (&node);
4349   vat_json_object_add_string_copy (&node, "status", status);
4350   if (mp->status)
4351     {
4352       if (mp->is_ip4)
4353         {
4354           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4355           vat_json_object_add_ip6 (&node, "address", ip6);
4356         }
4357       else
4358         {
4359           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4360           vat_json_object_add_ip4 (&node, "address", ip4);
4361         }
4362     }
4363
4364   vec_free (status);
4365
4366   vat_json_print (vam->ofp, &node);
4367   vat_json_free (&node);
4368
4369   vam->retval = ntohl (mp->retval);
4370   vam->result_ready = 1;
4371 }
4372
4373 static void
4374   vl_api_show_one_nsh_mapping_reply_t_handler
4375   (vl_api_show_one_nsh_mapping_reply_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378   i32 retval = ntohl (mp->retval);
4379
4380   if (0 <= retval)
4381     {
4382       print (vam->ofp, "%-20s%-16s",
4383              mp->is_set ? "set" : "not-set",
4384              mp->is_set ? (char *) mp->locator_set_name : "");
4385     }
4386
4387   vam->retval = retval;
4388   vam->result_ready = 1;
4389 }
4390
4391 static void
4392   vl_api_show_one_nsh_mapping_reply_t_handler_json
4393   (vl_api_show_one_nsh_mapping_reply_t * mp)
4394 {
4395   vat_main_t *vam = &vat_main;
4396   vat_json_node_t node;
4397   u8 *status = 0;
4398
4399   status = format (0, "%s", mp->is_set ? "yes" : "no");
4400   vec_add1 (status, 0);
4401
4402   vat_json_init_object (&node);
4403   vat_json_object_add_string_copy (&node, "is_set", status);
4404   if (mp->is_set)
4405     {
4406       vat_json_object_add_string_copy (&node, "locator_set",
4407                                        mp->locator_set_name);
4408     }
4409
4410   vec_free (status);
4411
4412   vat_json_print (vam->ofp, &node);
4413   vat_json_free (&node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_show_one_map_register_ttl_reply_t_handler
4421   (vl_api_show_one_map_register_ttl_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   i32 retval = ntohl (mp->retval);
4425
4426   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4427
4428   if (0 <= retval)
4429     {
4430       print (vam->ofp, "ttl: %u", mp->ttl);
4431     }
4432
4433   vam->retval = retval;
4434   vam->result_ready = 1;
4435 }
4436
4437 static void
4438   vl_api_show_one_map_register_ttl_reply_t_handler_json
4439   (vl_api_show_one_map_register_ttl_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   vat_json_node_t node;
4443
4444   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4445   vat_json_init_object (&node);
4446   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4447
4448   vat_json_print (vam->ofp, &node);
4449   vat_json_free (&node);
4450
4451   vam->retval = ntohl (mp->retval);
4452   vam->result_ready = 1;
4453 }
4454
4455 static void
4456 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4457 {
4458   vat_main_t *vam = &vat_main;
4459   i32 retval = ntohl (mp->retval);
4460
4461   if (0 <= retval)
4462     {
4463       print (vam->ofp, "%-20s%-16s",
4464              mp->status ? "enabled" : "disabled",
4465              mp->status ? (char *) mp->locator_set_name : "");
4466     }
4467
4468   vam->retval = retval;
4469   vam->result_ready = 1;
4470 }
4471
4472 static void
4473 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4474 {
4475   vat_main_t *vam = &vat_main;
4476   vat_json_node_t node;
4477   u8 *status = 0;
4478
4479   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4480   vec_add1 (status, 0);
4481
4482   vat_json_init_object (&node);
4483   vat_json_object_add_string_copy (&node, "status", status);
4484   if (mp->status)
4485     {
4486       vat_json_object_add_string_copy (&node, "locator_set",
4487                                        mp->locator_set_name);
4488     }
4489
4490   vec_free (status);
4491
4492   vat_json_print (vam->ofp, &node);
4493   vat_json_free (&node);
4494
4495   vam->retval = ntohl (mp->retval);
4496   vam->result_ready = 1;
4497 }
4498
4499 static u8 *
4500 format_policer_type (u8 * s, va_list * va)
4501 {
4502   u32 i = va_arg (*va, u32);
4503
4504   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4505     s = format (s, "1r2c");
4506   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4507     s = format (s, "1r3c");
4508   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4509     s = format (s, "2r3c-2698");
4510   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4511     s = format (s, "2r3c-4115");
4512   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4513     s = format (s, "2r3c-mef5cf1");
4514   else
4515     s = format (s, "ILLEGAL");
4516   return s;
4517 }
4518
4519 static u8 *
4520 format_policer_rate_type (u8 * s, va_list * va)
4521 {
4522   u32 i = va_arg (*va, u32);
4523
4524   if (i == SSE2_QOS_RATE_KBPS)
4525     s = format (s, "kbps");
4526   else if (i == SSE2_QOS_RATE_PPS)
4527     s = format (s, "pps");
4528   else
4529     s = format (s, "ILLEGAL");
4530   return s;
4531 }
4532
4533 static u8 *
4534 format_policer_round_type (u8 * s, va_list * va)
4535 {
4536   u32 i = va_arg (*va, u32);
4537
4538   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4539     s = format (s, "closest");
4540   else if (i == SSE2_QOS_ROUND_TO_UP)
4541     s = format (s, "up");
4542   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4543     s = format (s, "down");
4544   else
4545     s = format (s, "ILLEGAL");
4546   return s;
4547 }
4548
4549 static u8 *
4550 format_policer_action_type (u8 * s, va_list * va)
4551 {
4552   u32 i = va_arg (*va, u32);
4553
4554   if (i == SSE2_QOS_ACTION_DROP)
4555     s = format (s, "drop");
4556   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4557     s = format (s, "transmit");
4558   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4559     s = format (s, "mark-and-transmit");
4560   else
4561     s = format (s, "ILLEGAL");
4562   return s;
4563 }
4564
4565 static u8 *
4566 format_dscp (u8 * s, va_list * va)
4567 {
4568   u32 i = va_arg (*va, u32);
4569   char *t = 0;
4570
4571   switch (i)
4572     {
4573 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4574       foreach_vnet_dscp
4575 #undef _
4576     default:
4577       return format (s, "ILLEGAL");
4578     }
4579   s = format (s, "%s", t);
4580   return s;
4581 }
4582
4583 static void
4584 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4585 {
4586   vat_main_t *vam = &vat_main;
4587   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4588
4589   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4590     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4591   else
4592     conform_dscp_str = format (0, "");
4593
4594   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4595     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4596   else
4597     exceed_dscp_str = format (0, "");
4598
4599   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4600     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4601   else
4602     violate_dscp_str = format (0, "");
4603
4604   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4605          "rate type %U, round type %U, %s rate, %s color-aware, "
4606          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4607          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4608          "conform action %U%s, exceed action %U%s, violate action %U%s",
4609          mp->name,
4610          format_policer_type, mp->type,
4611          ntohl (mp->cir),
4612          ntohl (mp->eir),
4613          clib_net_to_host_u64 (mp->cb),
4614          clib_net_to_host_u64 (mp->eb),
4615          format_policer_rate_type, mp->rate_type,
4616          format_policer_round_type, mp->round_type,
4617          mp->single_rate ? "single" : "dual",
4618          mp->color_aware ? "is" : "not",
4619          ntohl (mp->cir_tokens_per_period),
4620          ntohl (mp->pir_tokens_per_period),
4621          ntohl (mp->scale),
4622          ntohl (mp->current_limit),
4623          ntohl (mp->current_bucket),
4624          ntohl (mp->extended_limit),
4625          ntohl (mp->extended_bucket),
4626          clib_net_to_host_u64 (mp->last_update_time),
4627          format_policer_action_type, mp->conform_action_type,
4628          conform_dscp_str,
4629          format_policer_action_type, mp->exceed_action_type,
4630          exceed_dscp_str,
4631          format_policer_action_type, mp->violate_action_type,
4632          violate_dscp_str);
4633
4634   vec_free (conform_dscp_str);
4635   vec_free (exceed_dscp_str);
4636   vec_free (violate_dscp_str);
4637 }
4638
4639 static void vl_api_policer_details_t_handler_json
4640   (vl_api_policer_details_t * mp)
4641 {
4642   vat_main_t *vam = &vat_main;
4643   vat_json_node_t *node;
4644   u8 *rate_type_str, *round_type_str, *type_str;
4645   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4646
4647   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4648   round_type_str =
4649     format (0, "%U", format_policer_round_type, mp->round_type);
4650   type_str = format (0, "%U", format_policer_type, mp->type);
4651   conform_action_str = format (0, "%U", format_policer_action_type,
4652                                mp->conform_action_type);
4653   exceed_action_str = format (0, "%U", format_policer_action_type,
4654                               mp->exceed_action_type);
4655   violate_action_str = format (0, "%U", format_policer_action_type,
4656                                mp->violate_action_type);
4657
4658   if (VAT_JSON_ARRAY != vam->json_tree.type)
4659     {
4660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4661       vat_json_init_array (&vam->json_tree);
4662     }
4663   node = vat_json_array_add (&vam->json_tree);
4664
4665   vat_json_init_object (node);
4666   vat_json_object_add_string_copy (node, "name", mp->name);
4667   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4668   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4669   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4670   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4671   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4672   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4673   vat_json_object_add_string_copy (node, "type", type_str);
4674   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4675   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4676   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4677   vat_json_object_add_uint (node, "cir_tokens_per_period",
4678                             ntohl (mp->cir_tokens_per_period));
4679   vat_json_object_add_uint (node, "eir_tokens_per_period",
4680                             ntohl (mp->pir_tokens_per_period));
4681   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4682   vat_json_object_add_uint (node, "current_bucket",
4683                             ntohl (mp->current_bucket));
4684   vat_json_object_add_uint (node, "extended_limit",
4685                             ntohl (mp->extended_limit));
4686   vat_json_object_add_uint (node, "extended_bucket",
4687                             ntohl (mp->extended_bucket));
4688   vat_json_object_add_uint (node, "last_update_time",
4689                             ntohl (mp->last_update_time));
4690   vat_json_object_add_string_copy (node, "conform_action",
4691                                    conform_action_str);
4692   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4693     {
4694       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4695       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4696       vec_free (dscp_str);
4697     }
4698   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4699   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4700     {
4701       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4702       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4703       vec_free (dscp_str);
4704     }
4705   vat_json_object_add_string_copy (node, "violate_action",
4706                                    violate_action_str);
4707   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4708     {
4709       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4710       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4711       vec_free (dscp_str);
4712     }
4713
4714   vec_free (rate_type_str);
4715   vec_free (round_type_str);
4716   vec_free (type_str);
4717   vec_free (conform_action_str);
4718   vec_free (exceed_action_str);
4719   vec_free (violate_action_str);
4720 }
4721
4722 static void
4723 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4724                                            mp)
4725 {
4726   vat_main_t *vam = &vat_main;
4727   int i, count = ntohl (mp->count);
4728
4729   if (count > 0)
4730     print (vam->ofp, "classify table ids (%d) : ", count);
4731   for (i = 0; i < count; i++)
4732     {
4733       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4734       print (vam->ofp, (i < count - 1) ? "," : "");
4735     }
4736   vam->retval = ntohl (mp->retval);
4737   vam->result_ready = 1;
4738 }
4739
4740 static void
4741   vl_api_classify_table_ids_reply_t_handler_json
4742   (vl_api_classify_table_ids_reply_t * mp)
4743 {
4744   vat_main_t *vam = &vat_main;
4745   int i, count = ntohl (mp->count);
4746
4747   if (count > 0)
4748     {
4749       vat_json_node_t node;
4750
4751       vat_json_init_object (&node);
4752       for (i = 0; i < count; i++)
4753         {
4754           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4755         }
4756       vat_json_print (vam->ofp, &node);
4757       vat_json_free (&node);
4758     }
4759   vam->retval = ntohl (mp->retval);
4760   vam->result_ready = 1;
4761 }
4762
4763 static void
4764   vl_api_classify_table_by_interface_reply_t_handler
4765   (vl_api_classify_table_by_interface_reply_t * mp)
4766 {
4767   vat_main_t *vam = &vat_main;
4768   u32 table_id;
4769
4770   table_id = ntohl (mp->l2_table_id);
4771   if (table_id != ~0)
4772     print (vam->ofp, "l2 table id : %d", table_id);
4773   else
4774     print (vam->ofp, "l2 table id : No input ACL tables configured");
4775   table_id = ntohl (mp->ip4_table_id);
4776   if (table_id != ~0)
4777     print (vam->ofp, "ip4 table id : %d", table_id);
4778   else
4779     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4780   table_id = ntohl (mp->ip6_table_id);
4781   if (table_id != ~0)
4782     print (vam->ofp, "ip6 table id : %d", table_id);
4783   else
4784     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4785   vam->retval = ntohl (mp->retval);
4786   vam->result_ready = 1;
4787 }
4788
4789 static void
4790   vl_api_classify_table_by_interface_reply_t_handler_json
4791   (vl_api_classify_table_by_interface_reply_t * mp)
4792 {
4793   vat_main_t *vam = &vat_main;
4794   vat_json_node_t node;
4795
4796   vat_json_init_object (&node);
4797
4798   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4799   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4800   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4801
4802   vat_json_print (vam->ofp, &node);
4803   vat_json_free (&node);
4804
4805   vam->retval = ntohl (mp->retval);
4806   vam->result_ready = 1;
4807 }
4808
4809 static void vl_api_policer_add_del_reply_t_handler
4810   (vl_api_policer_add_del_reply_t * mp)
4811 {
4812   vat_main_t *vam = &vat_main;
4813   i32 retval = ntohl (mp->retval);
4814   if (vam->async_mode)
4815     {
4816       vam->async_errors += (retval < 0);
4817     }
4818   else
4819     {
4820       vam->retval = retval;
4821       vam->result_ready = 1;
4822       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4823         /*
4824          * Note: this is just barely thread-safe, depends on
4825          * the main thread spinning waiting for an answer...
4826          */
4827         errmsg ("policer index %d", ntohl (mp->policer_index));
4828     }
4829 }
4830
4831 static void vl_api_policer_add_del_reply_t_handler_json
4832   (vl_api_policer_add_del_reply_t * mp)
4833 {
4834   vat_main_t *vam = &vat_main;
4835   vat_json_node_t node;
4836
4837   vat_json_init_object (&node);
4838   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4839   vat_json_object_add_uint (&node, "policer_index",
4840                             ntohl (mp->policer_index));
4841
4842   vat_json_print (vam->ofp, &node);
4843   vat_json_free (&node);
4844
4845   vam->retval = ntohl (mp->retval);
4846   vam->result_ready = 1;
4847 }
4848
4849 /* Format hex dump. */
4850 u8 *
4851 format_hex_bytes (u8 * s, va_list * va)
4852 {
4853   u8 *bytes = va_arg (*va, u8 *);
4854   int n_bytes = va_arg (*va, int);
4855   uword i;
4856
4857   /* Print short or long form depending on byte count. */
4858   uword short_form = n_bytes <= 32;
4859   u32 indent = format_get_indent (s);
4860
4861   if (n_bytes == 0)
4862     return s;
4863
4864   for (i = 0; i < n_bytes; i++)
4865     {
4866       if (!short_form && (i % 32) == 0)
4867         s = format (s, "%08x: ", i);
4868       s = format (s, "%02x", bytes[i]);
4869       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4870         s = format (s, "\n%U", format_white_space, indent);
4871     }
4872
4873   return s;
4874 }
4875
4876 static void
4877 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4878                                             * mp)
4879 {
4880   vat_main_t *vam = &vat_main;
4881   i32 retval = ntohl (mp->retval);
4882   if (retval == 0)
4883     {
4884       print (vam->ofp, "classify table info :");
4885       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4886              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4887              ntohl (mp->miss_next_index));
4888       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4889              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4890              ntohl (mp->match_n_vectors));
4891       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4892              ntohl (mp->mask_length));
4893     }
4894   vam->retval = retval;
4895   vam->result_ready = 1;
4896 }
4897
4898 static void
4899   vl_api_classify_table_info_reply_t_handler_json
4900   (vl_api_classify_table_info_reply_t * mp)
4901 {
4902   vat_main_t *vam = &vat_main;
4903   vat_json_node_t node;
4904
4905   i32 retval = ntohl (mp->retval);
4906   if (retval == 0)
4907     {
4908       vat_json_init_object (&node);
4909
4910       vat_json_object_add_int (&node, "sessions",
4911                                ntohl (mp->active_sessions));
4912       vat_json_object_add_int (&node, "nexttbl",
4913                                ntohl (mp->next_table_index));
4914       vat_json_object_add_int (&node, "nextnode",
4915                                ntohl (mp->miss_next_index));
4916       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4917       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4918       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4919       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4920                       ntohl (mp->mask_length), 0);
4921       vat_json_object_add_string_copy (&node, "mask", s);
4922
4923       vat_json_print (vam->ofp, &node);
4924       vat_json_free (&node);
4925     }
4926   vam->retval = ntohl (mp->retval);
4927   vam->result_ready = 1;
4928 }
4929
4930 static void
4931 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4932                                            mp)
4933 {
4934   vat_main_t *vam = &vat_main;
4935
4936   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4937          ntohl (mp->hit_next_index), ntohl (mp->advance),
4938          ntohl (mp->opaque_index));
4939   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4940          ntohl (mp->match_length));
4941 }
4942
4943 static void
4944   vl_api_classify_session_details_t_handler_json
4945   (vl_api_classify_session_details_t * mp)
4946 {
4947   vat_main_t *vam = &vat_main;
4948   vat_json_node_t *node = NULL;
4949
4950   if (VAT_JSON_ARRAY != vam->json_tree.type)
4951     {
4952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4953       vat_json_init_array (&vam->json_tree);
4954     }
4955   node = vat_json_array_add (&vam->json_tree);
4956
4957   vat_json_init_object (node);
4958   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4959   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4960   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4961   u8 *s =
4962     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4963             0);
4964   vat_json_object_add_string_copy (node, "match", s);
4965 }
4966
4967 static void vl_api_pg_create_interface_reply_t_handler
4968   (vl_api_pg_create_interface_reply_t * mp)
4969 {
4970   vat_main_t *vam = &vat_main;
4971
4972   vam->retval = ntohl (mp->retval);
4973   vam->result_ready = 1;
4974 }
4975
4976 static void vl_api_pg_create_interface_reply_t_handler_json
4977   (vl_api_pg_create_interface_reply_t * mp)
4978 {
4979   vat_main_t *vam = &vat_main;
4980   vat_json_node_t node;
4981
4982   i32 retval = ntohl (mp->retval);
4983   if (retval == 0)
4984     {
4985       vat_json_init_object (&node);
4986
4987       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4988
4989       vat_json_print (vam->ofp, &node);
4990       vat_json_free (&node);
4991     }
4992   vam->retval = ntohl (mp->retval);
4993   vam->result_ready = 1;
4994 }
4995
4996 static void vl_api_policer_classify_details_t_handler
4997   (vl_api_policer_classify_details_t * mp)
4998 {
4999   vat_main_t *vam = &vat_main;
5000
5001   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5002          ntohl (mp->table_index));
5003 }
5004
5005 static void vl_api_policer_classify_details_t_handler_json
5006   (vl_api_policer_classify_details_t * mp)
5007 {
5008   vat_main_t *vam = &vat_main;
5009   vat_json_node_t *node;
5010
5011   if (VAT_JSON_ARRAY != vam->json_tree.type)
5012     {
5013       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5014       vat_json_init_array (&vam->json_tree);
5015     }
5016   node = vat_json_array_add (&vam->json_tree);
5017
5018   vat_json_init_object (node);
5019   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5020   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5021 }
5022
5023 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5024   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5025 {
5026   vat_main_t *vam = &vat_main;
5027   i32 retval = ntohl (mp->retval);
5028   if (vam->async_mode)
5029     {
5030       vam->async_errors += (retval < 0);
5031     }
5032   else
5033     {
5034       vam->retval = retval;
5035       vam->sw_if_index = ntohl (mp->sw_if_index);
5036       vam->result_ready = 1;
5037     }
5038   vam->regenerate_interface_table = 1;
5039 }
5040
5041 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5042   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5043 {
5044   vat_main_t *vam = &vat_main;
5045   vat_json_node_t node;
5046
5047   vat_json_init_object (&node);
5048   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5049   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5050
5051   vat_json_print (vam->ofp, &node);
5052   vat_json_free (&node);
5053
5054   vam->retval = ntohl (mp->retval);
5055   vam->result_ready = 1;
5056 }
5057
5058 static void vl_api_flow_classify_details_t_handler
5059   (vl_api_flow_classify_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062
5063   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5064          ntohl (mp->table_index));
5065 }
5066
5067 static void vl_api_flow_classify_details_t_handler_json
5068   (vl_api_flow_classify_details_t * mp)
5069 {
5070   vat_main_t *vam = &vat_main;
5071   vat_json_node_t *node;
5072
5073   if (VAT_JSON_ARRAY != vam->json_tree.type)
5074     {
5075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5076       vat_json_init_array (&vam->json_tree);
5077     }
5078   node = vat_json_array_add (&vam->json_tree);
5079
5080   vat_json_init_object (node);
5081   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5082   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5083 }
5084
5085 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5086 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5087 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5088 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5089 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5090 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5091 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5092 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5093 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5094 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5095
5096 /*
5097  * Generate boilerplate reply handlers, which
5098  * dig the return value out of the xxx_reply_t API message,
5099  * stick it into vam->retval, and set vam->result_ready
5100  *
5101  * Could also do this by pointing N message decode slots at
5102  * a single function, but that could break in subtle ways.
5103  */
5104
5105 #define foreach_standard_reply_retval_handler           \
5106 _(sw_interface_set_flags_reply)                         \
5107 _(sw_interface_add_del_address_reply)                   \
5108 _(sw_interface_set_rx_mode_reply)                       \
5109 _(sw_interface_set_rx_placement_reply)                  \
5110 _(sw_interface_set_table_reply)                         \
5111 _(sw_interface_set_mpls_enable_reply)                   \
5112 _(sw_interface_set_vpath_reply)                         \
5113 _(sw_interface_set_vxlan_bypass_reply)                  \
5114 _(sw_interface_set_geneve_bypass_reply)                 \
5115 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5116 _(sw_interface_set_l2_bridge_reply)                     \
5117 _(bridge_domain_add_del_reply)                          \
5118 _(sw_interface_set_l2_xconnect_reply)                   \
5119 _(l2fib_add_del_reply)                                  \
5120 _(l2fib_flush_int_reply)                                \
5121 _(l2fib_flush_bd_reply)                                 \
5122 _(ip_add_del_route_reply)                               \
5123 _(ip_table_add_del_reply)                               \
5124 _(ip_mroute_add_del_reply)                              \
5125 _(mpls_route_add_del_reply)                             \
5126 _(mpls_table_add_del_reply)                             \
5127 _(mpls_ip_bind_unbind_reply)                            \
5128 _(bier_route_add_del_reply)                             \
5129 _(bier_table_add_del_reply)                             \
5130 _(proxy_arp_add_del_reply)                              \
5131 _(proxy_arp_intfc_enable_disable_reply)                 \
5132 _(sw_interface_set_unnumbered_reply)                    \
5133 _(ip_neighbor_add_del_reply)                            \
5134 _(oam_add_del_reply)                                    \
5135 _(reset_fib_reply)                                      \
5136 _(dhcp_proxy_config_reply)                              \
5137 _(dhcp_proxy_set_vss_reply)                             \
5138 _(dhcp_client_config_reply)                             \
5139 _(set_ip_flow_hash_reply)                               \
5140 _(sw_interface_ip6_enable_disable_reply)                \
5141 _(ip6nd_proxy_add_del_reply)                            \
5142 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5143 _(sw_interface_ip6nd_ra_config_reply)                   \
5144 _(set_arp_neighbor_limit_reply)                         \
5145 _(l2_patch_add_del_reply)                               \
5146 _(sr_mpls_policy_add_reply)                             \
5147 _(sr_mpls_policy_mod_reply)                             \
5148 _(sr_mpls_policy_del_reply)                             \
5149 _(sr_policy_add_reply)                                  \
5150 _(sr_policy_mod_reply)                                  \
5151 _(sr_policy_del_reply)                                  \
5152 _(sr_localsid_add_del_reply)                            \
5153 _(sr_steering_add_del_reply)                            \
5154 _(classify_add_del_session_reply)                       \
5155 _(classify_set_interface_ip_table_reply)                \
5156 _(classify_set_interface_l2_tables_reply)               \
5157 _(l2tpv3_set_tunnel_cookies_reply)                      \
5158 _(l2tpv3_interface_enable_disable_reply)                \
5159 _(l2tpv3_set_lookup_key_reply)                          \
5160 _(l2_fib_clear_table_reply)                             \
5161 _(l2_interface_efp_filter_reply)                        \
5162 _(l2_interface_vlan_tag_rewrite_reply)                  \
5163 _(modify_vhost_user_if_reply)                           \
5164 _(delete_vhost_user_if_reply)                           \
5165 _(ip_probe_neighbor_reply)                              \
5166 _(ip_scan_neighbor_enable_disable_reply)                \
5167 _(want_ip4_arp_events_reply)                            \
5168 _(want_ip6_nd_events_reply)                             \
5169 _(want_l2_macs_events_reply)                            \
5170 _(input_acl_set_interface_reply)                        \
5171 _(ipsec_spd_add_del_reply)                              \
5172 _(ipsec_interface_add_del_spd_reply)                    \
5173 _(ipsec_spd_entry_add_del_reply)                        \
5174 _(ipsec_sad_entry_add_del_reply)                        \
5175 _(ipsec_sa_set_key_reply)                               \
5176 _(ipsec_tunnel_if_add_del_reply)                        \
5177 _(ipsec_tunnel_if_set_key_reply)                        \
5178 _(ipsec_tunnel_if_set_sa_reply)                         \
5179 _(delete_loopback_reply)                                \
5180 _(bd_ip_mac_add_del_reply)                              \
5181 _(bd_ip_mac_flush_reply)                                \
5182 _(want_interface_events_reply)                          \
5183 _(cop_interface_enable_disable_reply)                   \
5184 _(cop_whitelist_enable_disable_reply)                   \
5185 _(sw_interface_clear_stats_reply)                       \
5186 _(ioam_enable_reply)                                    \
5187 _(ioam_disable_reply)                                   \
5188 _(one_add_del_locator_reply)                            \
5189 _(one_add_del_local_eid_reply)                          \
5190 _(one_add_del_remote_mapping_reply)                     \
5191 _(one_add_del_adjacency_reply)                          \
5192 _(one_add_del_map_resolver_reply)                       \
5193 _(one_add_del_map_server_reply)                         \
5194 _(one_enable_disable_reply)                             \
5195 _(one_rloc_probe_enable_disable_reply)                  \
5196 _(one_map_register_enable_disable_reply)                \
5197 _(one_map_register_set_ttl_reply)                       \
5198 _(one_set_transport_protocol_reply)                     \
5199 _(one_map_register_fallback_threshold_reply)            \
5200 _(one_pitr_set_locator_set_reply)                       \
5201 _(one_map_request_mode_reply)                           \
5202 _(one_add_del_map_request_itr_rlocs_reply)              \
5203 _(one_eid_table_add_del_map_reply)                      \
5204 _(one_use_petr_reply)                                   \
5205 _(one_stats_enable_disable_reply)                       \
5206 _(one_add_del_l2_arp_entry_reply)                       \
5207 _(one_add_del_ndp_entry_reply)                          \
5208 _(one_stats_flush_reply)                                \
5209 _(one_enable_disable_xtr_mode_reply)                    \
5210 _(one_enable_disable_pitr_mode_reply)                   \
5211 _(one_enable_disable_petr_mode_reply)                   \
5212 _(gpe_enable_disable_reply)                             \
5213 _(gpe_set_encap_mode_reply)                             \
5214 _(gpe_add_del_iface_reply)                              \
5215 _(gpe_add_del_native_fwd_rpath_reply)                   \
5216 _(af_packet_delete_reply)                               \
5217 _(policer_classify_set_interface_reply)                 \
5218 _(netmap_create_reply)                                  \
5219 _(netmap_delete_reply)                                  \
5220 _(set_ipfix_exporter_reply)                             \
5221 _(set_ipfix_classify_stream_reply)                      \
5222 _(ipfix_classify_table_add_del_reply)                   \
5223 _(flow_classify_set_interface_reply)                    \
5224 _(sw_interface_span_enable_disable_reply)               \
5225 _(pg_capture_reply)                                     \
5226 _(pg_enable_disable_reply)                              \
5227 _(ip_source_and_port_range_check_add_del_reply)         \
5228 _(ip_source_and_port_range_check_interface_add_del_reply)\
5229 _(delete_subif_reply)                                   \
5230 _(l2_interface_pbb_tag_rewrite_reply)                   \
5231 _(set_punt_reply)                                       \
5232 _(feature_enable_disable_reply)                         \
5233 _(sw_interface_tag_add_del_reply)                       \
5234 _(hw_interface_set_mtu_reply)                           \
5235 _(p2p_ethernet_add_reply)                               \
5236 _(p2p_ethernet_del_reply)                               \
5237 _(lldp_config_reply)                                    \
5238 _(sw_interface_set_lldp_reply)                          \
5239 _(tcp_configure_src_addresses_reply)                    \
5240 _(dns_enable_disable_reply)                             \
5241 _(dns_name_server_add_del_reply)                        \
5242 _(session_rule_add_del_reply)                           \
5243 _(ip_container_proxy_add_del_reply)                     \
5244 _(output_acl_set_interface_reply)                       \
5245 _(qos_record_enable_disable_reply)
5246
5247 #define _(n)                                    \
5248     static void vl_api_##n##_t_handler          \
5249     (vl_api_##n##_t * mp)                       \
5250     {                                           \
5251         vat_main_t * vam = &vat_main;           \
5252         i32 retval = ntohl(mp->retval);         \
5253         if (vam->async_mode) {                  \
5254             vam->async_errors += (retval < 0);  \
5255         } else {                                \
5256             vam->retval = retval;               \
5257             vam->result_ready = 1;              \
5258         }                                       \
5259     }
5260 foreach_standard_reply_retval_handler;
5261 #undef _
5262
5263 #define _(n)                                    \
5264     static void vl_api_##n##_t_handler_json     \
5265     (vl_api_##n##_t * mp)                       \
5266     {                                           \
5267         vat_main_t * vam = &vat_main;           \
5268         vat_json_node_t node;                   \
5269         vat_json_init_object(&node);            \
5270         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5271         vat_json_print(vam->ofp, &node);        \
5272         vam->retval = ntohl(mp->retval);        \
5273         vam->result_ready = 1;                  \
5274     }
5275 foreach_standard_reply_retval_handler;
5276 #undef _
5277
5278 /*
5279  * Table of message reply handlers, must include boilerplate handlers
5280  * we just generated
5281  */
5282
5283 #define foreach_vpe_api_reply_msg                                       \
5284 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5285 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5286 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5287 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5288 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5289 _(CLI_REPLY, cli_reply)                                                 \
5290 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5291 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5292   sw_interface_add_del_address_reply)                                   \
5293 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5294 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5295 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5296 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5297 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5298 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5299 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5300 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5301 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5302 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5303   sw_interface_set_l2_xconnect_reply)                                   \
5304 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5305   sw_interface_set_l2_bridge_reply)                                     \
5306 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5307 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5308 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5309 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5310 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5311 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5312 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5313 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5314 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5315 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5316 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5317 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5318 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5319 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5320 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5321 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5322 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5323 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5324 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5325 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5326 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5327 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5328 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5329 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5330 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5331 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5332 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5333 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5334 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5335 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5336   proxy_arp_intfc_enable_disable_reply)                                 \
5337 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5338 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5339   sw_interface_set_unnumbered_reply)                                    \
5340 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5341 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5342 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5343 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5344 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5345 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5346 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5347 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5348 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5349 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5350 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5351   sw_interface_ip6_enable_disable_reply)                                \
5352 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5353 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5354 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5355   sw_interface_ip6nd_ra_prefix_reply)                                   \
5356 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5357   sw_interface_ip6nd_ra_config_reply)                                   \
5358 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5359 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5360 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5361 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5362 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5363 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5364 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5365 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5366 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5367 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5368 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5369 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5370 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5371 classify_set_interface_ip_table_reply)                                  \
5372 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5373   classify_set_interface_l2_tables_reply)                               \
5374 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5375 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5376 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5377 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5378 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5379   l2tpv3_interface_enable_disable_reply)                                \
5380 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5381 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5382 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5383 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5384 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5385 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5386 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5387 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5388 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5389 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5390 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5391 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5392 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5393 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5394 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5395 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5396 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5397 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5398 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5399 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5400 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5401 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5402 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5403 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5404 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5405 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5406 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5407 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5408 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5409 _(L2_MACS_EVENT, l2_macs_event)                                         \
5410 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5411 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5412 _(IP_DETAILS, ip_details)                                               \
5413 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5414 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5415 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5416 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5417 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5418 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5419 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5420 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5421 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5422 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5423 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5424 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5425 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5426 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5427 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5428 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5429 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5430 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5431 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5432 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5433 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5434 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5435 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5436 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5437 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5438 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5439 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5440 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5441 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5442 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5443 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5444   one_map_register_enable_disable_reply)                                \
5445 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5446 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5447 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5448 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5449   one_map_register_fallback_threshold_reply)                            \
5450 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5451   one_rloc_probe_enable_disable_reply)                                  \
5452 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5453 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5454 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5455 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5456 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5457 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5458 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5459 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5460 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5461 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5462 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5463 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5464 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5465 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5466 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5467 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5468   show_one_stats_enable_disable_reply)                                  \
5469 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5470 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5471 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5472 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5473 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5474 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5475 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5476 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5477   one_enable_disable_pitr_mode_reply)                                   \
5478 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5479   one_enable_disable_petr_mode_reply)                                   \
5480 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5481 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5482 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5483 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5484 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5485 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5486 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5487 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5488 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5489 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5490 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5491 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5492   gpe_add_del_native_fwd_rpath_reply)                                   \
5493 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5494   gpe_fwd_entry_path_details)                                           \
5495 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5496 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5497   one_add_del_map_request_itr_rlocs_reply)                              \
5498 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5499   one_get_map_request_itr_rlocs_reply)                                  \
5500 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5501 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5502 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5503 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5504 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5505 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5506   show_one_map_register_state_reply)                                    \
5507 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5508 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5509   show_one_map_register_fallback_threshold_reply)                       \
5510 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5511 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5512 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5513 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5514 _(POLICER_DETAILS, policer_details)                                     \
5515 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5516 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5517 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5518 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5519 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5520 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5521 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5522 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5523 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5524 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5525 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5526 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5527 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5528 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5529 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5530 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5531 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5532 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5533 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5534 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5535 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5536 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5537 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5538 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5539 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5540  ip_source_and_port_range_check_add_del_reply)                          \
5541 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5542  ip_source_and_port_range_check_interface_add_del_reply)                \
5543 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5544 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5545 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5546 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5547 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5548 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5549 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5550 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5551 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5552 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5553 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5554 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5555 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5556 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5557 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5558 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5559 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5560 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5561 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5562 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5563 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5564 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5565 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5566 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5567 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5568 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5569 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5570 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5571
5572 #define foreach_standalone_reply_msg                                    \
5573 _(SW_INTERFACE_EVENT, sw_interface_event)
5574
5575 typedef struct
5576 {
5577   u8 *name;
5578   u32 value;
5579 } name_sort_t;
5580
5581 #define STR_VTR_OP_CASE(op)     \
5582     case L2_VTR_ ## op:         \
5583         return "" # op;
5584
5585 static const char *
5586 str_vtr_op (u32 vtr_op)
5587 {
5588   switch (vtr_op)
5589     {
5590       STR_VTR_OP_CASE (DISABLED);
5591       STR_VTR_OP_CASE (PUSH_1);
5592       STR_VTR_OP_CASE (PUSH_2);
5593       STR_VTR_OP_CASE (POP_1);
5594       STR_VTR_OP_CASE (POP_2);
5595       STR_VTR_OP_CASE (TRANSLATE_1_1);
5596       STR_VTR_OP_CASE (TRANSLATE_1_2);
5597       STR_VTR_OP_CASE (TRANSLATE_2_1);
5598       STR_VTR_OP_CASE (TRANSLATE_2_2);
5599     }
5600
5601   return "UNKNOWN";
5602 }
5603
5604 static int
5605 dump_sub_interface_table (vat_main_t * vam)
5606 {
5607   const sw_interface_subif_t *sub = NULL;
5608
5609   if (vam->json_output)
5610     {
5611       clib_warning
5612         ("JSON output supported only for VPE API calls and dump_stats_table");
5613       return -99;
5614     }
5615
5616   print (vam->ofp,
5617          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5618          "Interface", "sw_if_index",
5619          "sub id", "dot1ad", "tags", "outer id",
5620          "inner id", "exact", "default", "outer any", "inner any");
5621
5622   vec_foreach (sub, vam->sw_if_subif_table)
5623   {
5624     print (vam->ofp,
5625            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5626            sub->interface_name,
5627            sub->sw_if_index,
5628            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5629            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5630            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5631            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5632     if (sub->vtr_op != L2_VTR_DISABLED)
5633       {
5634         print (vam->ofp,
5635                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5636                "tag1: %d tag2: %d ]",
5637                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5638                sub->vtr_tag1, sub->vtr_tag2);
5639       }
5640   }
5641
5642   return 0;
5643 }
5644
5645 static int
5646 name_sort_cmp (void *a1, void *a2)
5647 {
5648   name_sort_t *n1 = a1;
5649   name_sort_t *n2 = a2;
5650
5651   return strcmp ((char *) n1->name, (char *) n2->name);
5652 }
5653
5654 static int
5655 dump_interface_table (vat_main_t * vam)
5656 {
5657   hash_pair_t *p;
5658   name_sort_t *nses = 0, *ns;
5659
5660   if (vam->json_output)
5661     {
5662       clib_warning
5663         ("JSON output supported only for VPE API calls and dump_stats_table");
5664       return -99;
5665     }
5666
5667   /* *INDENT-OFF* */
5668   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5669   ({
5670     vec_add2 (nses, ns, 1);
5671     ns->name = (u8 *)(p->key);
5672     ns->value = (u32) p->value[0];
5673   }));
5674   /* *INDENT-ON* */
5675
5676   vec_sort_with_function (nses, name_sort_cmp);
5677
5678   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5679   vec_foreach (ns, nses)
5680   {
5681     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5682   }
5683   vec_free (nses);
5684   return 0;
5685 }
5686
5687 static int
5688 dump_ip_table (vat_main_t * vam, int is_ipv6)
5689 {
5690   const ip_details_t *det = NULL;
5691   const ip_address_details_t *address = NULL;
5692   u32 i = ~0;
5693
5694   print (vam->ofp, "%-12s", "sw_if_index");
5695
5696   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5697   {
5698     i++;
5699     if (!det->present)
5700       {
5701         continue;
5702       }
5703     print (vam->ofp, "%-12d", i);
5704     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5705     if (!det->addr)
5706       {
5707         continue;
5708       }
5709     vec_foreach (address, det->addr)
5710     {
5711       print (vam->ofp,
5712              "            %-30U%-13d",
5713              is_ipv6 ? format_ip6_address : format_ip4_address,
5714              address->ip, address->prefix_length);
5715     }
5716   }
5717
5718   return 0;
5719 }
5720
5721 static int
5722 dump_ipv4_table (vat_main_t * vam)
5723 {
5724   if (vam->json_output)
5725     {
5726       clib_warning
5727         ("JSON output supported only for VPE API calls and dump_stats_table");
5728       return -99;
5729     }
5730
5731   return dump_ip_table (vam, 0);
5732 }
5733
5734 static int
5735 dump_ipv6_table (vat_main_t * vam)
5736 {
5737   if (vam->json_output)
5738     {
5739       clib_warning
5740         ("JSON output supported only for VPE API calls and dump_stats_table");
5741       return -99;
5742     }
5743
5744   return dump_ip_table (vam, 1);
5745 }
5746
5747 /*
5748  * Pass CLI buffers directly in the CLI_INBAND API message,
5749  * instead of an additional shared memory area.
5750  */
5751 static int
5752 exec_inband (vat_main_t * vam)
5753 {
5754   vl_api_cli_inband_t *mp;
5755   unformat_input_t *i = vam->input;
5756   int ret;
5757
5758   if (vec_len (i->buffer) == 0)
5759     return -1;
5760
5761   if (vam->exec_mode == 0 && unformat (i, "mode"))
5762     {
5763       vam->exec_mode = 1;
5764       return 0;
5765     }
5766   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5767     {
5768       vam->exec_mode = 0;
5769       return 0;
5770     }
5771
5772   /*
5773    * In order for the CLI command to work, it
5774    * must be a vector ending in \n, not a C-string ending
5775    * in \n\0.
5776    */
5777   u32 len = vec_len (vam->input->buffer);
5778   M2 (CLI_INBAND, mp, len);
5779   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5780
5781   S (mp);
5782   W (ret);
5783   /* json responses may or may not include a useful reply... */
5784   if (vec_len (vam->cmd_reply))
5785     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5786   return ret;
5787 }
5788
5789 int
5790 exec (vat_main_t * vam)
5791 {
5792   return exec_inband (vam);
5793 }
5794
5795 static int
5796 api_create_loopback (vat_main_t * vam)
5797 {
5798   unformat_input_t *i = vam->input;
5799   vl_api_create_loopback_t *mp;
5800   vl_api_create_loopback_instance_t *mp_lbi;
5801   u8 mac_address[6];
5802   u8 mac_set = 0;
5803   u8 is_specified = 0;
5804   u32 user_instance = 0;
5805   int ret;
5806
5807   clib_memset (mac_address, 0, sizeof (mac_address));
5808
5809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5810     {
5811       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5812         mac_set = 1;
5813       if (unformat (i, "instance %d", &user_instance))
5814         is_specified = 1;
5815       else
5816         break;
5817     }
5818
5819   if (is_specified)
5820     {
5821       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5822       mp_lbi->is_specified = is_specified;
5823       if (is_specified)
5824         mp_lbi->user_instance = htonl (user_instance);
5825       if (mac_set)
5826         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5827       S (mp_lbi);
5828     }
5829   else
5830     {
5831       /* Construct the API message */
5832       M (CREATE_LOOPBACK, mp);
5833       if (mac_set)
5834         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5835       S (mp);
5836     }
5837
5838   W (ret);
5839   return ret;
5840 }
5841
5842 static int
5843 api_delete_loopback (vat_main_t * vam)
5844 {
5845   unformat_input_t *i = vam->input;
5846   vl_api_delete_loopback_t *mp;
5847   u32 sw_if_index = ~0;
5848   int ret;
5849
5850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5851     {
5852       if (unformat (i, "sw_if_index %d", &sw_if_index))
5853         ;
5854       else
5855         break;
5856     }
5857
5858   if (sw_if_index == ~0)
5859     {
5860       errmsg ("missing sw_if_index");
5861       return -99;
5862     }
5863
5864   /* Construct the API message */
5865   M (DELETE_LOOPBACK, mp);
5866   mp->sw_if_index = ntohl (sw_if_index);
5867
5868   S (mp);
5869   W (ret);
5870   return ret;
5871 }
5872
5873 static int
5874 api_want_interface_events (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_want_interface_events_t *mp;
5878   int enable = -1;
5879   int ret;
5880
5881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5882     {
5883       if (unformat (i, "enable"))
5884         enable = 1;
5885       else if (unformat (i, "disable"))
5886         enable = 0;
5887       else
5888         break;
5889     }
5890
5891   if (enable == -1)
5892     {
5893       errmsg ("missing enable|disable");
5894       return -99;
5895     }
5896
5897   M (WANT_INTERFACE_EVENTS, mp);
5898   mp->enable_disable = enable;
5899
5900   vam->interface_event_display = enable;
5901
5902   S (mp);
5903   W (ret);
5904   return ret;
5905 }
5906
5907
5908 /* Note: non-static, called once to set up the initial intfc table */
5909 int
5910 api_sw_interface_dump (vat_main_t * vam)
5911 {
5912   vl_api_sw_interface_dump_t *mp;
5913   vl_api_control_ping_t *mp_ping;
5914   hash_pair_t *p;
5915   name_sort_t *nses = 0, *ns;
5916   sw_interface_subif_t *sub = NULL;
5917   int ret;
5918
5919   /* Toss the old name table */
5920   /* *INDENT-OFF* */
5921   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5922   ({
5923     vec_add2 (nses, ns, 1);
5924     ns->name = (u8 *)(p->key);
5925     ns->value = (u32) p->value[0];
5926   }));
5927   /* *INDENT-ON* */
5928
5929   hash_free (vam->sw_if_index_by_interface_name);
5930
5931   vec_foreach (ns, nses) vec_free (ns->name);
5932
5933   vec_free (nses);
5934
5935   vec_foreach (sub, vam->sw_if_subif_table)
5936   {
5937     vec_free (sub->interface_name);
5938   }
5939   vec_free (vam->sw_if_subif_table);
5940
5941   /* recreate the interface name hash table */
5942   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5943
5944   /*
5945    * Ask for all interface names. Otherwise, the epic catalog of
5946    * name filters becomes ridiculously long, and vat ends up needing
5947    * to be taught about new interface types.
5948    */
5949   M (SW_INTERFACE_DUMP, mp);
5950   S (mp);
5951
5952   /* Use a control ping for synchronization */
5953   MPING (CONTROL_PING, mp_ping);
5954   S (mp_ping);
5955
5956   W (ret);
5957   return ret;
5958 }
5959
5960 static int
5961 api_sw_interface_set_flags (vat_main_t * vam)
5962 {
5963   unformat_input_t *i = vam->input;
5964   vl_api_sw_interface_set_flags_t *mp;
5965   u32 sw_if_index;
5966   u8 sw_if_index_set = 0;
5967   u8 admin_up = 0;
5968   int ret;
5969
5970   /* Parse args required to build the message */
5971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5972     {
5973       if (unformat (i, "admin-up"))
5974         admin_up = 1;
5975       else if (unformat (i, "admin-down"))
5976         admin_up = 0;
5977       else
5978         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5979         sw_if_index_set = 1;
5980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5981         sw_if_index_set = 1;
5982       else
5983         break;
5984     }
5985
5986   if (sw_if_index_set == 0)
5987     {
5988       errmsg ("missing interface name or sw_if_index");
5989       return -99;
5990     }
5991
5992   /* Construct the API message */
5993   M (SW_INTERFACE_SET_FLAGS, mp);
5994   mp->sw_if_index = ntohl (sw_if_index);
5995   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5996
5997   /* send it... */
5998   S (mp);
5999
6000   /* Wait for a reply, return the good/bad news... */
6001   W (ret);
6002   return ret;
6003 }
6004
6005 static int
6006 api_sw_interface_set_rx_mode (vat_main_t * vam)
6007 {
6008   unformat_input_t *i = vam->input;
6009   vl_api_sw_interface_set_rx_mode_t *mp;
6010   u32 sw_if_index;
6011   u8 sw_if_index_set = 0;
6012   int ret;
6013   u8 queue_id_valid = 0;
6014   u32 queue_id;
6015   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6016
6017   /* Parse args required to build the message */
6018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6019     {
6020       if (unformat (i, "queue %d", &queue_id))
6021         queue_id_valid = 1;
6022       else if (unformat (i, "polling"))
6023         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6024       else if (unformat (i, "interrupt"))
6025         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6026       else if (unformat (i, "adaptive"))
6027         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6028       else
6029         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6030         sw_if_index_set = 1;
6031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6032         sw_if_index_set = 1;
6033       else
6034         break;
6035     }
6036
6037   if (sw_if_index_set == 0)
6038     {
6039       errmsg ("missing interface name or sw_if_index");
6040       return -99;
6041     }
6042   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6043     {
6044       errmsg ("missing rx-mode");
6045       return -99;
6046     }
6047
6048   /* Construct the API message */
6049   M (SW_INTERFACE_SET_RX_MODE, mp);
6050   mp->sw_if_index = ntohl (sw_if_index);
6051   mp->mode = mode;
6052   mp->queue_id_valid = queue_id_valid;
6053   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6054
6055   /* send it... */
6056   S (mp);
6057
6058   /* Wait for a reply, return the good/bad news... */
6059   W (ret);
6060   return ret;
6061 }
6062
6063 static int
6064 api_sw_interface_set_rx_placement (vat_main_t * vam)
6065 {
6066   unformat_input_t *i = vam->input;
6067   vl_api_sw_interface_set_rx_placement_t *mp;
6068   u32 sw_if_index;
6069   u8 sw_if_index_set = 0;
6070   int ret;
6071   u8 is_main = 0;
6072   u32 queue_id, thread_index;
6073
6074   /* Parse args required to build the message */
6075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6076     {
6077       if (unformat (i, "queue %d", &queue_id))
6078         ;
6079       else if (unformat (i, "main"))
6080         is_main = 1;
6081       else if (unformat (i, "worker %d", &thread_index))
6082         ;
6083       else
6084         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6085         sw_if_index_set = 1;
6086       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6087         sw_if_index_set = 1;
6088       else
6089         break;
6090     }
6091
6092   if (sw_if_index_set == 0)
6093     {
6094       errmsg ("missing interface name or sw_if_index");
6095       return -99;
6096     }
6097
6098   if (is_main)
6099     thread_index = 0;
6100   /* Construct the API message */
6101   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6102   mp->sw_if_index = ntohl (sw_if_index);
6103   mp->worker_id = ntohl (thread_index);
6104   mp->queue_id = ntohl (queue_id);
6105   mp->is_main = is_main;
6106
6107   /* send it... */
6108   S (mp);
6109   /* Wait for a reply, return the good/bad news... */
6110   W (ret);
6111   return ret;
6112 }
6113
6114 static void vl_api_sw_interface_rx_placement_details_t_handler
6115   (vl_api_sw_interface_rx_placement_details_t * mp)
6116 {
6117   vat_main_t *vam = &vat_main;
6118   u32 worker_id = ntohl (mp->worker_id);
6119
6120   print (vam->ofp,
6121          "\n%-11d %-11s %-6d %-5d %-9s",
6122          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6123          worker_id, ntohl (mp->queue_id),
6124          (mp->mode ==
6125           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6126 }
6127
6128 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6129   (vl_api_sw_interface_rx_placement_details_t * mp)
6130 {
6131   vat_main_t *vam = &vat_main;
6132   vat_json_node_t *node = NULL;
6133
6134   if (VAT_JSON_ARRAY != vam->json_tree.type)
6135     {
6136       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6137       vat_json_init_array (&vam->json_tree);
6138     }
6139   node = vat_json_array_add (&vam->json_tree);
6140
6141   vat_json_init_object (node);
6142   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6143   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6144   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6145   vat_json_object_add_uint (node, "mode", mp->mode);
6146 }
6147
6148 static int
6149 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6150 {
6151   unformat_input_t *i = vam->input;
6152   vl_api_sw_interface_rx_placement_dump_t *mp;
6153   vl_api_control_ping_t *mp_ping;
6154   int ret;
6155   u32 sw_if_index;
6156   u8 sw_if_index_set = 0;
6157
6158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6159     {
6160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6161         sw_if_index_set++;
6162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6163         sw_if_index_set++;
6164       else
6165         break;
6166     }
6167
6168   print (vam->ofp,
6169          "\n%-11s %-11s %-6s %-5s %-4s",
6170          "sw_if_index", "main/worker", "thread", "queue", "mode");
6171
6172   /* Dump Interface rx placement */
6173   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6174
6175   if (sw_if_index_set)
6176     mp->sw_if_index = htonl (sw_if_index);
6177   else
6178     mp->sw_if_index = ~0;
6179
6180   S (mp);
6181
6182   /* Use a control ping for synchronization */
6183   MPING (CONTROL_PING, mp_ping);
6184   S (mp_ping);
6185
6186   W (ret);
6187   return ret;
6188 }
6189
6190 static int
6191 api_sw_interface_clear_stats (vat_main_t * vam)
6192 {
6193   unformat_input_t *i = vam->input;
6194   vl_api_sw_interface_clear_stats_t *mp;
6195   u32 sw_if_index;
6196   u8 sw_if_index_set = 0;
6197   int ret;
6198
6199   /* Parse args required to build the message */
6200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6201     {
6202       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6203         sw_if_index_set = 1;
6204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6205         sw_if_index_set = 1;
6206       else
6207         break;
6208     }
6209
6210   /* Construct the API message */
6211   M (SW_INTERFACE_CLEAR_STATS, mp);
6212
6213   if (sw_if_index_set == 1)
6214     mp->sw_if_index = ntohl (sw_if_index);
6215   else
6216     mp->sw_if_index = ~0;
6217
6218   /* send it... */
6219   S (mp);
6220
6221   /* Wait for a reply, return the good/bad news... */
6222   W (ret);
6223   return ret;
6224 }
6225
6226 static int
6227 api_sw_interface_add_del_address (vat_main_t * vam)
6228 {
6229   unformat_input_t *i = vam->input;
6230   vl_api_sw_interface_add_del_address_t *mp;
6231   u32 sw_if_index;
6232   u8 sw_if_index_set = 0;
6233   u8 is_add = 1, del_all = 0;
6234   u32 address_length = 0;
6235   u8 v4_address_set = 0;
6236   u8 v6_address_set = 0;
6237   ip4_address_t v4address;
6238   ip6_address_t v6address;
6239   int ret;
6240
6241   /* Parse args required to build the message */
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "del-all"))
6245         del_all = 1;
6246       else if (unformat (i, "del"))
6247         is_add = 0;
6248       else
6249         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6250         sw_if_index_set = 1;
6251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6252         sw_if_index_set = 1;
6253       else if (unformat (i, "%U/%d",
6254                          unformat_ip4_address, &v4address, &address_length))
6255         v4_address_set = 1;
6256       else if (unformat (i, "%U/%d",
6257                          unformat_ip6_address, &v6address, &address_length))
6258         v6_address_set = 1;
6259       else
6260         break;
6261     }
6262
6263   if (sw_if_index_set == 0)
6264     {
6265       errmsg ("missing interface name or sw_if_index");
6266       return -99;
6267     }
6268   if (v4_address_set && v6_address_set)
6269     {
6270       errmsg ("both v4 and v6 addresses set");
6271       return -99;
6272     }
6273   if (!v4_address_set && !v6_address_set && !del_all)
6274     {
6275       errmsg ("no addresses set");
6276       return -99;
6277     }
6278
6279   /* Construct the API message */
6280   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6281
6282   mp->sw_if_index = ntohl (sw_if_index);
6283   mp->is_add = is_add;
6284   mp->del_all = del_all;
6285   if (v6_address_set)
6286     {
6287       mp->prefix.address.af = ADDRESS_IP6;
6288       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6289     }
6290   else
6291     {
6292       mp->prefix.address.af = ADDRESS_IP4;
6293       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6294     }
6295   mp->prefix.address_length = address_length;
6296
6297   /* send it... */
6298   S (mp);
6299
6300   /* Wait for a reply, return good/bad news  */
6301   W (ret);
6302   return ret;
6303 }
6304
6305 static int
6306 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6307 {
6308   unformat_input_t *i = vam->input;
6309   vl_api_sw_interface_set_mpls_enable_t *mp;
6310   u32 sw_if_index;
6311   u8 sw_if_index_set = 0;
6312   u8 enable = 1;
6313   int ret;
6314
6315   /* Parse args required to build the message */
6316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6317     {
6318       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6319         sw_if_index_set = 1;
6320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6321         sw_if_index_set = 1;
6322       else if (unformat (i, "disable"))
6323         enable = 0;
6324       else if (unformat (i, "dis"))
6325         enable = 0;
6326       else
6327         break;
6328     }
6329
6330   if (sw_if_index_set == 0)
6331     {
6332       errmsg ("missing interface name or sw_if_index");
6333       return -99;
6334     }
6335
6336   /* Construct the API message */
6337   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6338
6339   mp->sw_if_index = ntohl (sw_if_index);
6340   mp->enable = enable;
6341
6342   /* send it... */
6343   S (mp);
6344
6345   /* Wait for a reply... */
6346   W (ret);
6347   return ret;
6348 }
6349
6350 static int
6351 api_sw_interface_set_table (vat_main_t * vam)
6352 {
6353   unformat_input_t *i = vam->input;
6354   vl_api_sw_interface_set_table_t *mp;
6355   u32 sw_if_index, vrf_id = 0;
6356   u8 sw_if_index_set = 0;
6357   u8 is_ipv6 = 0;
6358   int ret;
6359
6360   /* Parse args required to build the message */
6361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6362     {
6363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6364         sw_if_index_set = 1;
6365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6366         sw_if_index_set = 1;
6367       else if (unformat (i, "vrf %d", &vrf_id))
6368         ;
6369       else if (unformat (i, "ipv6"))
6370         is_ipv6 = 1;
6371       else
6372         break;
6373     }
6374
6375   if (sw_if_index_set == 0)
6376     {
6377       errmsg ("missing interface name or sw_if_index");
6378       return -99;
6379     }
6380
6381   /* Construct the API message */
6382   M (SW_INTERFACE_SET_TABLE, mp);
6383
6384   mp->sw_if_index = ntohl (sw_if_index);
6385   mp->is_ipv6 = is_ipv6;
6386   mp->vrf_id = ntohl (vrf_id);
6387
6388   /* send it... */
6389   S (mp);
6390
6391   /* Wait for a reply... */
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static void vl_api_sw_interface_get_table_reply_t_handler
6397   (vl_api_sw_interface_get_table_reply_t * mp)
6398 {
6399   vat_main_t *vam = &vat_main;
6400
6401   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6402
6403   vam->retval = ntohl (mp->retval);
6404   vam->result_ready = 1;
6405
6406 }
6407
6408 static void vl_api_sw_interface_get_table_reply_t_handler_json
6409   (vl_api_sw_interface_get_table_reply_t * mp)
6410 {
6411   vat_main_t *vam = &vat_main;
6412   vat_json_node_t node;
6413
6414   vat_json_init_object (&node);
6415   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6416   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6417
6418   vat_json_print (vam->ofp, &node);
6419   vat_json_free (&node);
6420
6421   vam->retval = ntohl (mp->retval);
6422   vam->result_ready = 1;
6423 }
6424
6425 static int
6426 api_sw_interface_get_table (vat_main_t * vam)
6427 {
6428   unformat_input_t *i = vam->input;
6429   vl_api_sw_interface_get_table_t *mp;
6430   u32 sw_if_index;
6431   u8 sw_if_index_set = 0;
6432   u8 is_ipv6 = 0;
6433   int ret;
6434
6435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6438         sw_if_index_set = 1;
6439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6440         sw_if_index_set = 1;
6441       else if (unformat (i, "ipv6"))
6442         is_ipv6 = 1;
6443       else
6444         break;
6445     }
6446
6447   if (sw_if_index_set == 0)
6448     {
6449       errmsg ("missing interface name or sw_if_index");
6450       return -99;
6451     }
6452
6453   M (SW_INTERFACE_GET_TABLE, mp);
6454   mp->sw_if_index = htonl (sw_if_index);
6455   mp->is_ipv6 = is_ipv6;
6456
6457   S (mp);
6458   W (ret);
6459   return ret;
6460 }
6461
6462 static int
6463 api_sw_interface_set_vpath (vat_main_t * vam)
6464 {
6465   unformat_input_t *i = vam->input;
6466   vl_api_sw_interface_set_vpath_t *mp;
6467   u32 sw_if_index = 0;
6468   u8 sw_if_index_set = 0;
6469   u8 is_enable = 0;
6470   int ret;
6471
6472   /* Parse args required to build the message */
6473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6474     {
6475       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6476         sw_if_index_set = 1;
6477       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6478         sw_if_index_set = 1;
6479       else if (unformat (i, "enable"))
6480         is_enable = 1;
6481       else if (unformat (i, "disable"))
6482         is_enable = 0;
6483       else
6484         break;
6485     }
6486
6487   if (sw_if_index_set == 0)
6488     {
6489       errmsg ("missing interface name or sw_if_index");
6490       return -99;
6491     }
6492
6493   /* Construct the API message */
6494   M (SW_INTERFACE_SET_VPATH, mp);
6495
6496   mp->sw_if_index = ntohl (sw_if_index);
6497   mp->enable = is_enable;
6498
6499   /* send it... */
6500   S (mp);
6501
6502   /* Wait for a reply... */
6503   W (ret);
6504   return ret;
6505 }
6506
6507 static int
6508 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6509 {
6510   unformat_input_t *i = vam->input;
6511   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6512   u32 sw_if_index = 0;
6513   u8 sw_if_index_set = 0;
6514   u8 is_enable = 1;
6515   u8 is_ipv6 = 0;
6516   int ret;
6517
6518   /* Parse args required to build the message */
6519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6520     {
6521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6522         sw_if_index_set = 1;
6523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6524         sw_if_index_set = 1;
6525       else if (unformat (i, "enable"))
6526         is_enable = 1;
6527       else if (unformat (i, "disable"))
6528         is_enable = 0;
6529       else if (unformat (i, "ip4"))
6530         is_ipv6 = 0;
6531       else if (unformat (i, "ip6"))
6532         is_ipv6 = 1;
6533       else
6534         break;
6535     }
6536
6537   if (sw_if_index_set == 0)
6538     {
6539       errmsg ("missing interface name or sw_if_index");
6540       return -99;
6541     }
6542
6543   /* Construct the API message */
6544   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6545
6546   mp->sw_if_index = ntohl (sw_if_index);
6547   mp->enable = is_enable;
6548   mp->is_ipv6 = is_ipv6;
6549
6550   /* send it... */
6551   S (mp);
6552
6553   /* Wait for a reply... */
6554   W (ret);
6555   return ret;
6556 }
6557
6558 static int
6559 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6560 {
6561   unformat_input_t *i = vam->input;
6562   vl_api_sw_interface_set_geneve_bypass_t *mp;
6563   u32 sw_if_index = 0;
6564   u8 sw_if_index_set = 0;
6565   u8 is_enable = 1;
6566   u8 is_ipv6 = 0;
6567   int ret;
6568
6569   /* Parse args required to build the message */
6570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6571     {
6572       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6573         sw_if_index_set = 1;
6574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6575         sw_if_index_set = 1;
6576       else if (unformat (i, "enable"))
6577         is_enable = 1;
6578       else if (unformat (i, "disable"))
6579         is_enable = 0;
6580       else if (unformat (i, "ip4"))
6581         is_ipv6 = 0;
6582       else if (unformat (i, "ip6"))
6583         is_ipv6 = 1;
6584       else
6585         break;
6586     }
6587
6588   if (sw_if_index_set == 0)
6589     {
6590       errmsg ("missing interface name or sw_if_index");
6591       return -99;
6592     }
6593
6594   /* Construct the API message */
6595   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6596
6597   mp->sw_if_index = ntohl (sw_if_index);
6598   mp->enable = is_enable;
6599   mp->is_ipv6 = is_ipv6;
6600
6601   /* send it... */
6602   S (mp);
6603
6604   /* Wait for a reply... */
6605   W (ret);
6606   return ret;
6607 }
6608
6609 static int
6610 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6611 {
6612   unformat_input_t *i = vam->input;
6613   vl_api_sw_interface_set_l2_xconnect_t *mp;
6614   u32 rx_sw_if_index;
6615   u8 rx_sw_if_index_set = 0;
6616   u32 tx_sw_if_index;
6617   u8 tx_sw_if_index_set = 0;
6618   u8 enable = 1;
6619   int ret;
6620
6621   /* Parse args required to build the message */
6622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6623     {
6624       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6625         rx_sw_if_index_set = 1;
6626       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6627         tx_sw_if_index_set = 1;
6628       else if (unformat (i, "rx"))
6629         {
6630           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6631             {
6632               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6633                             &rx_sw_if_index))
6634                 rx_sw_if_index_set = 1;
6635             }
6636           else
6637             break;
6638         }
6639       else if (unformat (i, "tx"))
6640         {
6641           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6642             {
6643               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6644                             &tx_sw_if_index))
6645                 tx_sw_if_index_set = 1;
6646             }
6647           else
6648             break;
6649         }
6650       else if (unformat (i, "enable"))
6651         enable = 1;
6652       else if (unformat (i, "disable"))
6653         enable = 0;
6654       else
6655         break;
6656     }
6657
6658   if (rx_sw_if_index_set == 0)
6659     {
6660       errmsg ("missing rx interface name or rx_sw_if_index");
6661       return -99;
6662     }
6663
6664   if (enable && (tx_sw_if_index_set == 0))
6665     {
6666       errmsg ("missing tx interface name or tx_sw_if_index");
6667       return -99;
6668     }
6669
6670   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6671
6672   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6673   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6674   mp->enable = enable;
6675
6676   S (mp);
6677   W (ret);
6678   return ret;
6679 }
6680
6681 static int
6682 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6683 {
6684   unformat_input_t *i = vam->input;
6685   vl_api_sw_interface_set_l2_bridge_t *mp;
6686   vl_api_l2_port_type_t port_type;
6687   u32 rx_sw_if_index;
6688   u8 rx_sw_if_index_set = 0;
6689   u32 bd_id;
6690   u8 bd_id_set = 0;
6691   u32 shg = 0;
6692   u8 enable = 1;
6693   int ret;
6694
6695   port_type = L2_API_PORT_TYPE_NORMAL;
6696
6697   /* Parse args required to build the message */
6698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6699     {
6700       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6701         rx_sw_if_index_set = 1;
6702       else if (unformat (i, "bd_id %d", &bd_id))
6703         bd_id_set = 1;
6704       else
6705         if (unformat
6706             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6707         rx_sw_if_index_set = 1;
6708       else if (unformat (i, "shg %d", &shg))
6709         ;
6710       else if (unformat (i, "bvi"))
6711         port_type = L2_API_PORT_TYPE_BVI;
6712       else if (unformat (i, "uu-fwd"))
6713         port_type = L2_API_PORT_TYPE_UU_FWD;
6714       else if (unformat (i, "enable"))
6715         enable = 1;
6716       else if (unformat (i, "disable"))
6717         enable = 0;
6718       else
6719         break;
6720     }
6721
6722   if (rx_sw_if_index_set == 0)
6723     {
6724       errmsg ("missing rx interface name or sw_if_index");
6725       return -99;
6726     }
6727
6728   if (enable && (bd_id_set == 0))
6729     {
6730       errmsg ("missing bridge domain");
6731       return -99;
6732     }
6733
6734   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6735
6736   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6737   mp->bd_id = ntohl (bd_id);
6738   mp->shg = (u8) shg;
6739   mp->port_type = ntohl (port_type);
6740   mp->enable = enable;
6741
6742   S (mp);
6743   W (ret);
6744   return ret;
6745 }
6746
6747 static int
6748 api_bridge_domain_dump (vat_main_t * vam)
6749 {
6750   unformat_input_t *i = vam->input;
6751   vl_api_bridge_domain_dump_t *mp;
6752   vl_api_control_ping_t *mp_ping;
6753   u32 bd_id = ~0;
6754   int ret;
6755
6756   /* Parse args required to build the message */
6757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6758     {
6759       if (unformat (i, "bd_id %d", &bd_id))
6760         ;
6761       else
6762         break;
6763     }
6764
6765   M (BRIDGE_DOMAIN_DUMP, mp);
6766   mp->bd_id = ntohl (bd_id);
6767   S (mp);
6768
6769   /* Use a control ping for synchronization */
6770   MPING (CONTROL_PING, mp_ping);
6771   S (mp_ping);
6772
6773   W (ret);
6774   return ret;
6775 }
6776
6777 static int
6778 api_bridge_domain_add_del (vat_main_t * vam)
6779 {
6780   unformat_input_t *i = vam->input;
6781   vl_api_bridge_domain_add_del_t *mp;
6782   u32 bd_id = ~0;
6783   u8 is_add = 1;
6784   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6785   u8 *bd_tag = NULL;
6786   u32 mac_age = 0;
6787   int ret;
6788
6789   /* Parse args required to build the message */
6790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6791     {
6792       if (unformat (i, "bd_id %d", &bd_id))
6793         ;
6794       else if (unformat (i, "flood %d", &flood))
6795         ;
6796       else if (unformat (i, "uu-flood %d", &uu_flood))
6797         ;
6798       else if (unformat (i, "forward %d", &forward))
6799         ;
6800       else if (unformat (i, "learn %d", &learn))
6801         ;
6802       else if (unformat (i, "arp-term %d", &arp_term))
6803         ;
6804       else if (unformat (i, "mac-age %d", &mac_age))
6805         ;
6806       else if (unformat (i, "bd-tag %s", &bd_tag))
6807         ;
6808       else if (unformat (i, "del"))
6809         {
6810           is_add = 0;
6811           flood = uu_flood = forward = learn = 0;
6812         }
6813       else
6814         break;
6815     }
6816
6817   if (bd_id == ~0)
6818     {
6819       errmsg ("missing bridge domain");
6820       ret = -99;
6821       goto done;
6822     }
6823
6824   if (mac_age > 255)
6825     {
6826       errmsg ("mac age must be less than 256 ");
6827       ret = -99;
6828       goto done;
6829     }
6830
6831   if ((bd_tag) && (vec_len (bd_tag) > 63))
6832     {
6833       errmsg ("bd-tag cannot be longer than 63");
6834       ret = -99;
6835       goto done;
6836     }
6837
6838   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6839
6840   mp->bd_id = ntohl (bd_id);
6841   mp->flood = flood;
6842   mp->uu_flood = uu_flood;
6843   mp->forward = forward;
6844   mp->learn = learn;
6845   mp->arp_term = arp_term;
6846   mp->is_add = is_add;
6847   mp->mac_age = (u8) mac_age;
6848   if (bd_tag)
6849     {
6850       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6851       mp->bd_tag[vec_len (bd_tag)] = 0;
6852     }
6853   S (mp);
6854   W (ret);
6855
6856 done:
6857   vec_free (bd_tag);
6858   return ret;
6859 }
6860
6861 static int
6862 api_l2fib_flush_bd (vat_main_t * vam)
6863 {
6864   unformat_input_t *i = vam->input;
6865   vl_api_l2fib_flush_bd_t *mp;
6866   u32 bd_id = ~0;
6867   int ret;
6868
6869   /* Parse args required to build the message */
6870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6871     {
6872       if (unformat (i, "bd_id %d", &bd_id));
6873       else
6874         break;
6875     }
6876
6877   if (bd_id == ~0)
6878     {
6879       errmsg ("missing bridge domain");
6880       return -99;
6881     }
6882
6883   M (L2FIB_FLUSH_BD, mp);
6884
6885   mp->bd_id = htonl (bd_id);
6886
6887   S (mp);
6888   W (ret);
6889   return ret;
6890 }
6891
6892 static int
6893 api_l2fib_flush_int (vat_main_t * vam)
6894 {
6895   unformat_input_t *i = vam->input;
6896   vl_api_l2fib_flush_int_t *mp;
6897   u32 sw_if_index = ~0;
6898   int ret;
6899
6900   /* Parse args required to build the message */
6901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6902     {
6903       if (unformat (i, "sw_if_index %d", &sw_if_index));
6904       else
6905         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6906       else
6907         break;
6908     }
6909
6910   if (sw_if_index == ~0)
6911     {
6912       errmsg ("missing interface name or sw_if_index");
6913       return -99;
6914     }
6915
6916   M (L2FIB_FLUSH_INT, mp);
6917
6918   mp->sw_if_index = ntohl (sw_if_index);
6919
6920   S (mp);
6921   W (ret);
6922   return ret;
6923 }
6924
6925 static int
6926 api_l2fib_add_del (vat_main_t * vam)
6927 {
6928   unformat_input_t *i = vam->input;
6929   vl_api_l2fib_add_del_t *mp;
6930   f64 timeout;
6931   u8 mac[6] = { 0 };
6932   u8 mac_set = 0;
6933   u32 bd_id;
6934   u8 bd_id_set = 0;
6935   u32 sw_if_index = 0;
6936   u8 sw_if_index_set = 0;
6937   u8 is_add = 1;
6938   u8 static_mac = 0;
6939   u8 filter_mac = 0;
6940   u8 bvi_mac = 0;
6941   int count = 1;
6942   f64 before = 0;
6943   int j;
6944
6945   /* Parse args required to build the message */
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6949         mac_set = 1;
6950       else if (unformat (i, "bd_id %d", &bd_id))
6951         bd_id_set = 1;
6952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6953         sw_if_index_set = 1;
6954       else if (unformat (i, "sw_if"))
6955         {
6956           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6957             {
6958               if (unformat
6959                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6960                 sw_if_index_set = 1;
6961             }
6962           else
6963             break;
6964         }
6965       else if (unformat (i, "static"))
6966         static_mac = 1;
6967       else if (unformat (i, "filter"))
6968         {
6969           filter_mac = 1;
6970           static_mac = 1;
6971         }
6972       else if (unformat (i, "bvi"))
6973         {
6974           bvi_mac = 1;
6975           static_mac = 1;
6976         }
6977       else if (unformat (i, "del"))
6978         is_add = 0;
6979       else if (unformat (i, "count %d", &count))
6980         ;
6981       else
6982         break;
6983     }
6984
6985   if (mac_set == 0)
6986     {
6987       errmsg ("missing mac address");
6988       return -99;
6989     }
6990
6991   if (bd_id_set == 0)
6992     {
6993       errmsg ("missing bridge domain");
6994       return -99;
6995     }
6996
6997   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6998     {
6999       errmsg ("missing interface name or sw_if_index");
7000       return -99;
7001     }
7002
7003   if (count > 1)
7004     {
7005       /* Turn on async mode */
7006       vam->async_mode = 1;
7007       vam->async_errors = 0;
7008       before = vat_time_now (vam);
7009     }
7010
7011   for (j = 0; j < count; j++)
7012     {
7013       M (L2FIB_ADD_DEL, mp);
7014
7015       clib_memcpy (mp->mac, mac, 6);
7016       mp->bd_id = ntohl (bd_id);
7017       mp->is_add = is_add;
7018       mp->sw_if_index = ntohl (sw_if_index);
7019
7020       if (is_add)
7021         {
7022           mp->static_mac = static_mac;
7023           mp->filter_mac = filter_mac;
7024           mp->bvi_mac = bvi_mac;
7025         }
7026       increment_mac_address (mac);
7027       /* send it... */
7028       S (mp);
7029     }
7030
7031   if (count > 1)
7032     {
7033       vl_api_control_ping_t *mp_ping;
7034       f64 after;
7035
7036       /* Shut off async mode */
7037       vam->async_mode = 0;
7038
7039       MPING (CONTROL_PING, mp_ping);
7040       S (mp_ping);
7041
7042       timeout = vat_time_now (vam) + 1.0;
7043       while (vat_time_now (vam) < timeout)
7044         if (vam->result_ready == 1)
7045           goto out;
7046       vam->retval = -99;
7047
7048     out:
7049       if (vam->retval == -99)
7050         errmsg ("timeout");
7051
7052       if (vam->async_errors > 0)
7053         {
7054           errmsg ("%d asynchronous errors", vam->async_errors);
7055           vam->retval = -98;
7056         }
7057       vam->async_errors = 0;
7058       after = vat_time_now (vam);
7059
7060       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7061              count, after - before, count / (after - before));
7062     }
7063   else
7064     {
7065       int ret;
7066
7067       /* Wait for a reply... */
7068       W (ret);
7069       return ret;
7070     }
7071   /* Return the good/bad news */
7072   return (vam->retval);
7073 }
7074
7075 static int
7076 api_bridge_domain_set_mac_age (vat_main_t * vam)
7077 {
7078   unformat_input_t *i = vam->input;
7079   vl_api_bridge_domain_set_mac_age_t *mp;
7080   u32 bd_id = ~0;
7081   u32 mac_age = 0;
7082   int ret;
7083
7084   /* Parse args required to build the message */
7085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7086     {
7087       if (unformat (i, "bd_id %d", &bd_id));
7088       else if (unformat (i, "mac-age %d", &mac_age));
7089       else
7090         break;
7091     }
7092
7093   if (bd_id == ~0)
7094     {
7095       errmsg ("missing bridge domain");
7096       return -99;
7097     }
7098
7099   if (mac_age > 255)
7100     {
7101       errmsg ("mac age must be less than 256 ");
7102       return -99;
7103     }
7104
7105   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7106
7107   mp->bd_id = htonl (bd_id);
7108   mp->mac_age = (u8) mac_age;
7109
7110   S (mp);
7111   W (ret);
7112   return ret;
7113 }
7114
7115 static int
7116 api_l2_flags (vat_main_t * vam)
7117 {
7118   unformat_input_t *i = vam->input;
7119   vl_api_l2_flags_t *mp;
7120   u32 sw_if_index;
7121   u32 flags = 0;
7122   u8 sw_if_index_set = 0;
7123   u8 is_set = 0;
7124   int ret;
7125
7126   /* Parse args required to build the message */
7127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7128     {
7129       if (unformat (i, "sw_if_index %d", &sw_if_index))
7130         sw_if_index_set = 1;
7131       else if (unformat (i, "sw_if"))
7132         {
7133           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7134             {
7135               if (unformat
7136                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7137                 sw_if_index_set = 1;
7138             }
7139           else
7140             break;
7141         }
7142       else if (unformat (i, "learn"))
7143         flags |= L2_LEARN;
7144       else if (unformat (i, "forward"))
7145         flags |= L2_FWD;
7146       else if (unformat (i, "flood"))
7147         flags |= L2_FLOOD;
7148       else if (unformat (i, "uu-flood"))
7149         flags |= L2_UU_FLOOD;
7150       else if (unformat (i, "arp-term"))
7151         flags |= L2_ARP_TERM;
7152       else if (unformat (i, "off"))
7153         is_set = 0;
7154       else if (unformat (i, "disable"))
7155         is_set = 0;
7156       else
7157         break;
7158     }
7159
7160   if (sw_if_index_set == 0)
7161     {
7162       errmsg ("missing interface name or sw_if_index");
7163       return -99;
7164     }
7165
7166   M (L2_FLAGS, mp);
7167
7168   mp->sw_if_index = ntohl (sw_if_index);
7169   mp->feature_bitmap = ntohl (flags);
7170   mp->is_set = is_set;
7171
7172   S (mp);
7173   W (ret);
7174   return ret;
7175 }
7176
7177 static int
7178 api_bridge_flags (vat_main_t * vam)
7179 {
7180   unformat_input_t *i = vam->input;
7181   vl_api_bridge_flags_t *mp;
7182   u32 bd_id;
7183   u8 bd_id_set = 0;
7184   u8 is_set = 1;
7185   bd_flags_t flags = 0;
7186   int ret;
7187
7188   /* Parse args required to build the message */
7189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7190     {
7191       if (unformat (i, "bd_id %d", &bd_id))
7192         bd_id_set = 1;
7193       else if (unformat (i, "learn"))
7194         flags |= BRIDGE_API_FLAG_LEARN;
7195       else if (unformat (i, "forward"))
7196         flags |= BRIDGE_API_FLAG_FWD;
7197       else if (unformat (i, "flood"))
7198         flags |= BRIDGE_API_FLAG_FLOOD;
7199       else if (unformat (i, "uu-flood"))
7200         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7201       else if (unformat (i, "arp-term"))
7202         flags |= BRIDGE_API_FLAG_ARP_TERM;
7203       else if (unformat (i, "off"))
7204         is_set = 0;
7205       else if (unformat (i, "disable"))
7206         is_set = 0;
7207       else
7208         break;
7209     }
7210
7211   if (bd_id_set == 0)
7212     {
7213       errmsg ("missing bridge domain");
7214       return -99;
7215     }
7216
7217   M (BRIDGE_FLAGS, mp);
7218
7219   mp->bd_id = ntohl (bd_id);
7220   mp->flags = ntohl (flags);
7221   mp->is_set = is_set;
7222
7223   S (mp);
7224   W (ret);
7225   return ret;
7226 }
7227
7228 static int
7229 api_bd_ip_mac_add_del (vat_main_t * vam)
7230 {
7231   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7232   vl_api_mac_address_t mac = { 0 };
7233   unformat_input_t *i = vam->input;
7234   vl_api_bd_ip_mac_add_del_t *mp;
7235   ip46_type_t type;
7236   u32 bd_id;
7237   u8 is_ipv6 = 0;
7238   u8 is_add = 1;
7239   u8 bd_id_set = 0;
7240   u8 ip_set = 0;
7241   u8 mac_set = 0;
7242   u8 macaddr[6];
7243   int ret;
7244
7245
7246   /* Parse args required to build the message */
7247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7248     {
7249       if (unformat (i, "bd_id %d", &bd_id))
7250         {
7251           bd_id_set++;
7252         }
7253       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7254         {
7255           ip_set++;
7256         }
7257       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7258         {
7259           mac_set++;
7260         }
7261       else if (unformat (i, "del"))
7262         is_add = 0;
7263       else
7264         break;
7265     }
7266
7267   if (bd_id_set == 0)
7268     {
7269       errmsg ("missing bridge domain");
7270       return -99;
7271     }
7272   else if (ip_set == 0)
7273     {
7274       errmsg ("missing IP address");
7275       return -99;
7276     }
7277   else if (mac_set == 0)
7278     {
7279       errmsg ("missing MAC address");
7280       return -99;
7281     }
7282
7283   M (BD_IP_MAC_ADD_DEL, mp);
7284
7285   mp->bd_id = ntohl (bd_id);
7286   mp->is_add = is_add;
7287
7288   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7289   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7290
7291   S (mp);
7292   W (ret);
7293   return ret;
7294 }
7295
7296 static int
7297 api_bd_ip_mac_flush (vat_main_t * vam)
7298 {
7299   unformat_input_t *i = vam->input;
7300   vl_api_bd_ip_mac_flush_t *mp;
7301   u32 bd_id;
7302   u8 bd_id_set = 0;
7303   int ret;
7304
7305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7306     {
7307       if (unformat (i, "bd_id %d", &bd_id))
7308         {
7309           bd_id_set++;
7310         }
7311       else
7312         break;
7313     }
7314
7315   if (bd_id_set == 0)
7316     {
7317       errmsg ("missing bridge domain");
7318       return -99;
7319     }
7320
7321   M (BD_IP_MAC_FLUSH, mp);
7322
7323   mp->bd_id = ntohl (bd_id);
7324
7325   S (mp);
7326   W (ret);
7327   return ret;
7328 }
7329
7330 static void vl_api_bd_ip_mac_details_t_handler
7331   (vl_api_bd_ip_mac_details_t * mp)
7332 {
7333   vat_main_t *vam = &vat_main;
7334   u8 *ip = 0;
7335
7336   if (!mp->is_ipv6)
7337     ip =
7338       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7339   else
7340     ip =
7341       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7342
7343   print (vam->ofp,
7344          "\n%-5d %-7s %-20U %-30s",
7345          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7346          format_ethernet_address, mp->mac_address, ip);
7347
7348   vec_free (ip);
7349 }
7350
7351 static void vl_api_bd_ip_mac_details_t_handler_json
7352   (vl_api_bd_ip_mac_details_t * mp)
7353 {
7354   vat_main_t *vam = &vat_main;
7355   vat_json_node_t *node = NULL;
7356
7357   if (VAT_JSON_ARRAY != vam->json_tree.type)
7358     {
7359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7360       vat_json_init_array (&vam->json_tree);
7361     }
7362   node = vat_json_array_add (&vam->json_tree);
7363
7364   vat_json_init_object (node);
7365   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7366   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7367   vat_json_object_add_string_copy (node, "mac_address",
7368                                    format (0, "%U", format_ethernet_address,
7369                                            &mp->mac_address));
7370   u8 *ip = 0;
7371
7372   if (!mp->is_ipv6)
7373     ip =
7374       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7375   else
7376     ip =
7377       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7378   vat_json_object_add_string_copy (node, "ip_address", ip);
7379   vec_free (ip);
7380 }
7381
7382 static int
7383 api_bd_ip_mac_dump (vat_main_t * vam)
7384 {
7385   unformat_input_t *i = vam->input;
7386   vl_api_bd_ip_mac_dump_t *mp;
7387   vl_api_control_ping_t *mp_ping;
7388   int ret;
7389   u32 bd_id;
7390   u8 bd_id_set = 0;
7391
7392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7393     {
7394       if (unformat (i, "bd_id %d", &bd_id))
7395         {
7396           bd_id_set++;
7397         }
7398       else
7399         break;
7400     }
7401
7402   print (vam->ofp,
7403          "\n%-5s %-7s %-20s %-30s",
7404          "bd_id", "is_ipv6", "mac_address", "ip_address");
7405
7406   /* Dump Bridge Domain Ip to Mac entries */
7407   M (BD_IP_MAC_DUMP, mp);
7408
7409   if (bd_id_set)
7410     mp->bd_id = htonl (bd_id);
7411   else
7412     mp->bd_id = ~0;
7413
7414   S (mp);
7415
7416   /* Use a control ping for synchronization */
7417   MPING (CONTROL_PING, mp_ping);
7418   S (mp_ping);
7419
7420   W (ret);
7421   return ret;
7422 }
7423
7424 static int
7425 api_tap_create_v2 (vat_main_t * vam)
7426 {
7427   unformat_input_t *i = vam->input;
7428   vl_api_tap_create_v2_t *mp;
7429   u8 mac_address[6];
7430   u8 random_mac = 1;
7431   u32 id = ~0;
7432   u8 *host_if_name = 0;
7433   u8 *host_ns = 0;
7434   u8 host_mac_addr[6];
7435   u8 host_mac_addr_set = 0;
7436   u8 *host_bridge = 0;
7437   ip4_address_t host_ip4_addr;
7438   ip4_address_t host_ip4_gw;
7439   u8 host_ip4_gw_set = 0;
7440   u32 host_ip4_prefix_len = 0;
7441   ip6_address_t host_ip6_addr;
7442   ip6_address_t host_ip6_gw;
7443   u8 host_ip6_gw_set = 0;
7444   u32 host_ip6_prefix_len = 0;
7445   int ret;
7446   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7447
7448   clib_memset (mac_address, 0, sizeof (mac_address));
7449
7450   /* Parse args required to build the message */
7451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7452     {
7453       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7454         {
7455           random_mac = 0;
7456         }
7457       else if (unformat (i, "id %u", &id))
7458         ;
7459       else if (unformat (i, "host-if-name %s", &host_if_name))
7460         ;
7461       else if (unformat (i, "host-ns %s", &host_ns))
7462         ;
7463       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7464                          host_mac_addr))
7465         host_mac_addr_set = 1;
7466       else if (unformat (i, "host-bridge %s", &host_bridge))
7467         ;
7468       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7469                          &host_ip4_addr, &host_ip4_prefix_len))
7470         ;
7471       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7472                          &host_ip6_addr, &host_ip6_prefix_len))
7473         ;
7474       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7475                          &host_ip4_gw))
7476         host_ip4_gw_set = 1;
7477       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7478                          &host_ip6_gw))
7479         host_ip6_gw_set = 1;
7480       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7481         ;
7482       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7483         ;
7484       else
7485         break;
7486     }
7487
7488   if (vec_len (host_if_name) > 63)
7489     {
7490       errmsg ("tap name too long. ");
7491       return -99;
7492     }
7493   if (vec_len (host_ns) > 63)
7494     {
7495       errmsg ("host name space too long. ");
7496       return -99;
7497     }
7498   if (vec_len (host_bridge) > 63)
7499     {
7500       errmsg ("host bridge name too long. ");
7501       return -99;
7502     }
7503   if (host_ip4_prefix_len > 32)
7504     {
7505       errmsg ("host ip4 prefix length not valid. ");
7506       return -99;
7507     }
7508   if (host_ip6_prefix_len > 128)
7509     {
7510       errmsg ("host ip6 prefix length not valid. ");
7511       return -99;
7512     }
7513   if (!is_pow2 (rx_ring_sz))
7514     {
7515       errmsg ("rx ring size must be power of 2. ");
7516       return -99;
7517     }
7518   if (rx_ring_sz > 32768)
7519     {
7520       errmsg ("rx ring size must be 32768 or lower. ");
7521       return -99;
7522     }
7523   if (!is_pow2 (tx_ring_sz))
7524     {
7525       errmsg ("tx ring size must be power of 2. ");
7526       return -99;
7527     }
7528   if (tx_ring_sz > 32768)
7529     {
7530       errmsg ("tx ring size must be 32768 or lower. ");
7531       return -99;
7532     }
7533
7534   /* Construct the API message */
7535   M (TAP_CREATE_V2, mp);
7536
7537   mp->use_random_mac = random_mac;
7538
7539   mp->id = ntohl (id);
7540   mp->host_namespace_set = host_ns != 0;
7541   mp->host_bridge_set = host_bridge != 0;
7542   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7543   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7544   mp->rx_ring_sz = ntohs (rx_ring_sz);
7545   mp->tx_ring_sz = ntohs (tx_ring_sz);
7546
7547   if (random_mac == 0)
7548     clib_memcpy (mp->mac_address, mac_address, 6);
7549   if (host_mac_addr_set)
7550     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7551   if (host_if_name)
7552     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7553   if (host_ns)
7554     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7555   if (host_bridge)
7556     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7557   if (host_ip4_prefix_len)
7558     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7559   if (host_ip6_prefix_len)
7560     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7561   if (host_ip4_gw_set)
7562     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7563   if (host_ip6_gw_set)
7564     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7565
7566   vec_free (host_ns);
7567   vec_free (host_if_name);
7568   vec_free (host_bridge);
7569
7570   /* send it... */
7571   S (mp);
7572
7573   /* Wait for a reply... */
7574   W (ret);
7575   return ret;
7576 }
7577
7578 static int
7579 api_tap_delete_v2 (vat_main_t * vam)
7580 {
7581   unformat_input_t *i = vam->input;
7582   vl_api_tap_delete_v2_t *mp;
7583   u32 sw_if_index = ~0;
7584   u8 sw_if_index_set = 0;
7585   int ret;
7586
7587   /* Parse args required to build the message */
7588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7589     {
7590       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7591         sw_if_index_set = 1;
7592       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7593         sw_if_index_set = 1;
7594       else
7595         break;
7596     }
7597
7598   if (sw_if_index_set == 0)
7599     {
7600       errmsg ("missing vpp interface name. ");
7601       return -99;
7602     }
7603
7604   /* Construct the API message */
7605   M (TAP_DELETE_V2, mp);
7606
7607   mp->sw_if_index = ntohl (sw_if_index);
7608
7609   /* send it... */
7610   S (mp);
7611
7612   /* Wait for a reply... */
7613   W (ret);
7614   return ret;
7615 }
7616
7617 uword
7618 unformat_pci_addr (unformat_input_t * input, va_list * args)
7619 {
7620   struct pci_addr_t
7621   {
7622     u16 domain;
7623     u8 bus;
7624     u8 slot:5;
7625     u8 function:3;
7626   } *addr;
7627   addr = va_arg (*args, struct pci_addr_t *);
7628   u32 x[4];
7629
7630   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7631     return 0;
7632
7633   addr->domain = x[0];
7634   addr->bus = x[1];
7635   addr->slot = x[2];
7636   addr->function = x[3];
7637
7638   return 1;
7639 }
7640
7641 static int
7642 api_virtio_pci_create (vat_main_t * vam)
7643 {
7644   unformat_input_t *i = vam->input;
7645   vl_api_virtio_pci_create_t *mp;
7646   u8 mac_address[6];
7647   u8 random_mac = 1;
7648   u32 pci_addr = 0;
7649   u64 features = (u64) ~ (0ULL);
7650   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7651   int ret;
7652
7653   clib_memset (mac_address, 0, sizeof (mac_address));
7654
7655   /* Parse args required to build the message */
7656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7657     {
7658       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7659         {
7660           random_mac = 0;
7661         }
7662       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7663         ;
7664       else if (unformat (i, "features 0x%llx", &features))
7665         ;
7666       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7667         ;
7668       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7669         ;
7670       else
7671         break;
7672     }
7673
7674   if (pci_addr == 0)
7675     {
7676       errmsg ("pci address must be non zero. ");
7677       return -99;
7678     }
7679   if (!is_pow2 (rx_ring_sz))
7680     {
7681       errmsg ("rx ring size must be power of 2. ");
7682       return -99;
7683     }
7684   if (rx_ring_sz > 32768)
7685     {
7686       errmsg ("rx ring size must be 32768 or lower. ");
7687       return -99;
7688     }
7689   if (!is_pow2 (tx_ring_sz))
7690     {
7691       errmsg ("tx ring size must be power of 2. ");
7692       return -99;
7693     }
7694   if (tx_ring_sz > 32768)
7695     {
7696       errmsg ("tx ring size must be 32768 or lower. ");
7697       return -99;
7698     }
7699
7700   /* Construct the API message */
7701   M (VIRTIO_PCI_CREATE, mp);
7702
7703   mp->use_random_mac = random_mac;
7704
7705   mp->pci_addr = htonl (pci_addr);
7706   mp->features = clib_host_to_net_u64 (features);
7707   mp->rx_ring_sz = htons (rx_ring_sz);
7708   mp->tx_ring_sz = htons (tx_ring_sz);
7709
7710   if (random_mac == 0)
7711     clib_memcpy (mp->mac_address, mac_address, 6);
7712
7713   /* send it... */
7714   S (mp);
7715
7716   /* Wait for a reply... */
7717   W (ret);
7718   return ret;
7719 }
7720
7721 static int
7722 api_virtio_pci_delete (vat_main_t * vam)
7723 {
7724   unformat_input_t *i = vam->input;
7725   vl_api_virtio_pci_delete_t *mp;
7726   u32 sw_if_index = ~0;
7727   u8 sw_if_index_set = 0;
7728   int ret;
7729
7730   /* Parse args required to build the message */
7731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7732     {
7733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7734         sw_if_index_set = 1;
7735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7736         sw_if_index_set = 1;
7737       else
7738         break;
7739     }
7740
7741   if (sw_if_index_set == 0)
7742     {
7743       errmsg ("missing vpp interface name. ");
7744       return -99;
7745     }
7746
7747   /* Construct the API message */
7748   M (VIRTIO_PCI_DELETE, mp);
7749
7750   mp->sw_if_index = htonl (sw_if_index);
7751
7752   /* send it... */
7753   S (mp);
7754
7755   /* Wait for a reply... */
7756   W (ret);
7757   return ret;
7758 }
7759
7760 static int
7761 api_bond_create (vat_main_t * vam)
7762 {
7763   unformat_input_t *i = vam->input;
7764   vl_api_bond_create_t *mp;
7765   u8 mac_address[6];
7766   u8 custom_mac = 0;
7767   int ret;
7768   u8 mode;
7769   u8 lb;
7770   u8 mode_is_set = 0;
7771   u32 id = ~0;
7772
7773   clib_memset (mac_address, 0, sizeof (mac_address));
7774   lb = BOND_LB_L2;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7780         mode_is_set = 1;
7781       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7782                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7783         ;
7784       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7785                          mac_address))
7786         custom_mac = 1;
7787       else if (unformat (i, "id %u", &id))
7788         ;
7789       else
7790         break;
7791     }
7792
7793   if (mode_is_set == 0)
7794     {
7795       errmsg ("Missing bond mode. ");
7796       return -99;
7797     }
7798
7799   /* Construct the API message */
7800   M (BOND_CREATE, mp);
7801
7802   mp->use_custom_mac = custom_mac;
7803
7804   mp->mode = mode;
7805   mp->lb = lb;
7806   mp->id = htonl (id);
7807
7808   if (custom_mac)
7809     clib_memcpy (mp->mac_address, mac_address, 6);
7810
7811   /* send it... */
7812   S (mp);
7813
7814   /* Wait for a reply... */
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_bond_delete (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_bond_delete_t *mp;
7824   u32 sw_if_index = ~0;
7825   u8 sw_if_index_set = 0;
7826   int ret;
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7832         sw_if_index_set = 1;
7833       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7834         sw_if_index_set = 1;
7835       else
7836         break;
7837     }
7838
7839   if (sw_if_index_set == 0)
7840     {
7841       errmsg ("missing vpp interface name. ");
7842       return -99;
7843     }
7844
7845   /* Construct the API message */
7846   M (BOND_DELETE, mp);
7847
7848   mp->sw_if_index = ntohl (sw_if_index);
7849
7850   /* send it... */
7851   S (mp);
7852
7853   /* Wait for a reply... */
7854   W (ret);
7855   return ret;
7856 }
7857
7858 static int
7859 api_bond_enslave (vat_main_t * vam)
7860 {
7861   unformat_input_t *i = vam->input;
7862   vl_api_bond_enslave_t *mp;
7863   u32 bond_sw_if_index;
7864   int ret;
7865   u8 is_passive;
7866   u8 is_long_timeout;
7867   u32 bond_sw_if_index_is_set = 0;
7868   u32 sw_if_index;
7869   u8 sw_if_index_is_set = 0;
7870
7871   /* Parse args required to build the message */
7872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7873     {
7874       if (unformat (i, "sw_if_index %d", &sw_if_index))
7875         sw_if_index_is_set = 1;
7876       else if (unformat (i, "bond %u", &bond_sw_if_index))
7877         bond_sw_if_index_is_set = 1;
7878       else if (unformat (i, "passive %d", &is_passive))
7879         ;
7880       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7881         ;
7882       else
7883         break;
7884     }
7885
7886   if (bond_sw_if_index_is_set == 0)
7887     {
7888       errmsg ("Missing bond sw_if_index. ");
7889       return -99;
7890     }
7891   if (sw_if_index_is_set == 0)
7892     {
7893       errmsg ("Missing slave sw_if_index. ");
7894       return -99;
7895     }
7896
7897   /* Construct the API message */
7898   M (BOND_ENSLAVE, mp);
7899
7900   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7901   mp->sw_if_index = ntohl (sw_if_index);
7902   mp->is_long_timeout = is_long_timeout;
7903   mp->is_passive = is_passive;
7904
7905   /* send it... */
7906   S (mp);
7907
7908   /* Wait for a reply... */
7909   W (ret);
7910   return ret;
7911 }
7912
7913 static int
7914 api_bond_detach_slave (vat_main_t * vam)
7915 {
7916   unformat_input_t *i = vam->input;
7917   vl_api_bond_detach_slave_t *mp;
7918   u32 sw_if_index = ~0;
7919   u8 sw_if_index_set = 0;
7920   int ret;
7921
7922   /* Parse args required to build the message */
7923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7924     {
7925       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7926         sw_if_index_set = 1;
7927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7928         sw_if_index_set = 1;
7929       else
7930         break;
7931     }
7932
7933   if (sw_if_index_set == 0)
7934     {
7935       errmsg ("missing vpp interface name. ");
7936       return -99;
7937     }
7938
7939   /* Construct the API message */
7940   M (BOND_DETACH_SLAVE, mp);
7941
7942   mp->sw_if_index = ntohl (sw_if_index);
7943
7944   /* send it... */
7945   S (mp);
7946
7947   /* Wait for a reply... */
7948   W (ret);
7949   return ret;
7950 }
7951
7952 static int
7953 api_ip_table_add_del (vat_main_t * vam)
7954 {
7955   unformat_input_t *i = vam->input;
7956   vl_api_ip_table_add_del_t *mp;
7957   u32 table_id = ~0;
7958   u8 is_ipv6 = 0;
7959   u8 is_add = 1;
7960   int ret = 0;
7961
7962   /* Parse args required to build the message */
7963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7964     {
7965       if (unformat (i, "ipv6"))
7966         is_ipv6 = 1;
7967       else if (unformat (i, "del"))
7968         is_add = 0;
7969       else if (unformat (i, "add"))
7970         is_add = 1;
7971       else if (unformat (i, "table %d", &table_id))
7972         ;
7973       else
7974         {
7975           clib_warning ("parse error '%U'", format_unformat_error, i);
7976           return -99;
7977         }
7978     }
7979
7980   if (~0 == table_id)
7981     {
7982       errmsg ("missing table-ID");
7983       return -99;
7984     }
7985
7986   /* Construct the API message */
7987   M (IP_TABLE_ADD_DEL, mp);
7988
7989   mp->table_id = ntohl (table_id);
7990   mp->is_ipv6 = is_ipv6;
7991   mp->is_add = is_add;
7992
7993   /* send it... */
7994   S (mp);
7995
7996   /* Wait for a reply... */
7997   W (ret);
7998
7999   return ret;
8000 }
8001
8002 static int
8003 api_ip_add_del_route (vat_main_t * vam)
8004 {
8005   unformat_input_t *i = vam->input;
8006   vl_api_ip_add_del_route_t *mp;
8007   u32 sw_if_index = ~0, vrf_id = 0;
8008   u8 is_ipv6 = 0;
8009   u8 is_local = 0, is_drop = 0;
8010   u8 is_unreach = 0, is_prohibit = 0;
8011   u8 is_add = 1;
8012   u32 next_hop_weight = 1;
8013   u8 is_multipath = 0;
8014   u8 address_set = 0;
8015   u8 address_length_set = 0;
8016   u32 next_hop_table_id = 0;
8017   u32 resolve_attempts = 0;
8018   u32 dst_address_length = 0;
8019   u8 next_hop_set = 0;
8020   ip4_address_t v4_dst_address, v4_next_hop_address;
8021   ip6_address_t v6_dst_address, v6_next_hop_address;
8022   int count = 1;
8023   int j;
8024   f64 before = 0;
8025   u32 random_add_del = 0;
8026   u32 *random_vector = 0;
8027   uword *random_hash;
8028   u32 random_seed = 0xdeaddabe;
8029   u32 classify_table_index = ~0;
8030   u8 is_classify = 0;
8031   u8 resolve_host = 0, resolve_attached = 0;
8032   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8033   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8034   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8035
8036   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8037   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8038   /* Parse args required to build the message */
8039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8040     {
8041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8042         ;
8043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8044         ;
8045       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8046         {
8047           address_set = 1;
8048           is_ipv6 = 0;
8049         }
8050       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8051         {
8052           address_set = 1;
8053           is_ipv6 = 1;
8054         }
8055       else if (unformat (i, "/%d", &dst_address_length))
8056         {
8057           address_length_set = 1;
8058         }
8059
8060       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8061                                          &v4_next_hop_address))
8062         {
8063           next_hop_set = 1;
8064         }
8065       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8066                                          &v6_next_hop_address))
8067         {
8068           next_hop_set = 1;
8069         }
8070       else
8071         if (unformat
8072             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8073         {
8074           next_hop_set = 1;
8075         }
8076       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8077         {
8078           next_hop_set = 1;
8079         }
8080       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8081         ;
8082       else if (unformat (i, "weight %d", &next_hop_weight))
8083         ;
8084       else if (unformat (i, "drop"))
8085         {
8086           is_drop = 1;
8087         }
8088       else if (unformat (i, "null-send-unreach"))
8089         {
8090           is_unreach = 1;
8091         }
8092       else if (unformat (i, "null-send-prohibit"))
8093         {
8094           is_prohibit = 1;
8095         }
8096       else if (unformat (i, "local"))
8097         {
8098           is_local = 1;
8099         }
8100       else if (unformat (i, "classify %d", &classify_table_index))
8101         {
8102           is_classify = 1;
8103         }
8104       else if (unformat (i, "del"))
8105         is_add = 0;
8106       else if (unformat (i, "add"))
8107         is_add = 1;
8108       else if (unformat (i, "resolve-via-host"))
8109         resolve_host = 1;
8110       else if (unformat (i, "resolve-via-attached"))
8111         resolve_attached = 1;
8112       else if (unformat (i, "multipath"))
8113         is_multipath = 1;
8114       else if (unformat (i, "vrf %d", &vrf_id))
8115         ;
8116       else if (unformat (i, "count %d", &count))
8117         ;
8118       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8119         ;
8120       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8121         ;
8122       else if (unformat (i, "out-label %d", &next_hop_out_label))
8123         {
8124           vl_api_fib_mpls_label_t fib_label = {
8125             .label = ntohl (next_hop_out_label),
8126             .ttl = 64,
8127             .exp = 0,
8128           };
8129           vec_add1 (next_hop_out_label_stack, fib_label);
8130         }
8131       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8132         ;
8133       else if (unformat (i, "random"))
8134         random_add_del = 1;
8135       else if (unformat (i, "seed %d", &random_seed))
8136         ;
8137       else
8138         {
8139           clib_warning ("parse error '%U'", format_unformat_error, i);
8140           return -99;
8141         }
8142     }
8143
8144   if (!next_hop_set && !is_drop && !is_local &&
8145       !is_classify && !is_unreach && !is_prohibit &&
8146       MPLS_LABEL_INVALID == next_hop_via_label)
8147     {
8148       errmsg
8149         ("next hop / local / drop / unreach / prohibit / classify not set");
8150       return -99;
8151     }
8152
8153   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8154     {
8155       errmsg ("next hop and next-hop via label set");
8156       return -99;
8157     }
8158   if (address_set == 0)
8159     {
8160       errmsg ("missing addresses");
8161       return -99;
8162     }
8163
8164   if (address_length_set == 0)
8165     {
8166       errmsg ("missing address length");
8167       return -99;
8168     }
8169
8170   /* Generate a pile of unique, random routes */
8171   if (random_add_del)
8172     {
8173       u32 this_random_address;
8174       random_hash = hash_create (count, sizeof (uword));
8175
8176       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8177       for (j = 0; j <= count; j++)
8178         {
8179           do
8180             {
8181               this_random_address = random_u32 (&random_seed);
8182               this_random_address =
8183                 clib_host_to_net_u32 (this_random_address);
8184             }
8185           while (hash_get (random_hash, this_random_address));
8186           vec_add1 (random_vector, this_random_address);
8187           hash_set (random_hash, this_random_address, 1);
8188         }
8189       hash_free (random_hash);
8190       v4_dst_address.as_u32 = random_vector[0];
8191     }
8192
8193   if (count > 1)
8194     {
8195       /* Turn on async mode */
8196       vam->async_mode = 1;
8197       vam->async_errors = 0;
8198       before = vat_time_now (vam);
8199     }
8200
8201   for (j = 0; j < count; j++)
8202     {
8203       /* Construct the API message */
8204       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8205           vec_len (next_hop_out_label_stack));
8206
8207       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8208       mp->table_id = ntohl (vrf_id);
8209
8210       mp->is_add = is_add;
8211       mp->is_drop = is_drop;
8212       mp->is_unreach = is_unreach;
8213       mp->is_prohibit = is_prohibit;
8214       mp->is_ipv6 = is_ipv6;
8215       mp->is_local = is_local;
8216       mp->is_classify = is_classify;
8217       mp->is_multipath = is_multipath;
8218       mp->is_resolve_host = resolve_host;
8219       mp->is_resolve_attached = resolve_attached;
8220       mp->next_hop_weight = next_hop_weight;
8221       mp->next_hop_preference = 0;
8222       mp->dst_address_length = dst_address_length;
8223       mp->next_hop_table_id = ntohl (next_hop_table_id);
8224       mp->classify_table_index = ntohl (classify_table_index);
8225       mp->next_hop_via_label = ntohl (next_hop_via_label);
8226       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8227       if (0 != mp->next_hop_n_out_labels)
8228         {
8229           memcpy (mp->next_hop_out_label_stack,
8230                   next_hop_out_label_stack,
8231                   (vec_len (next_hop_out_label_stack) *
8232                    sizeof (vl_api_fib_mpls_label_t)));
8233           vec_free (next_hop_out_label_stack);
8234         }
8235
8236       if (is_ipv6)
8237         {
8238           clib_memcpy (mp->dst_address, &v6_dst_address,
8239                        sizeof (v6_dst_address));
8240           if (next_hop_set)
8241             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8242                          sizeof (v6_next_hop_address));
8243           increment_v6_address (&v6_dst_address);
8244         }
8245       else
8246         {
8247           clib_memcpy (mp->dst_address, &v4_dst_address,
8248                        sizeof (v4_dst_address));
8249           if (next_hop_set)
8250             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8251                          sizeof (v4_next_hop_address));
8252           if (random_add_del)
8253             v4_dst_address.as_u32 = random_vector[j + 1];
8254           else
8255             increment_v4_address (&v4_dst_address);
8256         }
8257       /* send it... */
8258       S (mp);
8259       /* If we receive SIGTERM, stop now... */
8260       if (vam->do_exit)
8261         break;
8262     }
8263
8264   /* When testing multiple add/del ops, use a control-ping to sync */
8265   if (count > 1)
8266     {
8267       vl_api_control_ping_t *mp_ping;
8268       f64 after;
8269       f64 timeout;
8270
8271       /* Shut off async mode */
8272       vam->async_mode = 0;
8273
8274       MPING (CONTROL_PING, mp_ping);
8275       S (mp_ping);
8276
8277       timeout = vat_time_now (vam) + 1.0;
8278       while (vat_time_now (vam) < timeout)
8279         if (vam->result_ready == 1)
8280           goto out;
8281       vam->retval = -99;
8282
8283     out:
8284       if (vam->retval == -99)
8285         errmsg ("timeout");
8286
8287       if (vam->async_errors > 0)
8288         {
8289           errmsg ("%d asynchronous errors", vam->async_errors);
8290           vam->retval = -98;
8291         }
8292       vam->async_errors = 0;
8293       after = vat_time_now (vam);
8294
8295       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8296       if (j > 0)
8297         count = j;
8298
8299       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8300              count, after - before, count / (after - before));
8301     }
8302   else
8303     {
8304       int ret;
8305
8306       /* Wait for a reply... */
8307       W (ret);
8308       return ret;
8309     }
8310
8311   /* Return the good/bad news */
8312   return (vam->retval);
8313 }
8314
8315 static int
8316 api_ip_mroute_add_del (vat_main_t * vam)
8317 {
8318   unformat_input_t *i = vam->input;
8319   vl_api_ip_mroute_add_del_t *mp;
8320   u32 sw_if_index = ~0, vrf_id = 0;
8321   u8 is_ipv6 = 0;
8322   u8 is_local = 0;
8323   u8 is_add = 1;
8324   u8 address_set = 0;
8325   u32 grp_address_length = 0;
8326   ip4_address_t v4_grp_address, v4_src_address;
8327   ip6_address_t v6_grp_address, v6_src_address;
8328   mfib_itf_flags_t iflags = 0;
8329   mfib_entry_flags_t eflags = 0;
8330   int ret;
8331
8332   /* Parse args required to build the message */
8333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8334     {
8335       if (unformat (i, "sw_if_index %d", &sw_if_index))
8336         ;
8337       else if (unformat (i, "%U %U",
8338                          unformat_ip4_address, &v4_src_address,
8339                          unformat_ip4_address, &v4_grp_address))
8340         {
8341           grp_address_length = 64;
8342           address_set = 1;
8343           is_ipv6 = 0;
8344         }
8345       else if (unformat (i, "%U %U",
8346                          unformat_ip6_address, &v6_src_address,
8347                          unformat_ip6_address, &v6_grp_address))
8348         {
8349           grp_address_length = 256;
8350           address_set = 1;
8351           is_ipv6 = 1;
8352         }
8353       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8354         {
8355           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8356           grp_address_length = 32;
8357           address_set = 1;
8358           is_ipv6 = 0;
8359         }
8360       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8361         {
8362           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8363           grp_address_length = 128;
8364           address_set = 1;
8365           is_ipv6 = 1;
8366         }
8367       else if (unformat (i, "/%d", &grp_address_length))
8368         ;
8369       else if (unformat (i, "local"))
8370         {
8371           is_local = 1;
8372         }
8373       else if (unformat (i, "del"))
8374         is_add = 0;
8375       else if (unformat (i, "add"))
8376         is_add = 1;
8377       else if (unformat (i, "vrf %d", &vrf_id))
8378         ;
8379       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8380         ;
8381       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8382         ;
8383       else
8384         {
8385           clib_warning ("parse error '%U'", format_unformat_error, i);
8386           return -99;
8387         }
8388     }
8389
8390   if (address_set == 0)
8391     {
8392       errmsg ("missing addresses\n");
8393       return -99;
8394     }
8395
8396   /* Construct the API message */
8397   M (IP_MROUTE_ADD_DEL, mp);
8398
8399   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8400   mp->table_id = ntohl (vrf_id);
8401
8402   mp->is_add = is_add;
8403   mp->is_ipv6 = is_ipv6;
8404   mp->is_local = is_local;
8405   mp->itf_flags = ntohl (iflags);
8406   mp->entry_flags = ntohl (eflags);
8407   mp->grp_address_length = grp_address_length;
8408   mp->grp_address_length = ntohs (mp->grp_address_length);
8409
8410   if (is_ipv6)
8411     {
8412       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8413       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8414     }
8415   else
8416     {
8417       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8418       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8419
8420     }
8421
8422   /* send it... */
8423   S (mp);
8424   /* Wait for a reply... */
8425   W (ret);
8426   return ret;
8427 }
8428
8429 static int
8430 api_mpls_table_add_del (vat_main_t * vam)
8431 {
8432   unformat_input_t *i = vam->input;
8433   vl_api_mpls_table_add_del_t *mp;
8434   u32 table_id = ~0;
8435   u8 is_add = 1;
8436   int ret = 0;
8437
8438   /* Parse args required to build the message */
8439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8440     {
8441       if (unformat (i, "table %d", &table_id))
8442         ;
8443       else if (unformat (i, "del"))
8444         is_add = 0;
8445       else if (unformat (i, "add"))
8446         is_add = 1;
8447       else
8448         {
8449           clib_warning ("parse error '%U'", format_unformat_error, i);
8450           return -99;
8451         }
8452     }
8453
8454   if (~0 == table_id)
8455     {
8456       errmsg ("missing table-ID");
8457       return -99;
8458     }
8459
8460   /* Construct the API message */
8461   M (MPLS_TABLE_ADD_DEL, mp);
8462
8463   mp->mt_table_id = ntohl (table_id);
8464   mp->mt_is_add = is_add;
8465
8466   /* send it... */
8467   S (mp);
8468
8469   /* Wait for a reply... */
8470   W (ret);
8471
8472   return ret;
8473 }
8474
8475 static int
8476 api_mpls_route_add_del (vat_main_t * vam)
8477 {
8478   unformat_input_t *i = vam->input;
8479   vl_api_mpls_route_add_del_t *mp;
8480   u32 sw_if_index = ~0, table_id = 0;
8481   u8 is_add = 1;
8482   u32 next_hop_weight = 1;
8483   u8 is_multipath = 0;
8484   u32 next_hop_table_id = 0;
8485   u8 next_hop_set = 0;
8486   ip4_address_t v4_next_hop_address = {
8487     .as_u32 = 0,
8488   };
8489   ip6_address_t v6_next_hop_address = { {0} };
8490   int count = 1;
8491   int j;
8492   f64 before = 0;
8493   u32 classify_table_index = ~0;
8494   u8 is_classify = 0;
8495   u8 resolve_host = 0, resolve_attached = 0;
8496   u8 is_interface_rx = 0;
8497   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8498   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8499   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8500   mpls_label_t local_label = MPLS_LABEL_INVALID;
8501   u8 is_eos = 0;
8502   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8503
8504   /* Parse args required to build the message */
8505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8506     {
8507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8508         ;
8509       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8510         ;
8511       else if (unformat (i, "%d", &local_label))
8512         ;
8513       else if (unformat (i, "eos"))
8514         is_eos = 1;
8515       else if (unformat (i, "non-eos"))
8516         is_eos = 0;
8517       else if (unformat (i, "via %U", unformat_ip4_address,
8518                          &v4_next_hop_address))
8519         {
8520           next_hop_set = 1;
8521           next_hop_proto = DPO_PROTO_IP4;
8522         }
8523       else if (unformat (i, "via %U", unformat_ip6_address,
8524                          &v6_next_hop_address))
8525         {
8526           next_hop_set = 1;
8527           next_hop_proto = DPO_PROTO_IP6;
8528         }
8529       else if (unformat (i, "weight %d", &next_hop_weight))
8530         ;
8531       else if (unformat (i, "classify %d", &classify_table_index))
8532         {
8533           is_classify = 1;
8534         }
8535       else if (unformat (i, "del"))
8536         is_add = 0;
8537       else if (unformat (i, "add"))
8538         is_add = 1;
8539       else if (unformat (i, "resolve-via-host"))
8540         resolve_host = 1;
8541       else if (unformat (i, "resolve-via-attached"))
8542         resolve_attached = 1;
8543       else if (unformat (i, "multipath"))
8544         is_multipath = 1;
8545       else if (unformat (i, "count %d", &count))
8546         ;
8547       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8548         {
8549           next_hop_set = 1;
8550           next_hop_proto = DPO_PROTO_IP4;
8551         }
8552       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8553         {
8554           next_hop_set = 1;
8555           next_hop_proto = DPO_PROTO_IP6;
8556         }
8557       else
8558         if (unformat
8559             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8560              &sw_if_index))
8561         {
8562           next_hop_set = 1;
8563           next_hop_proto = DPO_PROTO_ETHERNET;
8564           is_interface_rx = 1;
8565         }
8566       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8567         {
8568           next_hop_set = 1;
8569           next_hop_proto = DPO_PROTO_ETHERNET;
8570           is_interface_rx = 1;
8571         }
8572       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8573         next_hop_set = 1;
8574       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8575         next_hop_set = 1;
8576       else if (unformat (i, "out-label %d", &next_hop_out_label))
8577         {
8578           vl_api_fib_mpls_label_t fib_label = {
8579             .label = ntohl (next_hop_out_label),
8580             .ttl = 64,
8581             .exp = 0,
8582           };
8583           vec_add1 (next_hop_out_label_stack, fib_label);
8584         }
8585       else
8586         {
8587           clib_warning ("parse error '%U'", format_unformat_error, i);
8588           return -99;
8589         }
8590     }
8591
8592   if (!next_hop_set && !is_classify)
8593     {
8594       errmsg ("next hop / classify not set");
8595       return -99;
8596     }
8597
8598   if (MPLS_LABEL_INVALID == local_label)
8599     {
8600       errmsg ("missing label");
8601       return -99;
8602     }
8603
8604   if (count > 1)
8605     {
8606       /* Turn on async mode */
8607       vam->async_mode = 1;
8608       vam->async_errors = 0;
8609       before = vat_time_now (vam);
8610     }
8611
8612   for (j = 0; j < count; j++)
8613     {
8614       /* Construct the API message */
8615       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8616           vec_len (next_hop_out_label_stack));
8617
8618       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8619       mp->mr_table_id = ntohl (table_id);
8620
8621       mp->mr_is_add = is_add;
8622       mp->mr_next_hop_proto = next_hop_proto;
8623       mp->mr_is_classify = is_classify;
8624       mp->mr_is_multipath = is_multipath;
8625       mp->mr_is_resolve_host = resolve_host;
8626       mp->mr_is_resolve_attached = resolve_attached;
8627       mp->mr_is_interface_rx = is_interface_rx;
8628       mp->mr_next_hop_weight = next_hop_weight;
8629       mp->mr_next_hop_preference = 0;
8630       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8631       mp->mr_classify_table_index = ntohl (classify_table_index);
8632       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8633       mp->mr_label = ntohl (local_label);
8634       mp->mr_eos = is_eos;
8635
8636       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8637       if (0 != mp->mr_next_hop_n_out_labels)
8638         {
8639           memcpy (mp->mr_next_hop_out_label_stack,
8640                   next_hop_out_label_stack,
8641                   vec_len (next_hop_out_label_stack) *
8642                   sizeof (vl_api_fib_mpls_label_t));
8643           vec_free (next_hop_out_label_stack);
8644         }
8645
8646       if (next_hop_set)
8647         {
8648           if (DPO_PROTO_IP4 == next_hop_proto)
8649             {
8650               clib_memcpy (mp->mr_next_hop,
8651                            &v4_next_hop_address,
8652                            sizeof (v4_next_hop_address));
8653             }
8654           else if (DPO_PROTO_IP6 == next_hop_proto)
8655
8656             {
8657               clib_memcpy (mp->mr_next_hop,
8658                            &v6_next_hop_address,
8659                            sizeof (v6_next_hop_address));
8660             }
8661         }
8662       local_label++;
8663
8664       /* send it... */
8665       S (mp);
8666       /* If we receive SIGTERM, stop now... */
8667       if (vam->do_exit)
8668         break;
8669     }
8670
8671   /* When testing multiple add/del ops, use a control-ping to sync */
8672   if (count > 1)
8673     {
8674       vl_api_control_ping_t *mp_ping;
8675       f64 after;
8676       f64 timeout;
8677
8678       /* Shut off async mode */
8679       vam->async_mode = 0;
8680
8681       MPING (CONTROL_PING, mp_ping);
8682       S (mp_ping);
8683
8684       timeout = vat_time_now (vam) + 1.0;
8685       while (vat_time_now (vam) < timeout)
8686         if (vam->result_ready == 1)
8687           goto out;
8688       vam->retval = -99;
8689
8690     out:
8691       if (vam->retval == -99)
8692         errmsg ("timeout");
8693
8694       if (vam->async_errors > 0)
8695         {
8696           errmsg ("%d asynchronous errors", vam->async_errors);
8697           vam->retval = -98;
8698         }
8699       vam->async_errors = 0;
8700       after = vat_time_now (vam);
8701
8702       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8703       if (j > 0)
8704         count = j;
8705
8706       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8707              count, after - before, count / (after - before));
8708     }
8709   else
8710     {
8711       int ret;
8712
8713       /* Wait for a reply... */
8714       W (ret);
8715       return ret;
8716     }
8717
8718   /* Return the good/bad news */
8719   return (vam->retval);
8720 }
8721
8722 static int
8723 api_mpls_ip_bind_unbind (vat_main_t * vam)
8724 {
8725   unformat_input_t *i = vam->input;
8726   vl_api_mpls_ip_bind_unbind_t *mp;
8727   u32 ip_table_id = 0;
8728   u8 is_bind = 1;
8729   u8 is_ip4 = 1;
8730   ip4_address_t v4_address;
8731   ip6_address_t v6_address;
8732   u32 address_length;
8733   u8 address_set = 0;
8734   mpls_label_t local_label = MPLS_LABEL_INVALID;
8735   int ret;
8736
8737   /* Parse args required to build the message */
8738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8739     {
8740       if (unformat (i, "%U/%d", unformat_ip4_address,
8741                     &v4_address, &address_length))
8742         {
8743           is_ip4 = 1;
8744           address_set = 1;
8745         }
8746       else if (unformat (i, "%U/%d", unformat_ip6_address,
8747                          &v6_address, &address_length))
8748         {
8749           is_ip4 = 0;
8750           address_set = 1;
8751         }
8752       else if (unformat (i, "%d", &local_label))
8753         ;
8754       else if (unformat (i, "table-id %d", &ip_table_id))
8755         ;
8756       else if (unformat (i, "unbind"))
8757         is_bind = 0;
8758       else if (unformat (i, "bind"))
8759         is_bind = 1;
8760       else
8761         {
8762           clib_warning ("parse error '%U'", format_unformat_error, i);
8763           return -99;
8764         }
8765     }
8766
8767   if (!address_set)
8768     {
8769       errmsg ("IP address not set");
8770       return -99;
8771     }
8772
8773   if (MPLS_LABEL_INVALID == local_label)
8774     {
8775       errmsg ("missing label");
8776       return -99;
8777     }
8778
8779   /* Construct the API message */
8780   M (MPLS_IP_BIND_UNBIND, mp);
8781
8782   mp->mb_is_bind = is_bind;
8783   mp->mb_is_ip4 = is_ip4;
8784   mp->mb_ip_table_id = ntohl (ip_table_id);
8785   mp->mb_mpls_table_id = 0;
8786   mp->mb_label = ntohl (local_label);
8787   mp->mb_address_length = address_length;
8788
8789   if (is_ip4)
8790     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8791   else
8792     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8793
8794   /* send it... */
8795   S (mp);
8796
8797   /* Wait for a reply... */
8798   W (ret);
8799   return ret;
8800 }
8801
8802 static int
8803 api_sr_mpls_policy_add (vat_main_t * vam)
8804 {
8805   unformat_input_t *i = vam->input;
8806   vl_api_sr_mpls_policy_add_t *mp;
8807   u32 bsid = 0;
8808   u32 weight = 1;
8809   u8 type = 0;
8810   u8 n_segments = 0;
8811   u32 sid;
8812   u32 *segments = NULL;
8813   int ret;
8814
8815   /* Parse args required to build the message */
8816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8817     {
8818       if (unformat (i, "bsid %d", &bsid))
8819         ;
8820       else if (unformat (i, "weight %d", &weight))
8821         ;
8822       else if (unformat (i, "spray"))
8823         type = 1;
8824       else if (unformat (i, "next %d", &sid))
8825         {
8826           n_segments += 1;
8827           vec_add1 (segments, htonl (sid));
8828         }
8829       else
8830         {
8831           clib_warning ("parse error '%U'", format_unformat_error, i);
8832           return -99;
8833         }
8834     }
8835
8836   if (bsid == 0)
8837     {
8838       errmsg ("bsid not set");
8839       return -99;
8840     }
8841
8842   if (n_segments == 0)
8843     {
8844       errmsg ("no sid in segment stack");
8845       return -99;
8846     }
8847
8848   /* Construct the API message */
8849   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8850
8851   mp->bsid = htonl (bsid);
8852   mp->weight = htonl (weight);
8853   mp->type = type;
8854   mp->n_segments = n_segments;
8855   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8856   vec_free (segments);
8857
8858   /* send it... */
8859   S (mp);
8860
8861   /* Wait for a reply... */
8862   W (ret);
8863   return ret;
8864 }
8865
8866 static int
8867 api_sr_mpls_policy_del (vat_main_t * vam)
8868 {
8869   unformat_input_t *i = vam->input;
8870   vl_api_sr_mpls_policy_del_t *mp;
8871   u32 bsid = 0;
8872   int ret;
8873
8874   /* Parse args required to build the message */
8875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8876     {
8877       if (unformat (i, "bsid %d", &bsid))
8878         ;
8879       else
8880         {
8881           clib_warning ("parse error '%U'", format_unformat_error, i);
8882           return -99;
8883         }
8884     }
8885
8886   if (bsid == 0)
8887     {
8888       errmsg ("bsid not set");
8889       return -99;
8890     }
8891
8892   /* Construct the API message */
8893   M (SR_MPLS_POLICY_DEL, mp);
8894
8895   mp->bsid = htonl (bsid);
8896
8897   /* send it... */
8898   S (mp);
8899
8900   /* Wait for a reply... */
8901   W (ret);
8902   return ret;
8903 }
8904
8905 static int
8906 api_bier_table_add_del (vat_main_t * vam)
8907 {
8908   unformat_input_t *i = vam->input;
8909   vl_api_bier_table_add_del_t *mp;
8910   u8 is_add = 1;
8911   u32 set = 0, sub_domain = 0, hdr_len = 3;
8912   mpls_label_t local_label = MPLS_LABEL_INVALID;
8913   int ret;
8914
8915   /* Parse args required to build the message */
8916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8917     {
8918       if (unformat (i, "sub-domain %d", &sub_domain))
8919         ;
8920       else if (unformat (i, "set %d", &set))
8921         ;
8922       else if (unformat (i, "label %d", &local_label))
8923         ;
8924       else if (unformat (i, "hdr-len %d", &hdr_len))
8925         ;
8926       else if (unformat (i, "add"))
8927         is_add = 1;
8928       else if (unformat (i, "del"))
8929         is_add = 0;
8930       else
8931         {
8932           clib_warning ("parse error '%U'", format_unformat_error, i);
8933           return -99;
8934         }
8935     }
8936
8937   if (MPLS_LABEL_INVALID == local_label)
8938     {
8939       errmsg ("missing label\n");
8940       return -99;
8941     }
8942
8943   /* Construct the API message */
8944   M (BIER_TABLE_ADD_DEL, mp);
8945
8946   mp->bt_is_add = is_add;
8947   mp->bt_label = ntohl (local_label);
8948   mp->bt_tbl_id.bt_set = set;
8949   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8950   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8951
8952   /* send it... */
8953   S (mp);
8954
8955   /* Wait for a reply... */
8956   W (ret);
8957
8958   return (ret);
8959 }
8960
8961 static int
8962 api_bier_route_add_del (vat_main_t * vam)
8963 {
8964   unformat_input_t *i = vam->input;
8965   vl_api_bier_route_add_del_t *mp;
8966   u8 is_add = 1;
8967   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8968   ip4_address_t v4_next_hop_address;
8969   ip6_address_t v6_next_hop_address;
8970   u8 next_hop_set = 0;
8971   u8 next_hop_proto_is_ip4 = 1;
8972   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8973   int ret;
8974
8975   /* Parse args required to build the message */
8976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8977     {
8978       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8979         {
8980           next_hop_proto_is_ip4 = 1;
8981           next_hop_set = 1;
8982         }
8983       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8984         {
8985           next_hop_proto_is_ip4 = 0;
8986           next_hop_set = 1;
8987         }
8988       if (unformat (i, "sub-domain %d", &sub_domain))
8989         ;
8990       else if (unformat (i, "set %d", &set))
8991         ;
8992       else if (unformat (i, "hdr-len %d", &hdr_len))
8993         ;
8994       else if (unformat (i, "bp %d", &bp))
8995         ;
8996       else if (unformat (i, "add"))
8997         is_add = 1;
8998       else if (unformat (i, "del"))
8999         is_add = 0;
9000       else if (unformat (i, "out-label %d", &next_hop_out_label))
9001         ;
9002       else
9003         {
9004           clib_warning ("parse error '%U'", format_unformat_error, i);
9005           return -99;
9006         }
9007     }
9008
9009   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9010     {
9011       errmsg ("next hop / label set\n");
9012       return -99;
9013     }
9014   if (0 == bp)
9015     {
9016       errmsg ("bit=position not set\n");
9017       return -99;
9018     }
9019
9020   /* Construct the API message */
9021   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9022
9023   mp->br_is_add = is_add;
9024   mp->br_tbl_id.bt_set = set;
9025   mp->br_tbl_id.bt_sub_domain = sub_domain;
9026   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9027   mp->br_bp = ntohs (bp);
9028   mp->br_n_paths = 1;
9029   mp->br_paths[0].n_labels = 1;
9030   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9031   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9032
9033   if (next_hop_proto_is_ip4)
9034     {
9035       clib_memcpy (mp->br_paths[0].next_hop,
9036                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9037     }
9038   else
9039     {
9040       clib_memcpy (mp->br_paths[0].next_hop,
9041                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9042     }
9043
9044   /* send it... */
9045   S (mp);
9046
9047   /* Wait for a reply... */
9048   W (ret);
9049
9050   return (ret);
9051 }
9052
9053 static int
9054 api_proxy_arp_add_del (vat_main_t * vam)
9055 {
9056   unformat_input_t *i = vam->input;
9057   vl_api_proxy_arp_add_del_t *mp;
9058   u32 vrf_id = 0;
9059   u8 is_add = 1;
9060   vl_api_ip4_address_t lo, hi;
9061   u8 range_set = 0;
9062   int ret;
9063
9064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9065     {
9066       if (unformat (i, "vrf %d", &vrf_id))
9067         ;
9068       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9069                          unformat_vl_api_ip4_address, &hi))
9070         range_set = 1;
9071       else if (unformat (i, "del"))
9072         is_add = 0;
9073       else
9074         {
9075           clib_warning ("parse error '%U'", format_unformat_error, i);
9076           return -99;
9077         }
9078     }
9079
9080   if (range_set == 0)
9081     {
9082       errmsg ("address range not set");
9083       return -99;
9084     }
9085
9086   M (PROXY_ARP_ADD_DEL, mp);
9087
9088   mp->proxy.table_id = ntohl (vrf_id);
9089   mp->is_add = is_add;
9090   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9091   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9092
9093   S (mp);
9094   W (ret);
9095   return ret;
9096 }
9097
9098 static int
9099 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9100 {
9101   unformat_input_t *i = vam->input;
9102   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9103   u32 sw_if_index;
9104   u8 enable = 1;
9105   u8 sw_if_index_set = 0;
9106   int ret;
9107
9108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9109     {
9110       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9111         sw_if_index_set = 1;
9112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9113         sw_if_index_set = 1;
9114       else if (unformat (i, "enable"))
9115         enable = 1;
9116       else if (unformat (i, "disable"))
9117         enable = 0;
9118       else
9119         {
9120           clib_warning ("parse error '%U'", format_unformat_error, i);
9121           return -99;
9122         }
9123     }
9124
9125   if (sw_if_index_set == 0)
9126     {
9127       errmsg ("missing interface name or sw_if_index");
9128       return -99;
9129     }
9130
9131   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9132
9133   mp->sw_if_index = ntohl (sw_if_index);
9134   mp->enable_disable = enable;
9135
9136   S (mp);
9137   W (ret);
9138   return ret;
9139 }
9140
9141 static int
9142 api_mpls_tunnel_add_del (vat_main_t * vam)
9143 {
9144   unformat_input_t *i = vam->input;
9145   vl_api_mpls_tunnel_add_del_t *mp;
9146
9147   u8 is_add = 1;
9148   u8 l2_only = 0;
9149   u32 sw_if_index = ~0;
9150   u32 next_hop_sw_if_index = ~0;
9151   u32 next_hop_proto_is_ip4 = 1;
9152
9153   u32 next_hop_table_id = 0;
9154   ip4_address_t v4_next_hop_address = {
9155     .as_u32 = 0,
9156   };
9157   ip6_address_t v6_next_hop_address = { {0} };
9158   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9159   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9160   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9161   int ret;
9162
9163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9164     {
9165       if (unformat (i, "add"))
9166         is_add = 1;
9167       else
9168         if (unformat
9169             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9170         is_add = 0;
9171       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9172         is_add = 0;
9173       else if (unformat (i, "via %U",
9174                          unformat_ip4_address, &v4_next_hop_address))
9175         {
9176           next_hop_proto_is_ip4 = 1;
9177         }
9178       else if (unformat (i, "via %U",
9179                          unformat_ip6_address, &v6_next_hop_address))
9180         {
9181           next_hop_proto_is_ip4 = 0;
9182         }
9183       else if (unformat (i, "via-label %d", &next_hop_via_label))
9184         ;
9185       else
9186         if (unformat
9187             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9188         ;
9189       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9190         ;
9191       else if (unformat (i, "l2-only"))
9192         l2_only = 1;
9193       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9194         ;
9195       else if (unformat (i, "out-label %d", &next_hop_out_label))
9196         {
9197           vl_api_fib_mpls_label_t fib_label = {
9198             .label = ntohl (next_hop_out_label),
9199             .ttl = 64,
9200             .exp = 0,
9201           };
9202           vec_add1 (next_hop_out_label_stack, fib_label);
9203         }
9204       else
9205         {
9206           clib_warning ("parse error '%U'", format_unformat_error, i);
9207           return -99;
9208         }
9209     }
9210
9211   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9212       vec_len (next_hop_out_label_stack));
9213
9214   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9215   mp->mt_sw_if_index = ntohl (sw_if_index);
9216   mp->mt_is_add = is_add;
9217   mp->mt_l2_only = l2_only;
9218   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9219   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9220   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9221   mp->mt_next_hop_weight = 1;
9222   mp->mt_next_hop_preference = 0;
9223
9224   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9225
9226   if (0 != mp->mt_next_hop_n_out_labels)
9227     {
9228       clib_memcpy (mp->mt_next_hop_out_label_stack,
9229                    next_hop_out_label_stack,
9230                    (vec_len (next_hop_out_label_stack) *
9231                     sizeof (vl_api_fib_mpls_label_t)));
9232       vec_free (next_hop_out_label_stack);
9233     }
9234
9235   if (next_hop_proto_is_ip4)
9236     {
9237       clib_memcpy (mp->mt_next_hop,
9238                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9239     }
9240   else
9241     {
9242       clib_memcpy (mp->mt_next_hop,
9243                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9244     }
9245
9246   S (mp);
9247   W (ret);
9248   return ret;
9249 }
9250
9251 static int
9252 api_sw_interface_set_unnumbered (vat_main_t * vam)
9253 {
9254   unformat_input_t *i = vam->input;
9255   vl_api_sw_interface_set_unnumbered_t *mp;
9256   u32 sw_if_index;
9257   u32 unnum_sw_index = ~0;
9258   u8 is_add = 1;
9259   u8 sw_if_index_set = 0;
9260   int ret;
9261
9262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9263     {
9264       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9265         sw_if_index_set = 1;
9266       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9267         sw_if_index_set = 1;
9268       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9269         ;
9270       else if (unformat (i, "del"))
9271         is_add = 0;
9272       else
9273         {
9274           clib_warning ("parse error '%U'", format_unformat_error, i);
9275           return -99;
9276         }
9277     }
9278
9279   if (sw_if_index_set == 0)
9280     {
9281       errmsg ("missing interface name or sw_if_index");
9282       return -99;
9283     }
9284
9285   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9286
9287   mp->sw_if_index = ntohl (sw_if_index);
9288   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9289   mp->is_add = is_add;
9290
9291   S (mp);
9292   W (ret);
9293   return ret;
9294 }
9295
9296 static int
9297 api_ip_neighbor_add_del (vat_main_t * vam)
9298 {
9299   vl_api_mac_address_t mac_address;
9300   unformat_input_t *i = vam->input;
9301   vl_api_ip_neighbor_add_del_t *mp;
9302   vl_api_address_t ip_address;
9303   u32 sw_if_index;
9304   u8 sw_if_index_set = 0;
9305   u8 is_add = 1;
9306   u8 mac_set = 0;
9307   u8 address_set = 0;
9308   int ret;
9309   ip_neighbor_flags_t flags;
9310
9311   flags = IP_NEIGHBOR_FLAG_NONE;
9312   clib_memset (&ip_address, 0, sizeof (ip_address));
9313   clib_memset (&mac_address, 0, sizeof (mac_address));
9314   /* Parse args required to build the message */
9315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9316     {
9317       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9318         {
9319           mac_set = 1;
9320         }
9321       else if (unformat (i, "del"))
9322         is_add = 0;
9323       else
9324         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9325         sw_if_index_set = 1;
9326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "static"))
9329         flags |= IP_NEIGHBOR_FLAG_STATIC;
9330       else if (unformat (i, "no-fib-entry"))
9331         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9332       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9333         address_set = 1;
9334       else
9335         {
9336           clib_warning ("parse error '%U'", format_unformat_error, i);
9337           return -99;
9338         }
9339     }
9340
9341   if (sw_if_index_set == 0)
9342     {
9343       errmsg ("missing interface name or sw_if_index");
9344       return -99;
9345     }
9346   if (!address_set)
9347     {
9348       errmsg ("no address set");
9349       return -99;
9350     }
9351
9352   /* Construct the API message */
9353   M (IP_NEIGHBOR_ADD_DEL, mp);
9354
9355   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9356   mp->is_add = is_add;
9357   mp->neighbor.flags = htonl (flags);
9358   if (mac_set)
9359     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9360                  sizeof (mac_address));
9361   if (address_set)
9362     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9363
9364   /* send it... */
9365   S (mp);
9366
9367   /* Wait for a reply, return good/bad news  */
9368   W (ret);
9369   return ret;
9370 }
9371
9372 static int
9373 api_create_vlan_subif (vat_main_t * vam)
9374 {
9375   unformat_input_t *i = vam->input;
9376   vl_api_create_vlan_subif_t *mp;
9377   u32 sw_if_index;
9378   u8 sw_if_index_set = 0;
9379   u32 vlan_id;
9380   u8 vlan_id_set = 0;
9381   int ret;
9382
9383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9384     {
9385       if (unformat (i, "sw_if_index %d", &sw_if_index))
9386         sw_if_index_set = 1;
9387       else
9388         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9389         sw_if_index_set = 1;
9390       else if (unformat (i, "vlan %d", &vlan_id))
9391         vlan_id_set = 1;
9392       else
9393         {
9394           clib_warning ("parse error '%U'", format_unformat_error, i);
9395           return -99;
9396         }
9397     }
9398
9399   if (sw_if_index_set == 0)
9400     {
9401       errmsg ("missing interface name or sw_if_index");
9402       return -99;
9403     }
9404
9405   if (vlan_id_set == 0)
9406     {
9407       errmsg ("missing vlan_id");
9408       return -99;
9409     }
9410   M (CREATE_VLAN_SUBIF, mp);
9411
9412   mp->sw_if_index = ntohl (sw_if_index);
9413   mp->vlan_id = ntohl (vlan_id);
9414
9415   S (mp);
9416   W (ret);
9417   return ret;
9418 }
9419
9420 #define foreach_create_subif_bit                \
9421 _(no_tags)                                      \
9422 _(one_tag)                                      \
9423 _(two_tags)                                     \
9424 _(dot1ad)                                       \
9425 _(exact_match)                                  \
9426 _(default_sub)                                  \
9427 _(outer_vlan_id_any)                            \
9428 _(inner_vlan_id_any)
9429
9430 #define foreach_create_subif_flag               \
9431 _(0, "no_tags")                                 \
9432 _(1, "one_tag")                                 \
9433 _(2, "two_tags")                                \
9434 _(3, "dot1ad")                                  \
9435 _(4, "exact_match")                             \
9436 _(5, "default_sub")                             \
9437 _(6, "outer_vlan_id_any")                       \
9438 _(7, "inner_vlan_id_any")
9439
9440 static int
9441 api_create_subif (vat_main_t * vam)
9442 {
9443   unformat_input_t *i = vam->input;
9444   vl_api_create_subif_t *mp;
9445   u32 sw_if_index;
9446   u8 sw_if_index_set = 0;
9447   u32 sub_id;
9448   u8 sub_id_set = 0;
9449   u32 no_tags = 0;
9450   u32 one_tag = 0;
9451   u32 two_tags = 0;
9452   u32 dot1ad = 0;
9453   u32 exact_match = 0;
9454   u32 default_sub = 0;
9455   u32 outer_vlan_id_any = 0;
9456   u32 inner_vlan_id_any = 0;
9457   u32 tmp;
9458   u16 outer_vlan_id = 0;
9459   u16 inner_vlan_id = 0;
9460   int ret;
9461
9462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9463     {
9464       if (unformat (i, "sw_if_index %d", &sw_if_index))
9465         sw_if_index_set = 1;
9466       else
9467         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9468         sw_if_index_set = 1;
9469       else if (unformat (i, "sub_id %d", &sub_id))
9470         sub_id_set = 1;
9471       else if (unformat (i, "outer_vlan_id %d", &tmp))
9472         outer_vlan_id = tmp;
9473       else if (unformat (i, "inner_vlan_id %d", &tmp))
9474         inner_vlan_id = tmp;
9475
9476 #define _(a) else if (unformat (i, #a)) a = 1 ;
9477       foreach_create_subif_bit
9478 #undef _
9479         else
9480         {
9481           clib_warning ("parse error '%U'", format_unformat_error, i);
9482           return -99;
9483         }
9484     }
9485
9486   if (sw_if_index_set == 0)
9487     {
9488       errmsg ("missing interface name or sw_if_index");
9489       return -99;
9490     }
9491
9492   if (sub_id_set == 0)
9493     {
9494       errmsg ("missing sub_id");
9495       return -99;
9496     }
9497   M (CREATE_SUBIF, mp);
9498
9499   mp->sw_if_index = ntohl (sw_if_index);
9500   mp->sub_id = ntohl (sub_id);
9501
9502 #define _(a,b) mp->sub_if_flags |= (1 << a);
9503   foreach_create_subif_flag;
9504 #undef _
9505
9506   mp->outer_vlan_id = ntohs (outer_vlan_id);
9507   mp->inner_vlan_id = ntohs (inner_vlan_id);
9508
9509   S (mp);
9510   W (ret);
9511   return ret;
9512 }
9513
9514 static int
9515 api_oam_add_del (vat_main_t * vam)
9516 {
9517   unformat_input_t *i = vam->input;
9518   vl_api_oam_add_del_t *mp;
9519   u32 vrf_id = 0;
9520   u8 is_add = 1;
9521   ip4_address_t src, dst;
9522   u8 src_set = 0;
9523   u8 dst_set = 0;
9524   int ret;
9525
9526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9527     {
9528       if (unformat (i, "vrf %d", &vrf_id))
9529         ;
9530       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9531         src_set = 1;
9532       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9533         dst_set = 1;
9534       else if (unformat (i, "del"))
9535         is_add = 0;
9536       else
9537         {
9538           clib_warning ("parse error '%U'", format_unformat_error, i);
9539           return -99;
9540         }
9541     }
9542
9543   if (src_set == 0)
9544     {
9545       errmsg ("missing src addr");
9546       return -99;
9547     }
9548
9549   if (dst_set == 0)
9550     {
9551       errmsg ("missing dst addr");
9552       return -99;
9553     }
9554
9555   M (OAM_ADD_DEL, mp);
9556
9557   mp->vrf_id = ntohl (vrf_id);
9558   mp->is_add = is_add;
9559   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9560   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9561
9562   S (mp);
9563   W (ret);
9564   return ret;
9565 }
9566
9567 static int
9568 api_reset_fib (vat_main_t * vam)
9569 {
9570   unformat_input_t *i = vam->input;
9571   vl_api_reset_fib_t *mp;
9572   u32 vrf_id = 0;
9573   u8 is_ipv6 = 0;
9574   u8 vrf_id_set = 0;
9575
9576   int ret;
9577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9578     {
9579       if (unformat (i, "vrf %d", &vrf_id))
9580         vrf_id_set = 1;
9581       else if (unformat (i, "ipv6"))
9582         is_ipv6 = 1;
9583       else
9584         {
9585           clib_warning ("parse error '%U'", format_unformat_error, i);
9586           return -99;
9587         }
9588     }
9589
9590   if (vrf_id_set == 0)
9591     {
9592       errmsg ("missing vrf id");
9593       return -99;
9594     }
9595
9596   M (RESET_FIB, mp);
9597
9598   mp->vrf_id = ntohl (vrf_id);
9599   mp->is_ipv6 = is_ipv6;
9600
9601   S (mp);
9602   W (ret);
9603   return ret;
9604 }
9605
9606 static int
9607 api_dhcp_proxy_config (vat_main_t * vam)
9608 {
9609   unformat_input_t *i = vam->input;
9610   vl_api_dhcp_proxy_config_t *mp;
9611   u32 rx_vrf_id = 0;
9612   u32 server_vrf_id = 0;
9613   u8 is_add = 1;
9614   u8 v4_address_set = 0;
9615   u8 v6_address_set = 0;
9616   ip4_address_t v4address;
9617   ip6_address_t v6address;
9618   u8 v4_src_address_set = 0;
9619   u8 v6_src_address_set = 0;
9620   ip4_address_t v4srcaddress;
9621   ip6_address_t v6srcaddress;
9622   int ret;
9623
9624   /* Parse args required to build the message */
9625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9626     {
9627       if (unformat (i, "del"))
9628         is_add = 0;
9629       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9630         ;
9631       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9632         ;
9633       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9634         v4_address_set = 1;
9635       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9636         v6_address_set = 1;
9637       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9638         v4_src_address_set = 1;
9639       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9640         v6_src_address_set = 1;
9641       else
9642         break;
9643     }
9644
9645   if (v4_address_set && v6_address_set)
9646     {
9647       errmsg ("both v4 and v6 server addresses set");
9648       return -99;
9649     }
9650   if (!v4_address_set && !v6_address_set)
9651     {
9652       errmsg ("no server addresses set");
9653       return -99;
9654     }
9655
9656   if (v4_src_address_set && v6_src_address_set)
9657     {
9658       errmsg ("both v4 and v6  src addresses set");
9659       return -99;
9660     }
9661   if (!v4_src_address_set && !v6_src_address_set)
9662     {
9663       errmsg ("no src addresses set");
9664       return -99;
9665     }
9666
9667   if (!(v4_src_address_set && v4_address_set) &&
9668       !(v6_src_address_set && v6_address_set))
9669     {
9670       errmsg ("no matching server and src addresses set");
9671       return -99;
9672     }
9673
9674   /* Construct the API message */
9675   M (DHCP_PROXY_CONFIG, mp);
9676
9677   mp->is_add = is_add;
9678   mp->rx_vrf_id = ntohl (rx_vrf_id);
9679   mp->server_vrf_id = ntohl (server_vrf_id);
9680   if (v6_address_set)
9681     {
9682       mp->is_ipv6 = 1;
9683       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9684       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9685     }
9686   else
9687     {
9688       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9689       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9690     }
9691
9692   /* send it... */
9693   S (mp);
9694
9695   /* Wait for a reply, return good/bad news  */
9696   W (ret);
9697   return ret;
9698 }
9699
9700 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9701 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9702
9703 static void
9704 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9705 {
9706   vat_main_t *vam = &vat_main;
9707   u32 i, count = mp->count;
9708   vl_api_dhcp_server_t *s;
9709
9710   if (mp->is_ipv6)
9711     print (vam->ofp,
9712            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9713            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9714            ntohl (mp->rx_vrf_id),
9715            format_ip6_address, mp->dhcp_src_address,
9716            mp->vss_type, mp->vss_vpn_ascii_id,
9717            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9718   else
9719     print (vam->ofp,
9720            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9721            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9722            ntohl (mp->rx_vrf_id),
9723            format_ip4_address, mp->dhcp_src_address,
9724            mp->vss_type, mp->vss_vpn_ascii_id,
9725            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9726
9727   for (i = 0; i < count; i++)
9728     {
9729       s = &mp->servers[i];
9730
9731       if (mp->is_ipv6)
9732         print (vam->ofp,
9733                " Server Table-ID %d, Server Address %U",
9734                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9735       else
9736         print (vam->ofp,
9737                " Server Table-ID %d, Server Address %U",
9738                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9739     }
9740 }
9741
9742 static void vl_api_dhcp_proxy_details_t_handler_json
9743   (vl_api_dhcp_proxy_details_t * mp)
9744 {
9745   vat_main_t *vam = &vat_main;
9746   vat_json_node_t *node = NULL;
9747   u32 i, count = mp->count;
9748   struct in_addr ip4;
9749   struct in6_addr ip6;
9750   vl_api_dhcp_server_t *s;
9751
9752   if (VAT_JSON_ARRAY != vam->json_tree.type)
9753     {
9754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9755       vat_json_init_array (&vam->json_tree);
9756     }
9757   node = vat_json_array_add (&vam->json_tree);
9758
9759   vat_json_init_object (node);
9760   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9761   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9762                              sizeof (mp->vss_type));
9763   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9764                                    mp->vss_vpn_ascii_id);
9765   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9766   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9767
9768   if (mp->is_ipv6)
9769     {
9770       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9771       vat_json_object_add_ip6 (node, "src_address", ip6);
9772     }
9773   else
9774     {
9775       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9776       vat_json_object_add_ip4 (node, "src_address", ip4);
9777     }
9778
9779   for (i = 0; i < count; i++)
9780     {
9781       s = &mp->servers[i];
9782
9783       vat_json_object_add_uint (node, "server-table-id",
9784                                 ntohl (s->server_vrf_id));
9785
9786       if (mp->is_ipv6)
9787         {
9788           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9789           vat_json_object_add_ip4 (node, "src_address", ip4);
9790         }
9791       else
9792         {
9793           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9794           vat_json_object_add_ip6 (node, "server_address", ip6);
9795         }
9796     }
9797 }
9798
9799 static int
9800 api_dhcp_proxy_dump (vat_main_t * vam)
9801 {
9802   unformat_input_t *i = vam->input;
9803   vl_api_control_ping_t *mp_ping;
9804   vl_api_dhcp_proxy_dump_t *mp;
9805   u8 is_ipv6 = 0;
9806   int ret;
9807
9808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9809     {
9810       if (unformat (i, "ipv6"))
9811         is_ipv6 = 1;
9812       else
9813         {
9814           clib_warning ("parse error '%U'", format_unformat_error, i);
9815           return -99;
9816         }
9817     }
9818
9819   M (DHCP_PROXY_DUMP, mp);
9820
9821   mp->is_ip6 = is_ipv6;
9822   S (mp);
9823
9824   /* Use a control ping for synchronization */
9825   MPING (CONTROL_PING, mp_ping);
9826   S (mp_ping);
9827
9828   W (ret);
9829   return ret;
9830 }
9831
9832 static int
9833 api_dhcp_proxy_set_vss (vat_main_t * vam)
9834 {
9835   unformat_input_t *i = vam->input;
9836   vl_api_dhcp_proxy_set_vss_t *mp;
9837   u8 is_ipv6 = 0;
9838   u8 is_add = 1;
9839   u32 tbl_id = ~0;
9840   u8 vss_type = VSS_TYPE_DEFAULT;
9841   u8 *vpn_ascii_id = 0;
9842   u32 oui = 0;
9843   u32 fib_id = 0;
9844   int ret;
9845
9846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9847     {
9848       if (unformat (i, "tbl_id %d", &tbl_id))
9849         ;
9850       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9851         vss_type = VSS_TYPE_ASCII;
9852       else if (unformat (i, "fib_id %d", &fib_id))
9853         vss_type = VSS_TYPE_VPN_ID;
9854       else if (unformat (i, "oui %d", &oui))
9855         vss_type = VSS_TYPE_VPN_ID;
9856       else if (unformat (i, "ipv6"))
9857         is_ipv6 = 1;
9858       else if (unformat (i, "del"))
9859         is_add = 0;
9860       else
9861         break;
9862     }
9863
9864   if (tbl_id == ~0)
9865     {
9866       errmsg ("missing tbl_id ");
9867       vec_free (vpn_ascii_id);
9868       return -99;
9869     }
9870
9871   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9872     {
9873       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9874       vec_free (vpn_ascii_id);
9875       return -99;
9876     }
9877
9878   M (DHCP_PROXY_SET_VSS, mp);
9879   mp->tbl_id = ntohl (tbl_id);
9880   mp->vss_type = vss_type;
9881   if (vpn_ascii_id)
9882     {
9883       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9884       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9885     }
9886   mp->vpn_index = ntohl (fib_id);
9887   mp->oui = ntohl (oui);
9888   mp->is_ipv6 = is_ipv6;
9889   mp->is_add = is_add;
9890
9891   S (mp);
9892   W (ret);
9893
9894   vec_free (vpn_ascii_id);
9895   return ret;
9896 }
9897
9898 static int
9899 api_dhcp_client_config (vat_main_t * vam)
9900 {
9901   unformat_input_t *i = vam->input;
9902   vl_api_dhcp_client_config_t *mp;
9903   u32 sw_if_index;
9904   u8 sw_if_index_set = 0;
9905   u8 is_add = 1;
9906   u8 *hostname = 0;
9907   u8 disable_event = 0;
9908   int ret;
9909
9910   /* Parse args required to build the message */
9911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (i, "del"))
9914         is_add = 0;
9915       else
9916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9919         sw_if_index_set = 1;
9920       else if (unformat (i, "hostname %s", &hostname))
9921         ;
9922       else if (unformat (i, "disable_event"))
9923         disable_event = 1;
9924       else
9925         break;
9926     }
9927
9928   if (sw_if_index_set == 0)
9929     {
9930       errmsg ("missing interface name or sw_if_index");
9931       return -99;
9932     }
9933
9934   if (vec_len (hostname) > 63)
9935     {
9936       errmsg ("hostname too long");
9937     }
9938   vec_add1 (hostname, 0);
9939
9940   /* Construct the API message */
9941   M (DHCP_CLIENT_CONFIG, mp);
9942
9943   mp->is_add = is_add;
9944   mp->client.sw_if_index = htonl (sw_if_index);
9945   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9946   vec_free (hostname);
9947   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9948   mp->client.pid = htonl (getpid ());
9949
9950   /* send it... */
9951   S (mp);
9952
9953   /* Wait for a reply, return good/bad news  */
9954   W (ret);
9955   return ret;
9956 }
9957
9958 static int
9959 api_set_ip_flow_hash (vat_main_t * vam)
9960 {
9961   unformat_input_t *i = vam->input;
9962   vl_api_set_ip_flow_hash_t *mp;
9963   u32 vrf_id = 0;
9964   u8 is_ipv6 = 0;
9965   u8 vrf_id_set = 0;
9966   u8 src = 0;
9967   u8 dst = 0;
9968   u8 sport = 0;
9969   u8 dport = 0;
9970   u8 proto = 0;
9971   u8 reverse = 0;
9972   int ret;
9973
9974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9975     {
9976       if (unformat (i, "vrf %d", &vrf_id))
9977         vrf_id_set = 1;
9978       else if (unformat (i, "ipv6"))
9979         is_ipv6 = 1;
9980       else if (unformat (i, "src"))
9981         src = 1;
9982       else if (unformat (i, "dst"))
9983         dst = 1;
9984       else if (unformat (i, "sport"))
9985         sport = 1;
9986       else if (unformat (i, "dport"))
9987         dport = 1;
9988       else if (unformat (i, "proto"))
9989         proto = 1;
9990       else if (unformat (i, "reverse"))
9991         reverse = 1;
9992
9993       else
9994         {
9995           clib_warning ("parse error '%U'", format_unformat_error, i);
9996           return -99;
9997         }
9998     }
9999
10000   if (vrf_id_set == 0)
10001     {
10002       errmsg ("missing vrf id");
10003       return -99;
10004     }
10005
10006   M (SET_IP_FLOW_HASH, mp);
10007   mp->src = src;
10008   mp->dst = dst;
10009   mp->sport = sport;
10010   mp->dport = dport;
10011   mp->proto = proto;
10012   mp->reverse = reverse;
10013   mp->vrf_id = ntohl (vrf_id);
10014   mp->is_ipv6 = is_ipv6;
10015
10016   S (mp);
10017   W (ret);
10018   return ret;
10019 }
10020
10021 static int
10022 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10023 {
10024   unformat_input_t *i = vam->input;
10025   vl_api_sw_interface_ip6_enable_disable_t *mp;
10026   u32 sw_if_index;
10027   u8 sw_if_index_set = 0;
10028   u8 enable = 0;
10029   int ret;
10030
10031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10032     {
10033       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10034         sw_if_index_set = 1;
10035       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10036         sw_if_index_set = 1;
10037       else if (unformat (i, "enable"))
10038         enable = 1;
10039       else if (unformat (i, "disable"))
10040         enable = 0;
10041       else
10042         {
10043           clib_warning ("parse error '%U'", format_unformat_error, i);
10044           return -99;
10045         }
10046     }
10047
10048   if (sw_if_index_set == 0)
10049     {
10050       errmsg ("missing interface name or sw_if_index");
10051       return -99;
10052     }
10053
10054   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10055
10056   mp->sw_if_index = ntohl (sw_if_index);
10057   mp->enable = enable;
10058
10059   S (mp);
10060   W (ret);
10061   return ret;
10062 }
10063
10064 static int
10065 api_ip6nd_proxy_add_del (vat_main_t * vam)
10066 {
10067   unformat_input_t *i = vam->input;
10068   vl_api_ip6nd_proxy_add_del_t *mp;
10069   u32 sw_if_index = ~0;
10070   u8 v6_address_set = 0;
10071   vl_api_ip6_address_t v6address;
10072   u8 is_del = 0;
10073   int ret;
10074
10075   /* Parse args required to build the message */
10076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10077     {
10078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10079         ;
10080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10081         ;
10082       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10083         v6_address_set = 1;
10084       if (unformat (i, "del"))
10085         is_del = 1;
10086       else
10087         {
10088           clib_warning ("parse error '%U'", format_unformat_error, i);
10089           return -99;
10090         }
10091     }
10092
10093   if (sw_if_index == ~0)
10094     {
10095       errmsg ("missing interface name or sw_if_index");
10096       return -99;
10097     }
10098   if (!v6_address_set)
10099     {
10100       errmsg ("no address set");
10101       return -99;
10102     }
10103
10104   /* Construct the API message */
10105   M (IP6ND_PROXY_ADD_DEL, mp);
10106
10107   mp->is_del = is_del;
10108   mp->sw_if_index = ntohl (sw_if_index);
10109   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10110
10111   /* send it... */
10112   S (mp);
10113
10114   /* Wait for a reply, return good/bad news  */
10115   W (ret);
10116   return ret;
10117 }
10118
10119 static int
10120 api_ip6nd_proxy_dump (vat_main_t * vam)
10121 {
10122   vl_api_ip6nd_proxy_dump_t *mp;
10123   vl_api_control_ping_t *mp_ping;
10124   int ret;
10125
10126   M (IP6ND_PROXY_DUMP, mp);
10127
10128   S (mp);
10129
10130   /* Use a control ping for synchronization */
10131   MPING (CONTROL_PING, mp_ping);
10132   S (mp_ping);
10133
10134   W (ret);
10135   return ret;
10136 }
10137
10138 static void vl_api_ip6nd_proxy_details_t_handler
10139   (vl_api_ip6nd_proxy_details_t * mp)
10140 {
10141   vat_main_t *vam = &vat_main;
10142
10143   print (vam->ofp, "host %U sw_if_index %d",
10144          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10145 }
10146
10147 static void vl_api_ip6nd_proxy_details_t_handler_json
10148   (vl_api_ip6nd_proxy_details_t * mp)
10149 {
10150   vat_main_t *vam = &vat_main;
10151   struct in6_addr ip6;
10152   vat_json_node_t *node = NULL;
10153
10154   if (VAT_JSON_ARRAY != vam->json_tree.type)
10155     {
10156       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10157       vat_json_init_array (&vam->json_tree);
10158     }
10159   node = vat_json_array_add (&vam->json_tree);
10160
10161   vat_json_init_object (node);
10162   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10163
10164   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10165   vat_json_object_add_ip6 (node, "host", ip6);
10166 }
10167
10168 static int
10169 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10170 {
10171   unformat_input_t *i = vam->input;
10172   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10173   u32 sw_if_index;
10174   u8 sw_if_index_set = 0;
10175   u32 address_length = 0;
10176   u8 v6_address_set = 0;
10177   vl_api_prefix_t pfx;
10178   u8 use_default = 0;
10179   u8 no_advertise = 0;
10180   u8 off_link = 0;
10181   u8 no_autoconfig = 0;
10182   u8 no_onlink = 0;
10183   u8 is_no = 0;
10184   u32 val_lifetime = 0;
10185   u32 pref_lifetime = 0;
10186   int ret;
10187
10188   /* Parse args required to build the message */
10189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10190     {
10191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10192         sw_if_index_set = 1;
10193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10194         sw_if_index_set = 1;
10195       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10196         v6_address_set = 1;
10197       else if (unformat (i, "val_life %d", &val_lifetime))
10198         ;
10199       else if (unformat (i, "pref_life %d", &pref_lifetime))
10200         ;
10201       else if (unformat (i, "def"))
10202         use_default = 1;
10203       else if (unformat (i, "noadv"))
10204         no_advertise = 1;
10205       else if (unformat (i, "offl"))
10206         off_link = 1;
10207       else if (unformat (i, "noauto"))
10208         no_autoconfig = 1;
10209       else if (unformat (i, "nolink"))
10210         no_onlink = 1;
10211       else if (unformat (i, "isno"))
10212         is_no = 1;
10213       else
10214         {
10215           clib_warning ("parse error '%U'", format_unformat_error, i);
10216           return -99;
10217         }
10218     }
10219
10220   if (sw_if_index_set == 0)
10221     {
10222       errmsg ("missing interface name or sw_if_index");
10223       return -99;
10224     }
10225   if (!v6_address_set)
10226     {
10227       errmsg ("no address set");
10228       return -99;
10229     }
10230
10231   /* Construct the API message */
10232   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10233
10234   mp->sw_if_index = ntohl (sw_if_index);
10235   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10236   mp->use_default = use_default;
10237   mp->no_advertise = no_advertise;
10238   mp->off_link = off_link;
10239   mp->no_autoconfig = no_autoconfig;
10240   mp->no_onlink = no_onlink;
10241   mp->is_no = is_no;
10242   mp->val_lifetime = ntohl (val_lifetime);
10243   mp->pref_lifetime = ntohl (pref_lifetime);
10244
10245   /* send it... */
10246   S (mp);
10247
10248   /* Wait for a reply, return good/bad news  */
10249   W (ret);
10250   return ret;
10251 }
10252
10253 static int
10254 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10255 {
10256   unformat_input_t *i = vam->input;
10257   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10258   u32 sw_if_index;
10259   u8 sw_if_index_set = 0;
10260   u8 suppress = 0;
10261   u8 managed = 0;
10262   u8 other = 0;
10263   u8 ll_option = 0;
10264   u8 send_unicast = 0;
10265   u8 cease = 0;
10266   u8 is_no = 0;
10267   u8 default_router = 0;
10268   u32 max_interval = 0;
10269   u32 min_interval = 0;
10270   u32 lifetime = 0;
10271   u32 initial_count = 0;
10272   u32 initial_interval = 0;
10273   int ret;
10274
10275
10276   /* Parse args required to build the message */
10277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10278     {
10279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10280         sw_if_index_set = 1;
10281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10282         sw_if_index_set = 1;
10283       else if (unformat (i, "maxint %d", &max_interval))
10284         ;
10285       else if (unformat (i, "minint %d", &min_interval))
10286         ;
10287       else if (unformat (i, "life %d", &lifetime))
10288         ;
10289       else if (unformat (i, "count %d", &initial_count))
10290         ;
10291       else if (unformat (i, "interval %d", &initial_interval))
10292         ;
10293       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10294         suppress = 1;
10295       else if (unformat (i, "managed"))
10296         managed = 1;
10297       else if (unformat (i, "other"))
10298         other = 1;
10299       else if (unformat (i, "ll"))
10300         ll_option = 1;
10301       else if (unformat (i, "send"))
10302         send_unicast = 1;
10303       else if (unformat (i, "cease"))
10304         cease = 1;
10305       else if (unformat (i, "isno"))
10306         is_no = 1;
10307       else if (unformat (i, "def"))
10308         default_router = 1;
10309       else
10310         {
10311           clib_warning ("parse error '%U'", format_unformat_error, i);
10312           return -99;
10313         }
10314     }
10315
10316   if (sw_if_index_set == 0)
10317     {
10318       errmsg ("missing interface name or sw_if_index");
10319       return -99;
10320     }
10321
10322   /* Construct the API message */
10323   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10324
10325   mp->sw_if_index = ntohl (sw_if_index);
10326   mp->max_interval = ntohl (max_interval);
10327   mp->min_interval = ntohl (min_interval);
10328   mp->lifetime = ntohl (lifetime);
10329   mp->initial_count = ntohl (initial_count);
10330   mp->initial_interval = ntohl (initial_interval);
10331   mp->suppress = suppress;
10332   mp->managed = managed;
10333   mp->other = other;
10334   mp->ll_option = ll_option;
10335   mp->send_unicast = send_unicast;
10336   mp->cease = cease;
10337   mp->is_no = is_no;
10338   mp->default_router = default_router;
10339
10340   /* send it... */
10341   S (mp);
10342
10343   /* Wait for a reply, return good/bad news  */
10344   W (ret);
10345   return ret;
10346 }
10347
10348 static int
10349 api_set_arp_neighbor_limit (vat_main_t * vam)
10350 {
10351   unformat_input_t *i = vam->input;
10352   vl_api_set_arp_neighbor_limit_t *mp;
10353   u32 arp_nbr_limit;
10354   u8 limit_set = 0;
10355   u8 is_ipv6 = 0;
10356   int ret;
10357
10358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10359     {
10360       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10361         limit_set = 1;
10362       else if (unformat (i, "ipv6"))
10363         is_ipv6 = 1;
10364       else
10365         {
10366           clib_warning ("parse error '%U'", format_unformat_error, i);
10367           return -99;
10368         }
10369     }
10370
10371   if (limit_set == 0)
10372     {
10373       errmsg ("missing limit value");
10374       return -99;
10375     }
10376
10377   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10378
10379   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10380   mp->is_ipv6 = is_ipv6;
10381
10382   S (mp);
10383   W (ret);
10384   return ret;
10385 }
10386
10387 static int
10388 api_l2_patch_add_del (vat_main_t * vam)
10389 {
10390   unformat_input_t *i = vam->input;
10391   vl_api_l2_patch_add_del_t *mp;
10392   u32 rx_sw_if_index;
10393   u8 rx_sw_if_index_set = 0;
10394   u32 tx_sw_if_index;
10395   u8 tx_sw_if_index_set = 0;
10396   u8 is_add = 1;
10397   int ret;
10398
10399   /* Parse args required to build the message */
10400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10401     {
10402       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10403         rx_sw_if_index_set = 1;
10404       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10405         tx_sw_if_index_set = 1;
10406       else if (unformat (i, "rx"))
10407         {
10408           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10409             {
10410               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10411                             &rx_sw_if_index))
10412                 rx_sw_if_index_set = 1;
10413             }
10414           else
10415             break;
10416         }
10417       else if (unformat (i, "tx"))
10418         {
10419           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10420             {
10421               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10422                             &tx_sw_if_index))
10423                 tx_sw_if_index_set = 1;
10424             }
10425           else
10426             break;
10427         }
10428       else if (unformat (i, "del"))
10429         is_add = 0;
10430       else
10431         break;
10432     }
10433
10434   if (rx_sw_if_index_set == 0)
10435     {
10436       errmsg ("missing rx interface name or rx_sw_if_index");
10437       return -99;
10438     }
10439
10440   if (tx_sw_if_index_set == 0)
10441     {
10442       errmsg ("missing tx interface name or tx_sw_if_index");
10443       return -99;
10444     }
10445
10446   M (L2_PATCH_ADD_DEL, mp);
10447
10448   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10449   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10450   mp->is_add = is_add;
10451
10452   S (mp);
10453   W (ret);
10454   return ret;
10455 }
10456
10457 u8 is_del;
10458 u8 localsid_addr[16];
10459 u8 end_psp;
10460 u8 behavior;
10461 u32 sw_if_index;
10462 u32 vlan_index;
10463 u32 fib_table;
10464 u8 nh_addr[16];
10465
10466 static int
10467 api_sr_localsid_add_del (vat_main_t * vam)
10468 {
10469   unformat_input_t *i = vam->input;
10470   vl_api_sr_localsid_add_del_t *mp;
10471
10472   u8 is_del;
10473   ip6_address_t localsid;
10474   u8 end_psp = 0;
10475   u8 behavior = ~0;
10476   u32 sw_if_index;
10477   u32 fib_table = ~(u32) 0;
10478   ip6_address_t nh_addr6;
10479   ip4_address_t nh_addr4;
10480   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10481   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10482
10483   bool nexthop_set = 0;
10484
10485   int ret;
10486
10487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10488     {
10489       if (unformat (i, "del"))
10490         is_del = 1;
10491       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10492       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10493         nexthop_set = 1;
10494       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10495         nexthop_set = 1;
10496       else if (unformat (i, "behavior %u", &behavior));
10497       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10498       else if (unformat (i, "fib-table %u", &fib_table));
10499       else if (unformat (i, "end.psp %u", &behavior));
10500       else
10501         break;
10502     }
10503
10504   M (SR_LOCALSID_ADD_DEL, mp);
10505
10506   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10507   if (nexthop_set)
10508     {
10509       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10510       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10511     }
10512   mp->behavior = behavior;
10513   mp->sw_if_index = ntohl (sw_if_index);
10514   mp->fib_table = ntohl (fib_table);
10515   mp->end_psp = end_psp;
10516   mp->is_del = is_del;
10517
10518   S (mp);
10519   W (ret);
10520   return ret;
10521 }
10522
10523 static int
10524 api_ioam_enable (vat_main_t * vam)
10525 {
10526   unformat_input_t *input = vam->input;
10527   vl_api_ioam_enable_t *mp;
10528   u32 id = 0;
10529   int has_trace_option = 0;
10530   int has_pot_option = 0;
10531   int has_seqno_option = 0;
10532   int has_analyse_option = 0;
10533   int ret;
10534
10535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10536     {
10537       if (unformat (input, "trace"))
10538         has_trace_option = 1;
10539       else if (unformat (input, "pot"))
10540         has_pot_option = 1;
10541       else if (unformat (input, "seqno"))
10542         has_seqno_option = 1;
10543       else if (unformat (input, "analyse"))
10544         has_analyse_option = 1;
10545       else
10546         break;
10547     }
10548   M (IOAM_ENABLE, mp);
10549   mp->id = htons (id);
10550   mp->seqno = has_seqno_option;
10551   mp->analyse = has_analyse_option;
10552   mp->pot_enable = has_pot_option;
10553   mp->trace_enable = has_trace_option;
10554
10555   S (mp);
10556   W (ret);
10557   return ret;
10558 }
10559
10560
10561 static int
10562 api_ioam_disable (vat_main_t * vam)
10563 {
10564   vl_api_ioam_disable_t *mp;
10565   int ret;
10566
10567   M (IOAM_DISABLE, mp);
10568   S (mp);
10569   W (ret);
10570   return ret;
10571 }
10572
10573 #define foreach_tcp_proto_field                 \
10574 _(src_port)                                     \
10575 _(dst_port)
10576
10577 #define foreach_udp_proto_field                 \
10578 _(src_port)                                     \
10579 _(dst_port)
10580
10581 #define foreach_ip4_proto_field                 \
10582 _(src_address)                                  \
10583 _(dst_address)                                  \
10584 _(tos)                                          \
10585 _(length)                                       \
10586 _(fragment_id)                                  \
10587 _(ttl)                                          \
10588 _(protocol)                                     \
10589 _(checksum)
10590
10591 typedef struct
10592 {
10593   u16 src_port, dst_port;
10594 } tcpudp_header_t;
10595
10596 #if VPP_API_TEST_BUILTIN == 0
10597 uword
10598 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10599 {
10600   u8 **maskp = va_arg (*args, u8 **);
10601   u8 *mask = 0;
10602   u8 found_something = 0;
10603   tcp_header_t *tcp;
10604
10605 #define _(a) u8 a=0;
10606   foreach_tcp_proto_field;
10607 #undef _
10608
10609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (0);
10612 #define _(a) else if (unformat (input, #a)) a=1;
10613       foreach_tcp_proto_field
10614 #undef _
10615         else
10616         break;
10617     }
10618
10619 #define _(a) found_something += a;
10620   foreach_tcp_proto_field;
10621 #undef _
10622
10623   if (found_something == 0)
10624     return 0;
10625
10626   vec_validate (mask, sizeof (*tcp) - 1);
10627
10628   tcp = (tcp_header_t *) mask;
10629
10630 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10631   foreach_tcp_proto_field;
10632 #undef _
10633
10634   *maskp = mask;
10635   return 1;
10636 }
10637
10638 uword
10639 unformat_udp_mask (unformat_input_t * input, va_list * args)
10640 {
10641   u8 **maskp = va_arg (*args, u8 **);
10642   u8 *mask = 0;
10643   u8 found_something = 0;
10644   udp_header_t *udp;
10645
10646 #define _(a) u8 a=0;
10647   foreach_udp_proto_field;
10648 #undef _
10649
10650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10651     {
10652       if (0);
10653 #define _(a) else if (unformat (input, #a)) a=1;
10654       foreach_udp_proto_field
10655 #undef _
10656         else
10657         break;
10658     }
10659
10660 #define _(a) found_something += a;
10661   foreach_udp_proto_field;
10662 #undef _
10663
10664   if (found_something == 0)
10665     return 0;
10666
10667   vec_validate (mask, sizeof (*udp) - 1);
10668
10669   udp = (udp_header_t *) mask;
10670
10671 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10672   foreach_udp_proto_field;
10673 #undef _
10674
10675   *maskp = mask;
10676   return 1;
10677 }
10678
10679 uword
10680 unformat_l4_mask (unformat_input_t * input, va_list * args)
10681 {
10682   u8 **maskp = va_arg (*args, u8 **);
10683   u16 src_port = 0, dst_port = 0;
10684   tcpudp_header_t *tcpudp;
10685
10686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10687     {
10688       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10689         return 1;
10690       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10691         return 1;
10692       else if (unformat (input, "src_port"))
10693         src_port = 0xFFFF;
10694       else if (unformat (input, "dst_port"))
10695         dst_port = 0xFFFF;
10696       else
10697         return 0;
10698     }
10699
10700   if (!src_port && !dst_port)
10701     return 0;
10702
10703   u8 *mask = 0;
10704   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10705
10706   tcpudp = (tcpudp_header_t *) mask;
10707   tcpudp->src_port = src_port;
10708   tcpudp->dst_port = dst_port;
10709
10710   *maskp = mask;
10711
10712   return 1;
10713 }
10714
10715 uword
10716 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10717 {
10718   u8 **maskp = va_arg (*args, u8 **);
10719   u8 *mask = 0;
10720   u8 found_something = 0;
10721   ip4_header_t *ip;
10722
10723 #define _(a) u8 a=0;
10724   foreach_ip4_proto_field;
10725 #undef _
10726   u8 version = 0;
10727   u8 hdr_length = 0;
10728
10729
10730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10731     {
10732       if (unformat (input, "version"))
10733         version = 1;
10734       else if (unformat (input, "hdr_length"))
10735         hdr_length = 1;
10736       else if (unformat (input, "src"))
10737         src_address = 1;
10738       else if (unformat (input, "dst"))
10739         dst_address = 1;
10740       else if (unformat (input, "proto"))
10741         protocol = 1;
10742
10743 #define _(a) else if (unformat (input, #a)) a=1;
10744       foreach_ip4_proto_field
10745 #undef _
10746         else
10747         break;
10748     }
10749
10750 #define _(a) found_something += a;
10751   foreach_ip4_proto_field;
10752 #undef _
10753
10754   if (found_something == 0)
10755     return 0;
10756
10757   vec_validate (mask, sizeof (*ip) - 1);
10758
10759   ip = (ip4_header_t *) mask;
10760
10761 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10762   foreach_ip4_proto_field;
10763 #undef _
10764
10765   ip->ip_version_and_header_length = 0;
10766
10767   if (version)
10768     ip->ip_version_and_header_length |= 0xF0;
10769
10770   if (hdr_length)
10771     ip->ip_version_and_header_length |= 0x0F;
10772
10773   *maskp = mask;
10774   return 1;
10775 }
10776
10777 #define foreach_ip6_proto_field                 \
10778 _(src_address)                                  \
10779 _(dst_address)                                  \
10780 _(payload_length)                               \
10781 _(hop_limit)                                    \
10782 _(protocol)
10783
10784 uword
10785 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10786 {
10787   u8 **maskp = va_arg (*args, u8 **);
10788   u8 *mask = 0;
10789   u8 found_something = 0;
10790   ip6_header_t *ip;
10791   u32 ip_version_traffic_class_and_flow_label;
10792
10793 #define _(a) u8 a=0;
10794   foreach_ip6_proto_field;
10795 #undef _
10796   u8 version = 0;
10797   u8 traffic_class = 0;
10798   u8 flow_label = 0;
10799
10800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10801     {
10802       if (unformat (input, "version"))
10803         version = 1;
10804       else if (unformat (input, "traffic-class"))
10805         traffic_class = 1;
10806       else if (unformat (input, "flow-label"))
10807         flow_label = 1;
10808       else if (unformat (input, "src"))
10809         src_address = 1;
10810       else if (unformat (input, "dst"))
10811         dst_address = 1;
10812       else if (unformat (input, "proto"))
10813         protocol = 1;
10814
10815 #define _(a) else if (unformat (input, #a)) a=1;
10816       foreach_ip6_proto_field
10817 #undef _
10818         else
10819         break;
10820     }
10821
10822 #define _(a) found_something += a;
10823   foreach_ip6_proto_field;
10824 #undef _
10825
10826   if (found_something == 0)
10827     return 0;
10828
10829   vec_validate (mask, sizeof (*ip) - 1);
10830
10831   ip = (ip6_header_t *) mask;
10832
10833 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10834   foreach_ip6_proto_field;
10835 #undef _
10836
10837   ip_version_traffic_class_and_flow_label = 0;
10838
10839   if (version)
10840     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10841
10842   if (traffic_class)
10843     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10844
10845   if (flow_label)
10846     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10847
10848   ip->ip_version_traffic_class_and_flow_label =
10849     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10850
10851   *maskp = mask;
10852   return 1;
10853 }
10854
10855 uword
10856 unformat_l3_mask (unformat_input_t * input, va_list * args)
10857 {
10858   u8 **maskp = va_arg (*args, u8 **);
10859
10860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10861     {
10862       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10863         return 1;
10864       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10865         return 1;
10866       else
10867         break;
10868     }
10869   return 0;
10870 }
10871
10872 uword
10873 unformat_l2_mask (unformat_input_t * input, va_list * args)
10874 {
10875   u8 **maskp = va_arg (*args, u8 **);
10876   u8 *mask = 0;
10877   u8 src = 0;
10878   u8 dst = 0;
10879   u8 proto = 0;
10880   u8 tag1 = 0;
10881   u8 tag2 = 0;
10882   u8 ignore_tag1 = 0;
10883   u8 ignore_tag2 = 0;
10884   u8 cos1 = 0;
10885   u8 cos2 = 0;
10886   u8 dot1q = 0;
10887   u8 dot1ad = 0;
10888   int len = 14;
10889
10890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10891     {
10892       if (unformat (input, "src"))
10893         src = 1;
10894       else if (unformat (input, "dst"))
10895         dst = 1;
10896       else if (unformat (input, "proto"))
10897         proto = 1;
10898       else if (unformat (input, "tag1"))
10899         tag1 = 1;
10900       else if (unformat (input, "tag2"))
10901         tag2 = 1;
10902       else if (unformat (input, "ignore-tag1"))
10903         ignore_tag1 = 1;
10904       else if (unformat (input, "ignore-tag2"))
10905         ignore_tag2 = 1;
10906       else if (unformat (input, "cos1"))
10907         cos1 = 1;
10908       else if (unformat (input, "cos2"))
10909         cos2 = 1;
10910       else if (unformat (input, "dot1q"))
10911         dot1q = 1;
10912       else if (unformat (input, "dot1ad"))
10913         dot1ad = 1;
10914       else
10915         break;
10916     }
10917   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10918        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10919     return 0;
10920
10921   if (tag1 || ignore_tag1 || cos1 || dot1q)
10922     len = 18;
10923   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10924     len = 22;
10925
10926   vec_validate (mask, len - 1);
10927
10928   if (dst)
10929     clib_memset (mask, 0xff, 6);
10930
10931   if (src)
10932     clib_memset (mask + 6, 0xff, 6);
10933
10934   if (tag2 || dot1ad)
10935     {
10936       /* inner vlan tag */
10937       if (tag2)
10938         {
10939           mask[19] = 0xff;
10940           mask[18] = 0x0f;
10941         }
10942       if (cos2)
10943         mask[18] |= 0xe0;
10944       if (proto)
10945         mask[21] = mask[20] = 0xff;
10946       if (tag1)
10947         {
10948           mask[15] = 0xff;
10949           mask[14] = 0x0f;
10950         }
10951       if (cos1)
10952         mask[14] |= 0xe0;
10953       *maskp = mask;
10954       return 1;
10955     }
10956   if (tag1 | dot1q)
10957     {
10958       if (tag1)
10959         {
10960           mask[15] = 0xff;
10961           mask[14] = 0x0f;
10962         }
10963       if (cos1)
10964         mask[14] |= 0xe0;
10965       if (proto)
10966         mask[16] = mask[17] = 0xff;
10967
10968       *maskp = mask;
10969       return 1;
10970     }
10971   if (cos2)
10972     mask[18] |= 0xe0;
10973   if (cos1)
10974     mask[14] |= 0xe0;
10975   if (proto)
10976     mask[12] = mask[13] = 0xff;
10977
10978   *maskp = mask;
10979   return 1;
10980 }
10981
10982 uword
10983 unformat_classify_mask (unformat_input_t * input, va_list * args)
10984 {
10985   u8 **maskp = va_arg (*args, u8 **);
10986   u32 *skipp = va_arg (*args, u32 *);
10987   u32 *matchp = va_arg (*args, u32 *);
10988   u32 match;
10989   u8 *mask = 0;
10990   u8 *l2 = 0;
10991   u8 *l3 = 0;
10992   u8 *l4 = 0;
10993   int i;
10994
10995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10996     {
10997       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10998         ;
10999       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11000         ;
11001       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11002         ;
11003       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11004         ;
11005       else
11006         break;
11007     }
11008
11009   if (l4 && !l3)
11010     {
11011       vec_free (mask);
11012       vec_free (l2);
11013       vec_free (l4);
11014       return 0;
11015     }
11016
11017   if (mask || l2 || l3 || l4)
11018     {
11019       if (l2 || l3 || l4)
11020         {
11021           /* "With a free Ethernet header in every package" */
11022           if (l2 == 0)
11023             vec_validate (l2, 13);
11024           mask = l2;
11025           if (vec_len (l3))
11026             {
11027               vec_append (mask, l3);
11028               vec_free (l3);
11029             }
11030           if (vec_len (l4))
11031             {
11032               vec_append (mask, l4);
11033               vec_free (l4);
11034             }
11035         }
11036
11037       /* Scan forward looking for the first significant mask octet */
11038       for (i = 0; i < vec_len (mask); i++)
11039         if (mask[i])
11040           break;
11041
11042       /* compute (skip, match) params */
11043       *skipp = i / sizeof (u32x4);
11044       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11045
11046       /* Pad mask to an even multiple of the vector size */
11047       while (vec_len (mask) % sizeof (u32x4))
11048         vec_add1 (mask, 0);
11049
11050       match = vec_len (mask) / sizeof (u32x4);
11051
11052       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11053         {
11054           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11055           if (*tmp || *(tmp + 1))
11056             break;
11057           match--;
11058         }
11059       if (match == 0)
11060         clib_warning ("BUG: match 0");
11061
11062       _vec_len (mask) = match * sizeof (u32x4);
11063
11064       *matchp = match;
11065       *maskp = mask;
11066
11067       return 1;
11068     }
11069
11070   return 0;
11071 }
11072 #endif /* VPP_API_TEST_BUILTIN */
11073
11074 #define foreach_l2_next                         \
11075 _(drop, DROP)                                   \
11076 _(ethernet, ETHERNET_INPUT)                     \
11077 _(ip4, IP4_INPUT)                               \
11078 _(ip6, IP6_INPUT)
11079
11080 uword
11081 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11082 {
11083   u32 *miss_next_indexp = va_arg (*args, u32 *);
11084   u32 next_index = 0;
11085   u32 tmp;
11086
11087 #define _(n,N) \
11088   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11089   foreach_l2_next;
11090 #undef _
11091
11092   if (unformat (input, "%d", &tmp))
11093     {
11094       next_index = tmp;
11095       goto out;
11096     }
11097
11098   return 0;
11099
11100 out:
11101   *miss_next_indexp = next_index;
11102   return 1;
11103 }
11104
11105 #define foreach_ip_next                         \
11106 _(drop, DROP)                                   \
11107 _(local, LOCAL)                                 \
11108 _(rewrite, REWRITE)
11109
11110 uword
11111 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11112 {
11113   u32 *miss_next_indexp = va_arg (*args, u32 *);
11114   u32 next_index = 0;
11115   u32 tmp;
11116
11117 #define _(n,N) \
11118   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11119   foreach_ip_next;
11120 #undef _
11121
11122   if (unformat (input, "%d", &tmp))
11123     {
11124       next_index = tmp;
11125       goto out;
11126     }
11127
11128   return 0;
11129
11130 out:
11131   *miss_next_indexp = next_index;
11132   return 1;
11133 }
11134
11135 #define foreach_acl_next                        \
11136 _(deny, DENY)
11137
11138 uword
11139 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11140 {
11141   u32 *miss_next_indexp = va_arg (*args, u32 *);
11142   u32 next_index = 0;
11143   u32 tmp;
11144
11145 #define _(n,N) \
11146   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11147   foreach_acl_next;
11148 #undef _
11149
11150   if (unformat (input, "permit"))
11151     {
11152       next_index = ~0;
11153       goto out;
11154     }
11155   else if (unformat (input, "%d", &tmp))
11156     {
11157       next_index = tmp;
11158       goto out;
11159     }
11160
11161   return 0;
11162
11163 out:
11164   *miss_next_indexp = next_index;
11165   return 1;
11166 }
11167
11168 uword
11169 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11170 {
11171   u32 *r = va_arg (*args, u32 *);
11172
11173   if (unformat (input, "conform-color"))
11174     *r = POLICE_CONFORM;
11175   else if (unformat (input, "exceed-color"))
11176     *r = POLICE_EXCEED;
11177   else
11178     return 0;
11179
11180   return 1;
11181 }
11182
11183 static int
11184 api_classify_add_del_table (vat_main_t * vam)
11185 {
11186   unformat_input_t *i = vam->input;
11187   vl_api_classify_add_del_table_t *mp;
11188
11189   u32 nbuckets = 2;
11190   u32 skip = ~0;
11191   u32 match = ~0;
11192   int is_add = 1;
11193   int del_chain = 0;
11194   u32 table_index = ~0;
11195   u32 next_table_index = ~0;
11196   u32 miss_next_index = ~0;
11197   u32 memory_size = 32 << 20;
11198   u8 *mask = 0;
11199   u32 current_data_flag = 0;
11200   int current_data_offset = 0;
11201   int ret;
11202
11203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11204     {
11205       if (unformat (i, "del"))
11206         is_add = 0;
11207       else if (unformat (i, "del-chain"))
11208         {
11209           is_add = 0;
11210           del_chain = 1;
11211         }
11212       else if (unformat (i, "buckets %d", &nbuckets))
11213         ;
11214       else if (unformat (i, "memory_size %d", &memory_size))
11215         ;
11216       else if (unformat (i, "skip %d", &skip))
11217         ;
11218       else if (unformat (i, "match %d", &match))
11219         ;
11220       else if (unformat (i, "table %d", &table_index))
11221         ;
11222       else if (unformat (i, "mask %U", unformat_classify_mask,
11223                          &mask, &skip, &match))
11224         ;
11225       else if (unformat (i, "next-table %d", &next_table_index))
11226         ;
11227       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11228                          &miss_next_index))
11229         ;
11230       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11231                          &miss_next_index))
11232         ;
11233       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11234                          &miss_next_index))
11235         ;
11236       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11237         ;
11238       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11239         ;
11240       else
11241         break;
11242     }
11243
11244   if (is_add && mask == 0)
11245     {
11246       errmsg ("Mask required");
11247       return -99;
11248     }
11249
11250   if (is_add && skip == ~0)
11251     {
11252       errmsg ("skip count required");
11253       return -99;
11254     }
11255
11256   if (is_add && match == ~0)
11257     {
11258       errmsg ("match count required");
11259       return -99;
11260     }
11261
11262   if (!is_add && table_index == ~0)
11263     {
11264       errmsg ("table index required for delete");
11265       return -99;
11266     }
11267
11268   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11269
11270   mp->is_add = is_add;
11271   mp->del_chain = del_chain;
11272   mp->table_index = ntohl (table_index);
11273   mp->nbuckets = ntohl (nbuckets);
11274   mp->memory_size = ntohl (memory_size);
11275   mp->skip_n_vectors = ntohl (skip);
11276   mp->match_n_vectors = ntohl (match);
11277   mp->next_table_index = ntohl (next_table_index);
11278   mp->miss_next_index = ntohl (miss_next_index);
11279   mp->current_data_flag = ntohl (current_data_flag);
11280   mp->current_data_offset = ntohl (current_data_offset);
11281   mp->mask_len = ntohl (vec_len (mask));
11282   clib_memcpy (mp->mask, mask, vec_len (mask));
11283
11284   vec_free (mask);
11285
11286   S (mp);
11287   W (ret);
11288   return ret;
11289 }
11290
11291 #if VPP_API_TEST_BUILTIN == 0
11292 uword
11293 unformat_l4_match (unformat_input_t * input, va_list * args)
11294 {
11295   u8 **matchp = va_arg (*args, u8 **);
11296
11297   u8 *proto_header = 0;
11298   int src_port = 0;
11299   int dst_port = 0;
11300
11301   tcpudp_header_t h;
11302
11303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11304     {
11305       if (unformat (input, "src_port %d", &src_port))
11306         ;
11307       else if (unformat (input, "dst_port %d", &dst_port))
11308         ;
11309       else
11310         return 0;
11311     }
11312
11313   h.src_port = clib_host_to_net_u16 (src_port);
11314   h.dst_port = clib_host_to_net_u16 (dst_port);
11315   vec_validate (proto_header, sizeof (h) - 1);
11316   memcpy (proto_header, &h, sizeof (h));
11317
11318   *matchp = proto_header;
11319
11320   return 1;
11321 }
11322
11323 uword
11324 unformat_ip4_match (unformat_input_t * input, va_list * args)
11325 {
11326   u8 **matchp = va_arg (*args, u8 **);
11327   u8 *match = 0;
11328   ip4_header_t *ip;
11329   int version = 0;
11330   u32 version_val;
11331   int hdr_length = 0;
11332   u32 hdr_length_val;
11333   int src = 0, dst = 0;
11334   ip4_address_t src_val, dst_val;
11335   int proto = 0;
11336   u32 proto_val;
11337   int tos = 0;
11338   u32 tos_val;
11339   int length = 0;
11340   u32 length_val;
11341   int fragment_id = 0;
11342   u32 fragment_id_val;
11343   int ttl = 0;
11344   int ttl_val;
11345   int checksum = 0;
11346   u32 checksum_val;
11347
11348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11349     {
11350       if (unformat (input, "version %d", &version_val))
11351         version = 1;
11352       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11353         hdr_length = 1;
11354       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11355         src = 1;
11356       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11357         dst = 1;
11358       else if (unformat (input, "proto %d", &proto_val))
11359         proto = 1;
11360       else if (unformat (input, "tos %d", &tos_val))
11361         tos = 1;
11362       else if (unformat (input, "length %d", &length_val))
11363         length = 1;
11364       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11365         fragment_id = 1;
11366       else if (unformat (input, "ttl %d", &ttl_val))
11367         ttl = 1;
11368       else if (unformat (input, "checksum %d", &checksum_val))
11369         checksum = 1;
11370       else
11371         break;
11372     }
11373
11374   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11375       + ttl + checksum == 0)
11376     return 0;
11377
11378   /*
11379    * Aligned because we use the real comparison functions
11380    */
11381   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11382
11383   ip = (ip4_header_t *) match;
11384
11385   /* These are realistically matched in practice */
11386   if (src)
11387     ip->src_address.as_u32 = src_val.as_u32;
11388
11389   if (dst)
11390     ip->dst_address.as_u32 = dst_val.as_u32;
11391
11392   if (proto)
11393     ip->protocol = proto_val;
11394
11395
11396   /* These are not, but they're included for completeness */
11397   if (version)
11398     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11399
11400   if (hdr_length)
11401     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11402
11403   if (tos)
11404     ip->tos = tos_val;
11405
11406   if (length)
11407     ip->length = clib_host_to_net_u16 (length_val);
11408
11409   if (ttl)
11410     ip->ttl = ttl_val;
11411
11412   if (checksum)
11413     ip->checksum = clib_host_to_net_u16 (checksum_val);
11414
11415   *matchp = match;
11416   return 1;
11417 }
11418
11419 uword
11420 unformat_ip6_match (unformat_input_t * input, va_list * args)
11421 {
11422   u8 **matchp = va_arg (*args, u8 **);
11423   u8 *match = 0;
11424   ip6_header_t *ip;
11425   int version = 0;
11426   u32 version_val;
11427   u8 traffic_class = 0;
11428   u32 traffic_class_val = 0;
11429   u8 flow_label = 0;
11430   u8 flow_label_val;
11431   int src = 0, dst = 0;
11432   ip6_address_t src_val, dst_val;
11433   int proto = 0;
11434   u32 proto_val;
11435   int payload_length = 0;
11436   u32 payload_length_val;
11437   int hop_limit = 0;
11438   int hop_limit_val;
11439   u32 ip_version_traffic_class_and_flow_label;
11440
11441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11442     {
11443       if (unformat (input, "version %d", &version_val))
11444         version = 1;
11445       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11446         traffic_class = 1;
11447       else if (unformat (input, "flow_label %d", &flow_label_val))
11448         flow_label = 1;
11449       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11450         src = 1;
11451       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11452         dst = 1;
11453       else if (unformat (input, "proto %d", &proto_val))
11454         proto = 1;
11455       else if (unformat (input, "payload_length %d", &payload_length_val))
11456         payload_length = 1;
11457       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11458         hop_limit = 1;
11459       else
11460         break;
11461     }
11462
11463   if (version + traffic_class + flow_label + src + dst + proto +
11464       payload_length + hop_limit == 0)
11465     return 0;
11466
11467   /*
11468    * Aligned because we use the real comparison functions
11469    */
11470   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11471
11472   ip = (ip6_header_t *) match;
11473
11474   if (src)
11475     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11476
11477   if (dst)
11478     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11479
11480   if (proto)
11481     ip->protocol = proto_val;
11482
11483   ip_version_traffic_class_and_flow_label = 0;
11484
11485   if (version)
11486     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11487
11488   if (traffic_class)
11489     ip_version_traffic_class_and_flow_label |=
11490       (traffic_class_val & 0xFF) << 20;
11491
11492   if (flow_label)
11493     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11494
11495   ip->ip_version_traffic_class_and_flow_label =
11496     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11497
11498   if (payload_length)
11499     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11500
11501   if (hop_limit)
11502     ip->hop_limit = hop_limit_val;
11503
11504   *matchp = match;
11505   return 1;
11506 }
11507
11508 uword
11509 unformat_l3_match (unformat_input_t * input, va_list * args)
11510 {
11511   u8 **matchp = va_arg (*args, u8 **);
11512
11513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11514     {
11515       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11516         return 1;
11517       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11518         return 1;
11519       else
11520         break;
11521     }
11522   return 0;
11523 }
11524
11525 uword
11526 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11527 {
11528   u8 *tagp = va_arg (*args, u8 *);
11529   u32 tag;
11530
11531   if (unformat (input, "%d", &tag))
11532     {
11533       tagp[0] = (tag >> 8) & 0x0F;
11534       tagp[1] = tag & 0xFF;
11535       return 1;
11536     }
11537
11538   return 0;
11539 }
11540
11541 uword
11542 unformat_l2_match (unformat_input_t * input, va_list * args)
11543 {
11544   u8 **matchp = va_arg (*args, u8 **);
11545   u8 *match = 0;
11546   u8 src = 0;
11547   u8 src_val[6];
11548   u8 dst = 0;
11549   u8 dst_val[6];
11550   u8 proto = 0;
11551   u16 proto_val;
11552   u8 tag1 = 0;
11553   u8 tag1_val[2];
11554   u8 tag2 = 0;
11555   u8 tag2_val[2];
11556   int len = 14;
11557   u8 ignore_tag1 = 0;
11558   u8 ignore_tag2 = 0;
11559   u8 cos1 = 0;
11560   u8 cos2 = 0;
11561   u32 cos1_val = 0;
11562   u32 cos2_val = 0;
11563
11564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11565     {
11566       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11567         src = 1;
11568       else
11569         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11570         dst = 1;
11571       else if (unformat (input, "proto %U",
11572                          unformat_ethernet_type_host_byte_order, &proto_val))
11573         proto = 1;
11574       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11575         tag1 = 1;
11576       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11577         tag2 = 1;
11578       else if (unformat (input, "ignore-tag1"))
11579         ignore_tag1 = 1;
11580       else if (unformat (input, "ignore-tag2"))
11581         ignore_tag2 = 1;
11582       else if (unformat (input, "cos1 %d", &cos1_val))
11583         cos1 = 1;
11584       else if (unformat (input, "cos2 %d", &cos2_val))
11585         cos2 = 1;
11586       else
11587         break;
11588     }
11589   if ((src + dst + proto + tag1 + tag2 +
11590        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11591     return 0;
11592
11593   if (tag1 || ignore_tag1 || cos1)
11594     len = 18;
11595   if (tag2 || ignore_tag2 || cos2)
11596     len = 22;
11597
11598   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11599
11600   if (dst)
11601     clib_memcpy (match, dst_val, 6);
11602
11603   if (src)
11604     clib_memcpy (match + 6, src_val, 6);
11605
11606   if (tag2)
11607     {
11608       /* inner vlan tag */
11609       match[19] = tag2_val[1];
11610       match[18] = tag2_val[0];
11611       if (cos2)
11612         match[18] |= (cos2_val & 0x7) << 5;
11613       if (proto)
11614         {
11615           match[21] = proto_val & 0xff;
11616           match[20] = proto_val >> 8;
11617         }
11618       if (tag1)
11619         {
11620           match[15] = tag1_val[1];
11621           match[14] = tag1_val[0];
11622         }
11623       if (cos1)
11624         match[14] |= (cos1_val & 0x7) << 5;
11625       *matchp = match;
11626       return 1;
11627     }
11628   if (tag1)
11629     {
11630       match[15] = tag1_val[1];
11631       match[14] = tag1_val[0];
11632       if (proto)
11633         {
11634           match[17] = proto_val & 0xff;
11635           match[16] = proto_val >> 8;
11636         }
11637       if (cos1)
11638         match[14] |= (cos1_val & 0x7) << 5;
11639
11640       *matchp = match;
11641       return 1;
11642     }
11643   if (cos2)
11644     match[18] |= (cos2_val & 0x7) << 5;
11645   if (cos1)
11646     match[14] |= (cos1_val & 0x7) << 5;
11647   if (proto)
11648     {
11649       match[13] = proto_val & 0xff;
11650       match[12] = proto_val >> 8;
11651     }
11652
11653   *matchp = match;
11654   return 1;
11655 }
11656
11657 uword
11658 unformat_qos_source (unformat_input_t * input, va_list * args)
11659 {
11660   int *qs = va_arg (*args, int *);
11661
11662   if (unformat (input, "ip"))
11663     *qs = QOS_SOURCE_IP;
11664   else if (unformat (input, "mpls"))
11665     *qs = QOS_SOURCE_MPLS;
11666   else if (unformat (input, "ext"))
11667     *qs = QOS_SOURCE_EXT;
11668   else if (unformat (input, "vlan"))
11669     *qs = QOS_SOURCE_VLAN;
11670   else
11671     return 0;
11672
11673   return 1;
11674 }
11675 #endif
11676
11677 uword
11678 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11679 {
11680   u8 **matchp = va_arg (*args, u8 **);
11681   u32 skip_n_vectors = va_arg (*args, u32);
11682   u32 match_n_vectors = va_arg (*args, u32);
11683
11684   u8 *match = 0;
11685   u8 *l2 = 0;
11686   u8 *l3 = 0;
11687   u8 *l4 = 0;
11688
11689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11690     {
11691       if (unformat (input, "hex %U", unformat_hex_string, &match))
11692         ;
11693       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11694         ;
11695       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11696         ;
11697       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11698         ;
11699       else
11700         break;
11701     }
11702
11703   if (l4 && !l3)
11704     {
11705       vec_free (match);
11706       vec_free (l2);
11707       vec_free (l4);
11708       return 0;
11709     }
11710
11711   if (match || l2 || l3 || l4)
11712     {
11713       if (l2 || l3 || l4)
11714         {
11715           /* "Win a free Ethernet header in every packet" */
11716           if (l2 == 0)
11717             vec_validate_aligned (l2, 13, sizeof (u32x4));
11718           match = l2;
11719           if (vec_len (l3))
11720             {
11721               vec_append_aligned (match, l3, sizeof (u32x4));
11722               vec_free (l3);
11723             }
11724           if (vec_len (l4))
11725             {
11726               vec_append_aligned (match, l4, sizeof (u32x4));
11727               vec_free (l4);
11728             }
11729         }
11730
11731       /* Make sure the vector is big enough even if key is all 0's */
11732       vec_validate_aligned
11733         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11734          sizeof (u32x4));
11735
11736       /* Set size, include skipped vectors */
11737       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11738
11739       *matchp = match;
11740
11741       return 1;
11742     }
11743
11744   return 0;
11745 }
11746
11747 static int
11748 api_classify_add_del_session (vat_main_t * vam)
11749 {
11750   unformat_input_t *i = vam->input;
11751   vl_api_classify_add_del_session_t *mp;
11752   int is_add = 1;
11753   u32 table_index = ~0;
11754   u32 hit_next_index = ~0;
11755   u32 opaque_index = ~0;
11756   u8 *match = 0;
11757   i32 advance = 0;
11758   u32 skip_n_vectors = 0;
11759   u32 match_n_vectors = 0;
11760   u32 action = 0;
11761   u32 metadata = 0;
11762   int ret;
11763
11764   /*
11765    * Warning: you have to supply skip_n and match_n
11766    * because the API client cant simply look at the classify
11767    * table object.
11768    */
11769
11770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11771     {
11772       if (unformat (i, "del"))
11773         is_add = 0;
11774       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11775                          &hit_next_index))
11776         ;
11777       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11778                          &hit_next_index))
11779         ;
11780       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11781                          &hit_next_index))
11782         ;
11783       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11784         ;
11785       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11786         ;
11787       else if (unformat (i, "opaque-index %d", &opaque_index))
11788         ;
11789       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11790         ;
11791       else if (unformat (i, "match_n %d", &match_n_vectors))
11792         ;
11793       else if (unformat (i, "match %U", api_unformat_classify_match,
11794                          &match, skip_n_vectors, match_n_vectors))
11795         ;
11796       else if (unformat (i, "advance %d", &advance))
11797         ;
11798       else if (unformat (i, "table-index %d", &table_index))
11799         ;
11800       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11801         action = 1;
11802       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11803         action = 2;
11804       else if (unformat (i, "action %d", &action))
11805         ;
11806       else if (unformat (i, "metadata %d", &metadata))
11807         ;
11808       else
11809         break;
11810     }
11811
11812   if (table_index == ~0)
11813     {
11814       errmsg ("Table index required");
11815       return -99;
11816     }
11817
11818   if (is_add && match == 0)
11819     {
11820       errmsg ("Match value required");
11821       return -99;
11822     }
11823
11824   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11825
11826   mp->is_add = is_add;
11827   mp->table_index = ntohl (table_index);
11828   mp->hit_next_index = ntohl (hit_next_index);
11829   mp->opaque_index = ntohl (opaque_index);
11830   mp->advance = ntohl (advance);
11831   mp->action = action;
11832   mp->metadata = ntohl (metadata);
11833   mp->match_len = ntohl (vec_len (match));
11834   clib_memcpy (mp->match, match, vec_len (match));
11835   vec_free (match);
11836
11837   S (mp);
11838   W (ret);
11839   return ret;
11840 }
11841
11842 static int
11843 api_classify_set_interface_ip_table (vat_main_t * vam)
11844 {
11845   unformat_input_t *i = vam->input;
11846   vl_api_classify_set_interface_ip_table_t *mp;
11847   u32 sw_if_index;
11848   int sw_if_index_set;
11849   u32 table_index = ~0;
11850   u8 is_ipv6 = 0;
11851   int ret;
11852
11853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11854     {
11855       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11856         sw_if_index_set = 1;
11857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11858         sw_if_index_set = 1;
11859       else if (unformat (i, "table %d", &table_index))
11860         ;
11861       else
11862         {
11863           clib_warning ("parse error '%U'", format_unformat_error, i);
11864           return -99;
11865         }
11866     }
11867
11868   if (sw_if_index_set == 0)
11869     {
11870       errmsg ("missing interface name or sw_if_index");
11871       return -99;
11872     }
11873
11874
11875   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11876
11877   mp->sw_if_index = ntohl (sw_if_index);
11878   mp->table_index = ntohl (table_index);
11879   mp->is_ipv6 = is_ipv6;
11880
11881   S (mp);
11882   W (ret);
11883   return ret;
11884 }
11885
11886 static int
11887 api_classify_set_interface_l2_tables (vat_main_t * vam)
11888 {
11889   unformat_input_t *i = vam->input;
11890   vl_api_classify_set_interface_l2_tables_t *mp;
11891   u32 sw_if_index;
11892   int sw_if_index_set;
11893   u32 ip4_table_index = ~0;
11894   u32 ip6_table_index = ~0;
11895   u32 other_table_index = ~0;
11896   u32 is_input = 1;
11897   int ret;
11898
11899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11900     {
11901       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11902         sw_if_index_set = 1;
11903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11904         sw_if_index_set = 1;
11905       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11906         ;
11907       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11908         ;
11909       else if (unformat (i, "other-table %d", &other_table_index))
11910         ;
11911       else if (unformat (i, "is-input %d", &is_input))
11912         ;
11913       else
11914         {
11915           clib_warning ("parse error '%U'", format_unformat_error, i);
11916           return -99;
11917         }
11918     }
11919
11920   if (sw_if_index_set == 0)
11921     {
11922       errmsg ("missing interface name or sw_if_index");
11923       return -99;
11924     }
11925
11926
11927   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11928
11929   mp->sw_if_index = ntohl (sw_if_index);
11930   mp->ip4_table_index = ntohl (ip4_table_index);
11931   mp->ip6_table_index = ntohl (ip6_table_index);
11932   mp->other_table_index = ntohl (other_table_index);
11933   mp->is_input = (u8) is_input;
11934
11935   S (mp);
11936   W (ret);
11937   return ret;
11938 }
11939
11940 static int
11941 api_set_ipfix_exporter (vat_main_t * vam)
11942 {
11943   unformat_input_t *i = vam->input;
11944   vl_api_set_ipfix_exporter_t *mp;
11945   ip4_address_t collector_address;
11946   u8 collector_address_set = 0;
11947   u32 collector_port = ~0;
11948   ip4_address_t src_address;
11949   u8 src_address_set = 0;
11950   u32 vrf_id = ~0;
11951   u32 path_mtu = ~0;
11952   u32 template_interval = ~0;
11953   u8 udp_checksum = 0;
11954   int ret;
11955
11956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11957     {
11958       if (unformat (i, "collector_address %U", unformat_ip4_address,
11959                     &collector_address))
11960         collector_address_set = 1;
11961       else if (unformat (i, "collector_port %d", &collector_port))
11962         ;
11963       else if (unformat (i, "src_address %U", unformat_ip4_address,
11964                          &src_address))
11965         src_address_set = 1;
11966       else if (unformat (i, "vrf_id %d", &vrf_id))
11967         ;
11968       else if (unformat (i, "path_mtu %d", &path_mtu))
11969         ;
11970       else if (unformat (i, "template_interval %d", &template_interval))
11971         ;
11972       else if (unformat (i, "udp_checksum"))
11973         udp_checksum = 1;
11974       else
11975         break;
11976     }
11977
11978   if (collector_address_set == 0)
11979     {
11980       errmsg ("collector_address required");
11981       return -99;
11982     }
11983
11984   if (src_address_set == 0)
11985     {
11986       errmsg ("src_address required");
11987       return -99;
11988     }
11989
11990   M (SET_IPFIX_EXPORTER, mp);
11991
11992   memcpy (mp->collector_address, collector_address.data,
11993           sizeof (collector_address.data));
11994   mp->collector_port = htons ((u16) collector_port);
11995   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11996   mp->vrf_id = htonl (vrf_id);
11997   mp->path_mtu = htonl (path_mtu);
11998   mp->template_interval = htonl (template_interval);
11999   mp->udp_checksum = udp_checksum;
12000
12001   S (mp);
12002   W (ret);
12003   return ret;
12004 }
12005
12006 static int
12007 api_set_ipfix_classify_stream (vat_main_t * vam)
12008 {
12009   unformat_input_t *i = vam->input;
12010   vl_api_set_ipfix_classify_stream_t *mp;
12011   u32 domain_id = 0;
12012   u32 src_port = UDP_DST_PORT_ipfix;
12013   int ret;
12014
12015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12016     {
12017       if (unformat (i, "domain %d", &domain_id))
12018         ;
12019       else if (unformat (i, "src_port %d", &src_port))
12020         ;
12021       else
12022         {
12023           errmsg ("unknown input `%U'", format_unformat_error, i);
12024           return -99;
12025         }
12026     }
12027
12028   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12029
12030   mp->domain_id = htonl (domain_id);
12031   mp->src_port = htons ((u16) src_port);
12032
12033   S (mp);
12034   W (ret);
12035   return ret;
12036 }
12037
12038 static int
12039 api_ipfix_classify_table_add_del (vat_main_t * vam)
12040 {
12041   unformat_input_t *i = vam->input;
12042   vl_api_ipfix_classify_table_add_del_t *mp;
12043   int is_add = -1;
12044   u32 classify_table_index = ~0;
12045   u8 ip_version = 0;
12046   u8 transport_protocol = 255;
12047   int ret;
12048
12049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12050     {
12051       if (unformat (i, "add"))
12052         is_add = 1;
12053       else if (unformat (i, "del"))
12054         is_add = 0;
12055       else if (unformat (i, "table %d", &classify_table_index))
12056         ;
12057       else if (unformat (i, "ip4"))
12058         ip_version = 4;
12059       else if (unformat (i, "ip6"))
12060         ip_version = 6;
12061       else if (unformat (i, "tcp"))
12062         transport_protocol = 6;
12063       else if (unformat (i, "udp"))
12064         transport_protocol = 17;
12065       else
12066         {
12067           errmsg ("unknown input `%U'", format_unformat_error, i);
12068           return -99;
12069         }
12070     }
12071
12072   if (is_add == -1)
12073     {
12074       errmsg ("expecting: add|del");
12075       return -99;
12076     }
12077   if (classify_table_index == ~0)
12078     {
12079       errmsg ("classifier table not specified");
12080       return -99;
12081     }
12082   if (ip_version == 0)
12083     {
12084       errmsg ("IP version not specified");
12085       return -99;
12086     }
12087
12088   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12089
12090   mp->is_add = is_add;
12091   mp->table_id = htonl (classify_table_index);
12092   mp->ip_version = ip_version;
12093   mp->transport_protocol = transport_protocol;
12094
12095   S (mp);
12096   W (ret);
12097   return ret;
12098 }
12099
12100 static int
12101 api_get_node_index (vat_main_t * vam)
12102 {
12103   unformat_input_t *i = vam->input;
12104   vl_api_get_node_index_t *mp;
12105   u8 *name = 0;
12106   int ret;
12107
12108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12109     {
12110       if (unformat (i, "node %s", &name))
12111         ;
12112       else
12113         break;
12114     }
12115   if (name == 0)
12116     {
12117       errmsg ("node name required");
12118       return -99;
12119     }
12120   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12121     {
12122       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12123       return -99;
12124     }
12125
12126   M (GET_NODE_INDEX, mp);
12127   clib_memcpy (mp->node_name, name, vec_len (name));
12128   vec_free (name);
12129
12130   S (mp);
12131   W (ret);
12132   return ret;
12133 }
12134
12135 static int
12136 api_get_next_index (vat_main_t * vam)
12137 {
12138   unformat_input_t *i = vam->input;
12139   vl_api_get_next_index_t *mp;
12140   u8 *node_name = 0, *next_node_name = 0;
12141   int ret;
12142
12143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12144     {
12145       if (unformat (i, "node-name %s", &node_name))
12146         ;
12147       else if (unformat (i, "next-node-name %s", &next_node_name))
12148         break;
12149     }
12150
12151   if (node_name == 0)
12152     {
12153       errmsg ("node name required");
12154       return -99;
12155     }
12156   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12157     {
12158       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12159       return -99;
12160     }
12161
12162   if (next_node_name == 0)
12163     {
12164       errmsg ("next node name required");
12165       return -99;
12166     }
12167   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12168     {
12169       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12170       return -99;
12171     }
12172
12173   M (GET_NEXT_INDEX, mp);
12174   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12175   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12176   vec_free (node_name);
12177   vec_free (next_node_name);
12178
12179   S (mp);
12180   W (ret);
12181   return ret;
12182 }
12183
12184 static int
12185 api_add_node_next (vat_main_t * vam)
12186 {
12187   unformat_input_t *i = vam->input;
12188   vl_api_add_node_next_t *mp;
12189   u8 *name = 0;
12190   u8 *next = 0;
12191   int ret;
12192
12193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12194     {
12195       if (unformat (i, "node %s", &name))
12196         ;
12197       else if (unformat (i, "next %s", &next))
12198         ;
12199       else
12200         break;
12201     }
12202   if (name == 0)
12203     {
12204       errmsg ("node name required");
12205       return -99;
12206     }
12207   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12208     {
12209       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12210       return -99;
12211     }
12212   if (next == 0)
12213     {
12214       errmsg ("next node required");
12215       return -99;
12216     }
12217   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12218     {
12219       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12220       return -99;
12221     }
12222
12223   M (ADD_NODE_NEXT, mp);
12224   clib_memcpy (mp->node_name, name, vec_len (name));
12225   clib_memcpy (mp->next_name, next, vec_len (next));
12226   vec_free (name);
12227   vec_free (next);
12228
12229   S (mp);
12230   W (ret);
12231   return ret;
12232 }
12233
12234 static int
12235 api_l2tpv3_create_tunnel (vat_main_t * vam)
12236 {
12237   unformat_input_t *i = vam->input;
12238   ip6_address_t client_address, our_address;
12239   int client_address_set = 0;
12240   int our_address_set = 0;
12241   u32 local_session_id = 0;
12242   u32 remote_session_id = 0;
12243   u64 local_cookie = 0;
12244   u64 remote_cookie = 0;
12245   u8 l2_sublayer_present = 0;
12246   vl_api_l2tpv3_create_tunnel_t *mp;
12247   int ret;
12248
12249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12250     {
12251       if (unformat (i, "client_address %U", unformat_ip6_address,
12252                     &client_address))
12253         client_address_set = 1;
12254       else if (unformat (i, "our_address %U", unformat_ip6_address,
12255                          &our_address))
12256         our_address_set = 1;
12257       else if (unformat (i, "local_session_id %d", &local_session_id))
12258         ;
12259       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12260         ;
12261       else if (unformat (i, "local_cookie %lld", &local_cookie))
12262         ;
12263       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12264         ;
12265       else if (unformat (i, "l2-sublayer-present"))
12266         l2_sublayer_present = 1;
12267       else
12268         break;
12269     }
12270
12271   if (client_address_set == 0)
12272     {
12273       errmsg ("client_address required");
12274       return -99;
12275     }
12276
12277   if (our_address_set == 0)
12278     {
12279       errmsg ("our_address required");
12280       return -99;
12281     }
12282
12283   M (L2TPV3_CREATE_TUNNEL, mp);
12284
12285   clib_memcpy (mp->client_address, client_address.as_u8,
12286                sizeof (mp->client_address));
12287
12288   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12289
12290   mp->local_session_id = ntohl (local_session_id);
12291   mp->remote_session_id = ntohl (remote_session_id);
12292   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12293   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12294   mp->l2_sublayer_present = l2_sublayer_present;
12295   mp->is_ipv6 = 1;
12296
12297   S (mp);
12298   W (ret);
12299   return ret;
12300 }
12301
12302 static int
12303 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12304 {
12305   unformat_input_t *i = vam->input;
12306   u32 sw_if_index;
12307   u8 sw_if_index_set = 0;
12308   u64 new_local_cookie = 0;
12309   u64 new_remote_cookie = 0;
12310   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12311   int ret;
12312
12313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12314     {
12315       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12316         sw_if_index_set = 1;
12317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12318         sw_if_index_set = 1;
12319       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12320         ;
12321       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12322         ;
12323       else
12324         break;
12325     }
12326
12327   if (sw_if_index_set == 0)
12328     {
12329       errmsg ("missing interface name or sw_if_index");
12330       return -99;
12331     }
12332
12333   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12334
12335   mp->sw_if_index = ntohl (sw_if_index);
12336   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12337   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12338
12339   S (mp);
12340   W (ret);
12341   return ret;
12342 }
12343
12344 static int
12345 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12346 {
12347   unformat_input_t *i = vam->input;
12348   vl_api_l2tpv3_interface_enable_disable_t *mp;
12349   u32 sw_if_index;
12350   u8 sw_if_index_set = 0;
12351   u8 enable_disable = 1;
12352   int ret;
12353
12354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12355     {
12356       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12357         sw_if_index_set = 1;
12358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12359         sw_if_index_set = 1;
12360       else if (unformat (i, "enable"))
12361         enable_disable = 1;
12362       else if (unformat (i, "disable"))
12363         enable_disable = 0;
12364       else
12365         break;
12366     }
12367
12368   if (sw_if_index_set == 0)
12369     {
12370       errmsg ("missing interface name or sw_if_index");
12371       return -99;
12372     }
12373
12374   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12375
12376   mp->sw_if_index = ntohl (sw_if_index);
12377   mp->enable_disable = enable_disable;
12378
12379   S (mp);
12380   W (ret);
12381   return ret;
12382 }
12383
12384 static int
12385 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12386 {
12387   unformat_input_t *i = vam->input;
12388   vl_api_l2tpv3_set_lookup_key_t *mp;
12389   u8 key = ~0;
12390   int ret;
12391
12392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12393     {
12394       if (unformat (i, "lookup_v6_src"))
12395         key = L2T_LOOKUP_SRC_ADDRESS;
12396       else if (unformat (i, "lookup_v6_dst"))
12397         key = L2T_LOOKUP_DST_ADDRESS;
12398       else if (unformat (i, "lookup_session_id"))
12399         key = L2T_LOOKUP_SESSION_ID;
12400       else
12401         break;
12402     }
12403
12404   if (key == (u8) ~ 0)
12405     {
12406       errmsg ("l2tp session lookup key unset");
12407       return -99;
12408     }
12409
12410   M (L2TPV3_SET_LOOKUP_KEY, mp);
12411
12412   mp->key = key;
12413
12414   S (mp);
12415   W (ret);
12416   return ret;
12417 }
12418
12419 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12420   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12421 {
12422   vat_main_t *vam = &vat_main;
12423
12424   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12425          format_ip6_address, mp->our_address,
12426          format_ip6_address, mp->client_address,
12427          clib_net_to_host_u32 (mp->sw_if_index));
12428
12429   print (vam->ofp,
12430          "   local cookies %016llx %016llx remote cookie %016llx",
12431          clib_net_to_host_u64 (mp->local_cookie[0]),
12432          clib_net_to_host_u64 (mp->local_cookie[1]),
12433          clib_net_to_host_u64 (mp->remote_cookie));
12434
12435   print (vam->ofp, "   local session-id %d remote session-id %d",
12436          clib_net_to_host_u32 (mp->local_session_id),
12437          clib_net_to_host_u32 (mp->remote_session_id));
12438
12439   print (vam->ofp, "   l2 specific sublayer %s\n",
12440          mp->l2_sublayer_present ? "preset" : "absent");
12441
12442 }
12443
12444 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12445   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12446 {
12447   vat_main_t *vam = &vat_main;
12448   vat_json_node_t *node = NULL;
12449   struct in6_addr addr;
12450
12451   if (VAT_JSON_ARRAY != vam->json_tree.type)
12452     {
12453       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12454       vat_json_init_array (&vam->json_tree);
12455     }
12456   node = vat_json_array_add (&vam->json_tree);
12457
12458   vat_json_init_object (node);
12459
12460   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12461   vat_json_object_add_ip6 (node, "our_address", addr);
12462   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12463   vat_json_object_add_ip6 (node, "client_address", addr);
12464
12465   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12466   vat_json_init_array (lc);
12467   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12468   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12469   vat_json_object_add_uint (node, "remote_cookie",
12470                             clib_net_to_host_u64 (mp->remote_cookie));
12471
12472   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12473   vat_json_object_add_uint (node, "local_session_id",
12474                             clib_net_to_host_u32 (mp->local_session_id));
12475   vat_json_object_add_uint (node, "remote_session_id",
12476                             clib_net_to_host_u32 (mp->remote_session_id));
12477   vat_json_object_add_string_copy (node, "l2_sublayer",
12478                                    mp->l2_sublayer_present ? (u8 *) "present"
12479                                    : (u8 *) "absent");
12480 }
12481
12482 static int
12483 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12484 {
12485   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12486   vl_api_control_ping_t *mp_ping;
12487   int ret;
12488
12489   /* Get list of l2tpv3-tunnel interfaces */
12490   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12491   S (mp);
12492
12493   /* Use a control ping for synchronization */
12494   MPING (CONTROL_PING, mp_ping);
12495   S (mp_ping);
12496
12497   W (ret);
12498   return ret;
12499 }
12500
12501
12502 static void vl_api_sw_interface_tap_v2_details_t_handler
12503   (vl_api_sw_interface_tap_v2_details_t * mp)
12504 {
12505   vat_main_t *vam = &vat_main;
12506
12507   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12508                     mp->host_ip4_prefix_len);
12509   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12510                     mp->host_ip6_prefix_len);
12511
12512   print (vam->ofp,
12513          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12514          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12515          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12516          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12517          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12518
12519   vec_free (ip4);
12520   vec_free (ip6);
12521 }
12522
12523 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12524   (vl_api_sw_interface_tap_v2_details_t * mp)
12525 {
12526   vat_main_t *vam = &vat_main;
12527   vat_json_node_t *node = NULL;
12528
12529   if (VAT_JSON_ARRAY != vam->json_tree.type)
12530     {
12531       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12532       vat_json_init_array (&vam->json_tree);
12533     }
12534   node = vat_json_array_add (&vam->json_tree);
12535
12536   vat_json_init_object (node);
12537   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12538   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12539   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12540   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12541   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12542   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12543   vat_json_object_add_string_copy (node, "host_mac_addr",
12544                                    format (0, "%U", format_ethernet_address,
12545                                            &mp->host_mac_addr));
12546   vat_json_object_add_string_copy (node, "host_namespace",
12547                                    mp->host_namespace);
12548   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12549   vat_json_object_add_string_copy (node, "host_ip4_addr",
12550                                    format (0, "%U/%d", format_ip4_address,
12551                                            mp->host_ip4_addr,
12552                                            mp->host_ip4_prefix_len));
12553   vat_json_object_add_string_copy (node, "host_ip6_addr",
12554                                    format (0, "%U/%d", format_ip6_address,
12555                                            mp->host_ip6_addr,
12556                                            mp->host_ip6_prefix_len));
12557
12558 }
12559
12560 static int
12561 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12562 {
12563   vl_api_sw_interface_tap_v2_dump_t *mp;
12564   vl_api_control_ping_t *mp_ping;
12565   int ret;
12566
12567   print (vam->ofp,
12568          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12569          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12570          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12571          "host_ip6_addr");
12572
12573   /* Get list of tap interfaces */
12574   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12575   S (mp);
12576
12577   /* Use a control ping for synchronization */
12578   MPING (CONTROL_PING, mp_ping);
12579   S (mp_ping);
12580
12581   W (ret);
12582   return ret;
12583 }
12584
12585 static void vl_api_sw_interface_virtio_pci_details_t_handler
12586   (vl_api_sw_interface_virtio_pci_details_t * mp)
12587 {
12588   vat_main_t *vam = &vat_main;
12589
12590   typedef union
12591   {
12592     struct
12593     {
12594       u16 domain;
12595       u8 bus;
12596       u8 slot:5;
12597       u8 function:3;
12598     };
12599     u32 as_u32;
12600   } pci_addr_t;
12601   pci_addr_t addr;
12602   addr.as_u32 = ntohl (mp->pci_addr);
12603   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12604                          addr.slot, addr.function);
12605
12606   print (vam->ofp,
12607          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12608          pci_addr, ntohl (mp->sw_if_index),
12609          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12610          format_ethernet_address, mp->mac_addr,
12611          clib_net_to_host_u64 (mp->features));
12612   vec_free (pci_addr);
12613 }
12614
12615 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12616   (vl_api_sw_interface_virtio_pci_details_t * mp)
12617 {
12618   vat_main_t *vam = &vat_main;
12619   vat_json_node_t *node = NULL;
12620
12621   if (VAT_JSON_ARRAY != vam->json_tree.type)
12622     {
12623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12624       vat_json_init_array (&vam->json_tree);
12625     }
12626   node = vat_json_array_add (&vam->json_tree);
12627
12628   vat_json_init_object (node);
12629   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12630   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12631   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12632   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12633   vat_json_object_add_uint (node, "features",
12634                             clib_net_to_host_u64 (mp->features));
12635   vat_json_object_add_string_copy (node, "mac_addr",
12636                                    format (0, "%U", format_ethernet_address,
12637                                            &mp->mac_addr));
12638 }
12639
12640 static int
12641 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12642 {
12643   vl_api_sw_interface_virtio_pci_dump_t *mp;
12644   vl_api_control_ping_t *mp_ping;
12645   int ret;
12646
12647   print (vam->ofp,
12648          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12649          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12650          "mac_addr", "features");
12651
12652   /* Get list of tap interfaces */
12653   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12654   S (mp);
12655
12656   /* Use a control ping for synchronization */
12657   MPING (CONTROL_PING, mp_ping);
12658   S (mp_ping);
12659
12660   W (ret);
12661   return ret;
12662 }
12663
12664 static int
12665 api_vxlan_offload_rx (vat_main_t * vam)
12666 {
12667   unformat_input_t *line_input = vam->input;
12668   vl_api_vxlan_offload_rx_t *mp;
12669   u32 hw_if_index = ~0, rx_if_index = ~0;
12670   u8 is_add = 1;
12671   int ret;
12672
12673   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12674     {
12675       if (unformat (line_input, "del"))
12676         is_add = 0;
12677       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12678                          &hw_if_index))
12679         ;
12680       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12681         ;
12682       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12683                          &rx_if_index))
12684         ;
12685       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12686         ;
12687       else
12688         {
12689           errmsg ("parse error '%U'", format_unformat_error, line_input);
12690           return -99;
12691         }
12692     }
12693
12694   if (hw_if_index == ~0)
12695     {
12696       errmsg ("no hw interface");
12697       return -99;
12698     }
12699
12700   if (rx_if_index == ~0)
12701     {
12702       errmsg ("no rx tunnel");
12703       return -99;
12704     }
12705
12706   M (VXLAN_OFFLOAD_RX, mp);
12707
12708   mp->hw_if_index = ntohl (hw_if_index);
12709   mp->sw_if_index = ntohl (rx_if_index);
12710   mp->enable = is_add;
12711
12712   S (mp);
12713   W (ret);
12714   return ret;
12715 }
12716
12717 static uword unformat_vxlan_decap_next
12718   (unformat_input_t * input, va_list * args)
12719 {
12720   u32 *result = va_arg (*args, u32 *);
12721   u32 tmp;
12722
12723   if (unformat (input, "l2"))
12724     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12725   else if (unformat (input, "%d", &tmp))
12726     *result = tmp;
12727   else
12728     return 0;
12729   return 1;
12730 }
12731
12732 static int
12733 api_vxlan_add_del_tunnel (vat_main_t * vam)
12734 {
12735   unformat_input_t *line_input = vam->input;
12736   vl_api_vxlan_add_del_tunnel_t *mp;
12737   ip46_address_t src, dst;
12738   u8 is_add = 1;
12739   u8 ipv4_set = 0, ipv6_set = 0;
12740   u8 src_set = 0;
12741   u8 dst_set = 0;
12742   u8 grp_set = 0;
12743   u32 instance = ~0;
12744   u32 mcast_sw_if_index = ~0;
12745   u32 encap_vrf_id = 0;
12746   u32 decap_next_index = ~0;
12747   u32 vni = 0;
12748   int ret;
12749
12750   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12751   clib_memset (&src, 0, sizeof src);
12752   clib_memset (&dst, 0, sizeof dst);
12753
12754   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12755     {
12756       if (unformat (line_input, "del"))
12757         is_add = 0;
12758       else if (unformat (line_input, "instance %d", &instance))
12759         ;
12760       else
12761         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12762         {
12763           ipv4_set = 1;
12764           src_set = 1;
12765         }
12766       else
12767         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12768         {
12769           ipv4_set = 1;
12770           dst_set = 1;
12771         }
12772       else
12773         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12774         {
12775           ipv6_set = 1;
12776           src_set = 1;
12777         }
12778       else
12779         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12780         {
12781           ipv6_set = 1;
12782           dst_set = 1;
12783         }
12784       else if (unformat (line_input, "group %U %U",
12785                          unformat_ip4_address, &dst.ip4,
12786                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12787         {
12788           grp_set = dst_set = 1;
12789           ipv4_set = 1;
12790         }
12791       else if (unformat (line_input, "group %U",
12792                          unformat_ip4_address, &dst.ip4))
12793         {
12794           grp_set = dst_set = 1;
12795           ipv4_set = 1;
12796         }
12797       else if (unformat (line_input, "group %U %U",
12798                          unformat_ip6_address, &dst.ip6,
12799                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12800         {
12801           grp_set = dst_set = 1;
12802           ipv6_set = 1;
12803         }
12804       else if (unformat (line_input, "group %U",
12805                          unformat_ip6_address, &dst.ip6))
12806         {
12807           grp_set = dst_set = 1;
12808           ipv6_set = 1;
12809         }
12810       else
12811         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12812         ;
12813       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12814         ;
12815       else if (unformat (line_input, "decap-next %U",
12816                          unformat_vxlan_decap_next, &decap_next_index))
12817         ;
12818       else if (unformat (line_input, "vni %d", &vni))
12819         ;
12820       else
12821         {
12822           errmsg ("parse error '%U'", format_unformat_error, line_input);
12823           return -99;
12824         }
12825     }
12826
12827   if (src_set == 0)
12828     {
12829       errmsg ("tunnel src address not specified");
12830       return -99;
12831     }
12832   if (dst_set == 0)
12833     {
12834       errmsg ("tunnel dst address not specified");
12835       return -99;
12836     }
12837
12838   if (grp_set && !ip46_address_is_multicast (&dst))
12839     {
12840       errmsg ("tunnel group address not multicast");
12841       return -99;
12842     }
12843   if (grp_set && mcast_sw_if_index == ~0)
12844     {
12845       errmsg ("tunnel nonexistent multicast device");
12846       return -99;
12847     }
12848   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12849     {
12850       errmsg ("tunnel dst address must be unicast");
12851       return -99;
12852     }
12853
12854
12855   if (ipv4_set && ipv6_set)
12856     {
12857       errmsg ("both IPv4 and IPv6 addresses specified");
12858       return -99;
12859     }
12860
12861   if ((vni == 0) || (vni >> 24))
12862     {
12863       errmsg ("vni not specified or out of range");
12864       return -99;
12865     }
12866
12867   M (VXLAN_ADD_DEL_TUNNEL, mp);
12868
12869   if (ipv6_set)
12870     {
12871       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12872       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12873     }
12874   else
12875     {
12876       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12877       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12878     }
12879
12880   mp->instance = htonl (instance);
12881   mp->encap_vrf_id = ntohl (encap_vrf_id);
12882   mp->decap_next_index = ntohl (decap_next_index);
12883   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12884   mp->vni = ntohl (vni);
12885   mp->is_add = is_add;
12886   mp->is_ipv6 = ipv6_set;
12887
12888   S (mp);
12889   W (ret);
12890   return ret;
12891 }
12892
12893 static void vl_api_vxlan_tunnel_details_t_handler
12894   (vl_api_vxlan_tunnel_details_t * mp)
12895 {
12896   vat_main_t *vam = &vat_main;
12897   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12898   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12899
12900   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12901          ntohl (mp->sw_if_index),
12902          ntohl (mp->instance),
12903          format_ip46_address, &src, IP46_TYPE_ANY,
12904          format_ip46_address, &dst, IP46_TYPE_ANY,
12905          ntohl (mp->encap_vrf_id),
12906          ntohl (mp->decap_next_index), ntohl (mp->vni),
12907          ntohl (mp->mcast_sw_if_index));
12908 }
12909
12910 static void vl_api_vxlan_tunnel_details_t_handler_json
12911   (vl_api_vxlan_tunnel_details_t * mp)
12912 {
12913   vat_main_t *vam = &vat_main;
12914   vat_json_node_t *node = NULL;
12915
12916   if (VAT_JSON_ARRAY != vam->json_tree.type)
12917     {
12918       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12919       vat_json_init_array (&vam->json_tree);
12920     }
12921   node = vat_json_array_add (&vam->json_tree);
12922
12923   vat_json_init_object (node);
12924   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12925
12926   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12927
12928   if (mp->is_ipv6)
12929     {
12930       struct in6_addr ip6;
12931
12932       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12933       vat_json_object_add_ip6 (node, "src_address", ip6);
12934       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12935       vat_json_object_add_ip6 (node, "dst_address", ip6);
12936     }
12937   else
12938     {
12939       struct in_addr ip4;
12940
12941       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12942       vat_json_object_add_ip4 (node, "src_address", ip4);
12943       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12944       vat_json_object_add_ip4 (node, "dst_address", ip4);
12945     }
12946   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12947   vat_json_object_add_uint (node, "decap_next_index",
12948                             ntohl (mp->decap_next_index));
12949   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12950   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12951   vat_json_object_add_uint (node, "mcast_sw_if_index",
12952                             ntohl (mp->mcast_sw_if_index));
12953 }
12954
12955 static int
12956 api_vxlan_tunnel_dump (vat_main_t * vam)
12957 {
12958   unformat_input_t *i = vam->input;
12959   vl_api_vxlan_tunnel_dump_t *mp;
12960   vl_api_control_ping_t *mp_ping;
12961   u32 sw_if_index;
12962   u8 sw_if_index_set = 0;
12963   int ret;
12964
12965   /* Parse args required to build the message */
12966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12967     {
12968       if (unformat (i, "sw_if_index %d", &sw_if_index))
12969         sw_if_index_set = 1;
12970       else
12971         break;
12972     }
12973
12974   if (sw_if_index_set == 0)
12975     {
12976       sw_if_index = ~0;
12977     }
12978
12979   if (!vam->json_output)
12980     {
12981       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12982              "sw_if_index", "instance", "src_address", "dst_address",
12983              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12984     }
12985
12986   /* Get list of vxlan-tunnel interfaces */
12987   M (VXLAN_TUNNEL_DUMP, mp);
12988
12989   mp->sw_if_index = htonl (sw_if_index);
12990
12991   S (mp);
12992
12993   /* Use a control ping for synchronization */
12994   MPING (CONTROL_PING, mp_ping);
12995   S (mp_ping);
12996
12997   W (ret);
12998   return ret;
12999 }
13000
13001 static uword unformat_geneve_decap_next
13002   (unformat_input_t * input, va_list * args)
13003 {
13004   u32 *result = va_arg (*args, u32 *);
13005   u32 tmp;
13006
13007   if (unformat (input, "l2"))
13008     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13009   else if (unformat (input, "%d", &tmp))
13010     *result = tmp;
13011   else
13012     return 0;
13013   return 1;
13014 }
13015
13016 static int
13017 api_geneve_add_del_tunnel (vat_main_t * vam)
13018 {
13019   unformat_input_t *line_input = vam->input;
13020   vl_api_geneve_add_del_tunnel_t *mp;
13021   ip46_address_t src, dst;
13022   u8 is_add = 1;
13023   u8 ipv4_set = 0, ipv6_set = 0;
13024   u8 src_set = 0;
13025   u8 dst_set = 0;
13026   u8 grp_set = 0;
13027   u32 mcast_sw_if_index = ~0;
13028   u32 encap_vrf_id = 0;
13029   u32 decap_next_index = ~0;
13030   u32 vni = 0;
13031   int ret;
13032
13033   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13034   clib_memset (&src, 0, sizeof src);
13035   clib_memset (&dst, 0, sizeof dst);
13036
13037   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13038     {
13039       if (unformat (line_input, "del"))
13040         is_add = 0;
13041       else
13042         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13043         {
13044           ipv4_set = 1;
13045           src_set = 1;
13046         }
13047       else
13048         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13049         {
13050           ipv4_set = 1;
13051           dst_set = 1;
13052         }
13053       else
13054         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13055         {
13056           ipv6_set = 1;
13057           src_set = 1;
13058         }
13059       else
13060         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13061         {
13062           ipv6_set = 1;
13063           dst_set = 1;
13064         }
13065       else if (unformat (line_input, "group %U %U",
13066                          unformat_ip4_address, &dst.ip4,
13067                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13068         {
13069           grp_set = dst_set = 1;
13070           ipv4_set = 1;
13071         }
13072       else if (unformat (line_input, "group %U",
13073                          unformat_ip4_address, &dst.ip4))
13074         {
13075           grp_set = dst_set = 1;
13076           ipv4_set = 1;
13077         }
13078       else if (unformat (line_input, "group %U %U",
13079                          unformat_ip6_address, &dst.ip6,
13080                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13081         {
13082           grp_set = dst_set = 1;
13083           ipv6_set = 1;
13084         }
13085       else if (unformat (line_input, "group %U",
13086                          unformat_ip6_address, &dst.ip6))
13087         {
13088           grp_set = dst_set = 1;
13089           ipv6_set = 1;
13090         }
13091       else
13092         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13093         ;
13094       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13095         ;
13096       else if (unformat (line_input, "decap-next %U",
13097                          unformat_geneve_decap_next, &decap_next_index))
13098         ;
13099       else if (unformat (line_input, "vni %d", &vni))
13100         ;
13101       else
13102         {
13103           errmsg ("parse error '%U'", format_unformat_error, line_input);
13104           return -99;
13105         }
13106     }
13107
13108   if (src_set == 0)
13109     {
13110       errmsg ("tunnel src address not specified");
13111       return -99;
13112     }
13113   if (dst_set == 0)
13114     {
13115       errmsg ("tunnel dst address not specified");
13116       return -99;
13117     }
13118
13119   if (grp_set && !ip46_address_is_multicast (&dst))
13120     {
13121       errmsg ("tunnel group address not multicast");
13122       return -99;
13123     }
13124   if (grp_set && mcast_sw_if_index == ~0)
13125     {
13126       errmsg ("tunnel nonexistent multicast device");
13127       return -99;
13128     }
13129   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13130     {
13131       errmsg ("tunnel dst address must be unicast");
13132       return -99;
13133     }
13134
13135
13136   if (ipv4_set && ipv6_set)
13137     {
13138       errmsg ("both IPv4 and IPv6 addresses specified");
13139       return -99;
13140     }
13141
13142   if ((vni == 0) || (vni >> 24))
13143     {
13144       errmsg ("vni not specified or out of range");
13145       return -99;
13146     }
13147
13148   M (GENEVE_ADD_DEL_TUNNEL, mp);
13149
13150   if (ipv6_set)
13151     {
13152       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13153       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13154     }
13155   else
13156     {
13157       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13158       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13159     }
13160   mp->encap_vrf_id = ntohl (encap_vrf_id);
13161   mp->decap_next_index = ntohl (decap_next_index);
13162   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13163   mp->vni = ntohl (vni);
13164   mp->is_add = is_add;
13165   mp->is_ipv6 = ipv6_set;
13166
13167   S (mp);
13168   W (ret);
13169   return ret;
13170 }
13171
13172 static void vl_api_geneve_tunnel_details_t_handler
13173   (vl_api_geneve_tunnel_details_t * mp)
13174 {
13175   vat_main_t *vam = &vat_main;
13176   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13177   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13178
13179   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13180          ntohl (mp->sw_if_index),
13181          format_ip46_address, &src, IP46_TYPE_ANY,
13182          format_ip46_address, &dst, IP46_TYPE_ANY,
13183          ntohl (mp->encap_vrf_id),
13184          ntohl (mp->decap_next_index), ntohl (mp->vni),
13185          ntohl (mp->mcast_sw_if_index));
13186 }
13187
13188 static void vl_api_geneve_tunnel_details_t_handler_json
13189   (vl_api_geneve_tunnel_details_t * mp)
13190 {
13191   vat_main_t *vam = &vat_main;
13192   vat_json_node_t *node = NULL;
13193
13194   if (VAT_JSON_ARRAY != vam->json_tree.type)
13195     {
13196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13197       vat_json_init_array (&vam->json_tree);
13198     }
13199   node = vat_json_array_add (&vam->json_tree);
13200
13201   vat_json_init_object (node);
13202   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13203   if (mp->is_ipv6)
13204     {
13205       struct in6_addr ip6;
13206
13207       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13208       vat_json_object_add_ip6 (node, "src_address", ip6);
13209       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13210       vat_json_object_add_ip6 (node, "dst_address", ip6);
13211     }
13212   else
13213     {
13214       struct in_addr ip4;
13215
13216       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13217       vat_json_object_add_ip4 (node, "src_address", ip4);
13218       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13219       vat_json_object_add_ip4 (node, "dst_address", ip4);
13220     }
13221   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13222   vat_json_object_add_uint (node, "decap_next_index",
13223                             ntohl (mp->decap_next_index));
13224   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13225   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13226   vat_json_object_add_uint (node, "mcast_sw_if_index",
13227                             ntohl (mp->mcast_sw_if_index));
13228 }
13229
13230 static int
13231 api_geneve_tunnel_dump (vat_main_t * vam)
13232 {
13233   unformat_input_t *i = vam->input;
13234   vl_api_geneve_tunnel_dump_t *mp;
13235   vl_api_control_ping_t *mp_ping;
13236   u32 sw_if_index;
13237   u8 sw_if_index_set = 0;
13238   int ret;
13239
13240   /* Parse args required to build the message */
13241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13242     {
13243       if (unformat (i, "sw_if_index %d", &sw_if_index))
13244         sw_if_index_set = 1;
13245       else
13246         break;
13247     }
13248
13249   if (sw_if_index_set == 0)
13250     {
13251       sw_if_index = ~0;
13252     }
13253
13254   if (!vam->json_output)
13255     {
13256       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13257              "sw_if_index", "local_address", "remote_address",
13258              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13259     }
13260
13261   /* Get list of geneve-tunnel interfaces */
13262   M (GENEVE_TUNNEL_DUMP, mp);
13263
13264   mp->sw_if_index = htonl (sw_if_index);
13265
13266   S (mp);
13267
13268   /* Use a control ping for synchronization */
13269   M (CONTROL_PING, mp_ping);
13270   S (mp_ping);
13271
13272   W (ret);
13273   return ret;
13274 }
13275
13276 static int
13277 api_gre_add_del_tunnel (vat_main_t * vam)
13278 {
13279   unformat_input_t *line_input = vam->input;
13280   vl_api_gre_add_del_tunnel_t *mp;
13281   ip4_address_t src4, dst4;
13282   ip6_address_t src6, dst6;
13283   u8 is_add = 1;
13284   u8 ipv4_set = 0;
13285   u8 ipv6_set = 0;
13286   u8 t_type = GRE_TUNNEL_TYPE_L3;
13287   u8 src_set = 0;
13288   u8 dst_set = 0;
13289   u32 outer_fib_id = 0;
13290   u32 session_id = 0;
13291   u32 instance = ~0;
13292   int ret;
13293
13294   clib_memset (&src4, 0, sizeof src4);
13295   clib_memset (&dst4, 0, sizeof dst4);
13296   clib_memset (&src6, 0, sizeof src6);
13297   clib_memset (&dst6, 0, sizeof dst6);
13298
13299   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13300     {
13301       if (unformat (line_input, "del"))
13302         is_add = 0;
13303       else if (unformat (line_input, "instance %d", &instance))
13304         ;
13305       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13306         {
13307           src_set = 1;
13308           ipv4_set = 1;
13309         }
13310       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13311         {
13312           dst_set = 1;
13313           ipv4_set = 1;
13314         }
13315       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13316         {
13317           src_set = 1;
13318           ipv6_set = 1;
13319         }
13320       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13321         {
13322           dst_set = 1;
13323           ipv6_set = 1;
13324         }
13325       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13326         ;
13327       else if (unformat (line_input, "teb"))
13328         t_type = GRE_TUNNEL_TYPE_TEB;
13329       else if (unformat (line_input, "erspan %d", &session_id))
13330         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13331       else
13332         {
13333           errmsg ("parse error '%U'", format_unformat_error, line_input);
13334           return -99;
13335         }
13336     }
13337
13338   if (src_set == 0)
13339     {
13340       errmsg ("tunnel src address not specified");
13341       return -99;
13342     }
13343   if (dst_set == 0)
13344     {
13345       errmsg ("tunnel dst address not specified");
13346       return -99;
13347     }
13348   if (ipv4_set && ipv6_set)
13349     {
13350       errmsg ("both IPv4 and IPv6 addresses specified");
13351       return -99;
13352     }
13353
13354
13355   M (GRE_ADD_DEL_TUNNEL, mp);
13356
13357   if (ipv4_set)
13358     {
13359       clib_memcpy (&mp->src_address, &src4, 4);
13360       clib_memcpy (&mp->dst_address, &dst4, 4);
13361     }
13362   else
13363     {
13364       clib_memcpy (&mp->src_address, &src6, 16);
13365       clib_memcpy (&mp->dst_address, &dst6, 16);
13366     }
13367   mp->instance = htonl (instance);
13368   mp->outer_fib_id = htonl (outer_fib_id);
13369   mp->is_add = is_add;
13370   mp->session_id = htons ((u16) session_id);
13371   mp->tunnel_type = t_type;
13372   mp->is_ipv6 = ipv6_set;
13373
13374   S (mp);
13375   W (ret);
13376   return ret;
13377 }
13378
13379 static void vl_api_gre_tunnel_details_t_handler
13380   (vl_api_gre_tunnel_details_t * mp)
13381 {
13382   vat_main_t *vam = &vat_main;
13383   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13384   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13385
13386   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13387          ntohl (mp->sw_if_index),
13388          ntohl (mp->instance),
13389          format_ip46_address, &src, IP46_TYPE_ANY,
13390          format_ip46_address, &dst, IP46_TYPE_ANY,
13391          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13392 }
13393
13394 static void vl_api_gre_tunnel_details_t_handler_json
13395   (vl_api_gre_tunnel_details_t * mp)
13396 {
13397   vat_main_t *vam = &vat_main;
13398   vat_json_node_t *node = NULL;
13399   struct in_addr ip4;
13400   struct in6_addr ip6;
13401
13402   if (VAT_JSON_ARRAY != vam->json_tree.type)
13403     {
13404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13405       vat_json_init_array (&vam->json_tree);
13406     }
13407   node = vat_json_array_add (&vam->json_tree);
13408
13409   vat_json_init_object (node);
13410   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13411   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13412   if (!mp->is_ipv6)
13413     {
13414       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13415       vat_json_object_add_ip4 (node, "src_address", ip4);
13416       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13417       vat_json_object_add_ip4 (node, "dst_address", ip4);
13418     }
13419   else
13420     {
13421       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13422       vat_json_object_add_ip6 (node, "src_address", ip6);
13423       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13424       vat_json_object_add_ip6 (node, "dst_address", ip6);
13425     }
13426   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13427   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13428   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13429   vat_json_object_add_uint (node, "session_id", mp->session_id);
13430 }
13431
13432 static int
13433 api_gre_tunnel_dump (vat_main_t * vam)
13434 {
13435   unformat_input_t *i = vam->input;
13436   vl_api_gre_tunnel_dump_t *mp;
13437   vl_api_control_ping_t *mp_ping;
13438   u32 sw_if_index;
13439   u8 sw_if_index_set = 0;
13440   int ret;
13441
13442   /* Parse args required to build the message */
13443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13444     {
13445       if (unformat (i, "sw_if_index %d", &sw_if_index))
13446         sw_if_index_set = 1;
13447       else
13448         break;
13449     }
13450
13451   if (sw_if_index_set == 0)
13452     {
13453       sw_if_index = ~0;
13454     }
13455
13456   if (!vam->json_output)
13457     {
13458       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13459              "sw_if_index", "instance", "src_address", "dst_address",
13460              "tunnel_type", "outer_fib_id", "session_id");
13461     }
13462
13463   /* Get list of gre-tunnel interfaces */
13464   M (GRE_TUNNEL_DUMP, mp);
13465
13466   mp->sw_if_index = htonl (sw_if_index);
13467
13468   S (mp);
13469
13470   /* Use a control ping for synchronization */
13471   MPING (CONTROL_PING, mp_ping);
13472   S (mp_ping);
13473
13474   W (ret);
13475   return ret;
13476 }
13477
13478 static int
13479 api_l2_fib_clear_table (vat_main_t * vam)
13480 {
13481 //  unformat_input_t * i = vam->input;
13482   vl_api_l2_fib_clear_table_t *mp;
13483   int ret;
13484
13485   M (L2_FIB_CLEAR_TABLE, mp);
13486
13487   S (mp);
13488   W (ret);
13489   return ret;
13490 }
13491
13492 static int
13493 api_l2_interface_efp_filter (vat_main_t * vam)
13494 {
13495   unformat_input_t *i = vam->input;
13496   vl_api_l2_interface_efp_filter_t *mp;
13497   u32 sw_if_index;
13498   u8 enable = 1;
13499   u8 sw_if_index_set = 0;
13500   int ret;
13501
13502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13503     {
13504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13505         sw_if_index_set = 1;
13506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13507         sw_if_index_set = 1;
13508       else if (unformat (i, "enable"))
13509         enable = 1;
13510       else if (unformat (i, "disable"))
13511         enable = 0;
13512       else
13513         {
13514           clib_warning ("parse error '%U'", format_unformat_error, i);
13515           return -99;
13516         }
13517     }
13518
13519   if (sw_if_index_set == 0)
13520     {
13521       errmsg ("missing sw_if_index");
13522       return -99;
13523     }
13524
13525   M (L2_INTERFACE_EFP_FILTER, mp);
13526
13527   mp->sw_if_index = ntohl (sw_if_index);
13528   mp->enable_disable = enable;
13529
13530   S (mp);
13531   W (ret);
13532   return ret;
13533 }
13534
13535 #define foreach_vtr_op                          \
13536 _("disable",  L2_VTR_DISABLED)                  \
13537 _("push-1",  L2_VTR_PUSH_1)                     \
13538 _("push-2",  L2_VTR_PUSH_2)                     \
13539 _("pop-1",  L2_VTR_POP_1)                       \
13540 _("pop-2",  L2_VTR_POP_2)                       \
13541 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13542 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13543 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13544 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13545
13546 static int
13547 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13548 {
13549   unformat_input_t *i = vam->input;
13550   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13551   u32 sw_if_index;
13552   u8 sw_if_index_set = 0;
13553   u8 vtr_op_set = 0;
13554   u32 vtr_op = 0;
13555   u32 push_dot1q = 1;
13556   u32 tag1 = ~0;
13557   u32 tag2 = ~0;
13558   int ret;
13559
13560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13561     {
13562       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13563         sw_if_index_set = 1;
13564       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13565         sw_if_index_set = 1;
13566       else if (unformat (i, "vtr_op %d", &vtr_op))
13567         vtr_op_set = 1;
13568 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13569       foreach_vtr_op
13570 #undef _
13571         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13572         ;
13573       else if (unformat (i, "tag1 %d", &tag1))
13574         ;
13575       else if (unformat (i, "tag2 %d", &tag2))
13576         ;
13577       else
13578         {
13579           clib_warning ("parse error '%U'", format_unformat_error, i);
13580           return -99;
13581         }
13582     }
13583
13584   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13585     {
13586       errmsg ("missing vtr operation or sw_if_index");
13587       return -99;
13588     }
13589
13590   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13591   mp->sw_if_index = ntohl (sw_if_index);
13592   mp->vtr_op = ntohl (vtr_op);
13593   mp->push_dot1q = ntohl (push_dot1q);
13594   mp->tag1 = ntohl (tag1);
13595   mp->tag2 = ntohl (tag2);
13596
13597   S (mp);
13598   W (ret);
13599   return ret;
13600 }
13601
13602 static int
13603 api_create_vhost_user_if (vat_main_t * vam)
13604 {
13605   unformat_input_t *i = vam->input;
13606   vl_api_create_vhost_user_if_t *mp;
13607   u8 *file_name;
13608   u8 is_server = 0;
13609   u8 file_name_set = 0;
13610   u32 custom_dev_instance = ~0;
13611   u8 hwaddr[6];
13612   u8 use_custom_mac = 0;
13613   u8 disable_mrg_rxbuf = 0;
13614   u8 disable_indirect_desc = 0;
13615   u8 *tag = 0;
13616   int ret;
13617
13618   /* Shut up coverity */
13619   clib_memset (hwaddr, 0, sizeof (hwaddr));
13620
13621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13622     {
13623       if (unformat (i, "socket %s", &file_name))
13624         {
13625           file_name_set = 1;
13626         }
13627       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13628         ;
13629       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13630         use_custom_mac = 1;
13631       else if (unformat (i, "server"))
13632         is_server = 1;
13633       else if (unformat (i, "disable_mrg_rxbuf"))
13634         disable_mrg_rxbuf = 1;
13635       else if (unformat (i, "disable_indirect_desc"))
13636         disable_indirect_desc = 1;
13637       else if (unformat (i, "tag %s", &tag))
13638         ;
13639       else
13640         break;
13641     }
13642
13643   if (file_name_set == 0)
13644     {
13645       errmsg ("missing socket file name");
13646       return -99;
13647     }
13648
13649   if (vec_len (file_name) > 255)
13650     {
13651       errmsg ("socket file name too long");
13652       return -99;
13653     }
13654   vec_add1 (file_name, 0);
13655
13656   M (CREATE_VHOST_USER_IF, mp);
13657
13658   mp->is_server = is_server;
13659   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13660   mp->disable_indirect_desc = disable_indirect_desc;
13661   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13662   vec_free (file_name);
13663   if (custom_dev_instance != ~0)
13664     {
13665       mp->renumber = 1;
13666       mp->custom_dev_instance = ntohl (custom_dev_instance);
13667     }
13668
13669   mp->use_custom_mac = use_custom_mac;
13670   clib_memcpy (mp->mac_address, hwaddr, 6);
13671   if (tag)
13672     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13673   vec_free (tag);
13674
13675   S (mp);
13676   W (ret);
13677   return ret;
13678 }
13679
13680 static int
13681 api_modify_vhost_user_if (vat_main_t * vam)
13682 {
13683   unformat_input_t *i = vam->input;
13684   vl_api_modify_vhost_user_if_t *mp;
13685   u8 *file_name;
13686   u8 is_server = 0;
13687   u8 file_name_set = 0;
13688   u32 custom_dev_instance = ~0;
13689   u8 sw_if_index_set = 0;
13690   u32 sw_if_index = (u32) ~ 0;
13691   int ret;
13692
13693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13694     {
13695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13696         sw_if_index_set = 1;
13697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13698         sw_if_index_set = 1;
13699       else if (unformat (i, "socket %s", &file_name))
13700         {
13701           file_name_set = 1;
13702         }
13703       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13704         ;
13705       else if (unformat (i, "server"))
13706         is_server = 1;
13707       else
13708         break;
13709     }
13710
13711   if (sw_if_index_set == 0)
13712     {
13713       errmsg ("missing sw_if_index or interface name");
13714       return -99;
13715     }
13716
13717   if (file_name_set == 0)
13718     {
13719       errmsg ("missing socket file name");
13720       return -99;
13721     }
13722
13723   if (vec_len (file_name) > 255)
13724     {
13725       errmsg ("socket file name too long");
13726       return -99;
13727     }
13728   vec_add1 (file_name, 0);
13729
13730   M (MODIFY_VHOST_USER_IF, mp);
13731
13732   mp->sw_if_index = ntohl (sw_if_index);
13733   mp->is_server = is_server;
13734   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13735   vec_free (file_name);
13736   if (custom_dev_instance != ~0)
13737     {
13738       mp->renumber = 1;
13739       mp->custom_dev_instance = ntohl (custom_dev_instance);
13740     }
13741
13742   S (mp);
13743   W (ret);
13744   return ret;
13745 }
13746
13747 static int
13748 api_delete_vhost_user_if (vat_main_t * vam)
13749 {
13750   unformat_input_t *i = vam->input;
13751   vl_api_delete_vhost_user_if_t *mp;
13752   u32 sw_if_index = ~0;
13753   u8 sw_if_index_set = 0;
13754   int ret;
13755
13756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13757     {
13758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13759         sw_if_index_set = 1;
13760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13761         sw_if_index_set = 1;
13762       else
13763         break;
13764     }
13765
13766   if (sw_if_index_set == 0)
13767     {
13768       errmsg ("missing sw_if_index or interface name");
13769       return -99;
13770     }
13771
13772
13773   M (DELETE_VHOST_USER_IF, mp);
13774
13775   mp->sw_if_index = ntohl (sw_if_index);
13776
13777   S (mp);
13778   W (ret);
13779   return ret;
13780 }
13781
13782 static void vl_api_sw_interface_vhost_user_details_t_handler
13783   (vl_api_sw_interface_vhost_user_details_t * mp)
13784 {
13785   vat_main_t *vam = &vat_main;
13786
13787   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13788          (char *) mp->interface_name,
13789          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13790          clib_net_to_host_u64 (mp->features), mp->is_server,
13791          ntohl (mp->num_regions), (char *) mp->sock_filename);
13792   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13793 }
13794
13795 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13796   (vl_api_sw_interface_vhost_user_details_t * mp)
13797 {
13798   vat_main_t *vam = &vat_main;
13799   vat_json_node_t *node = NULL;
13800
13801   if (VAT_JSON_ARRAY != vam->json_tree.type)
13802     {
13803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13804       vat_json_init_array (&vam->json_tree);
13805     }
13806   node = vat_json_array_add (&vam->json_tree);
13807
13808   vat_json_init_object (node);
13809   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13810   vat_json_object_add_string_copy (node, "interface_name",
13811                                    mp->interface_name);
13812   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13813                             ntohl (mp->virtio_net_hdr_sz));
13814   vat_json_object_add_uint (node, "features",
13815                             clib_net_to_host_u64 (mp->features));
13816   vat_json_object_add_uint (node, "is_server", mp->is_server);
13817   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13818   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13819   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13820 }
13821
13822 static int
13823 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13824 {
13825   vl_api_sw_interface_vhost_user_dump_t *mp;
13826   vl_api_control_ping_t *mp_ping;
13827   int ret;
13828   print (vam->ofp,
13829          "Interface name            idx hdr_sz features server regions filename");
13830
13831   /* Get list of vhost-user interfaces */
13832   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13833   S (mp);
13834
13835   /* Use a control ping for synchronization */
13836   MPING (CONTROL_PING, mp_ping);
13837   S (mp_ping);
13838
13839   W (ret);
13840   return ret;
13841 }
13842
13843 static int
13844 api_show_version (vat_main_t * vam)
13845 {
13846   vl_api_show_version_t *mp;
13847   int ret;
13848
13849   M (SHOW_VERSION, mp);
13850
13851   S (mp);
13852   W (ret);
13853   return ret;
13854 }
13855
13856
13857 static int
13858 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13859 {
13860   unformat_input_t *line_input = vam->input;
13861   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13862   ip4_address_t local4, remote4;
13863   ip6_address_t local6, remote6;
13864   u8 is_add = 1;
13865   u8 ipv4_set = 0, ipv6_set = 0;
13866   u8 local_set = 0;
13867   u8 remote_set = 0;
13868   u8 grp_set = 0;
13869   u32 mcast_sw_if_index = ~0;
13870   u32 encap_vrf_id = 0;
13871   u32 decap_vrf_id = 0;
13872   u8 protocol = ~0;
13873   u32 vni;
13874   u8 vni_set = 0;
13875   int ret;
13876
13877   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13878   clib_memset (&local4, 0, sizeof local4);
13879   clib_memset (&remote4, 0, sizeof remote4);
13880   clib_memset (&local6, 0, sizeof local6);
13881   clib_memset (&remote6, 0, sizeof remote6);
13882
13883   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13884     {
13885       if (unformat (line_input, "del"))
13886         is_add = 0;
13887       else if (unformat (line_input, "local %U",
13888                          unformat_ip4_address, &local4))
13889         {
13890           local_set = 1;
13891           ipv4_set = 1;
13892         }
13893       else if (unformat (line_input, "remote %U",
13894                          unformat_ip4_address, &remote4))
13895         {
13896           remote_set = 1;
13897           ipv4_set = 1;
13898         }
13899       else if (unformat (line_input, "local %U",
13900                          unformat_ip6_address, &local6))
13901         {
13902           local_set = 1;
13903           ipv6_set = 1;
13904         }
13905       else if (unformat (line_input, "remote %U",
13906                          unformat_ip6_address, &remote6))
13907         {
13908           remote_set = 1;
13909           ipv6_set = 1;
13910         }
13911       else if (unformat (line_input, "group %U %U",
13912                          unformat_ip4_address, &remote4,
13913                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13914         {
13915           grp_set = remote_set = 1;
13916           ipv4_set = 1;
13917         }
13918       else if (unformat (line_input, "group %U",
13919                          unformat_ip4_address, &remote4))
13920         {
13921           grp_set = remote_set = 1;
13922           ipv4_set = 1;
13923         }
13924       else if (unformat (line_input, "group %U %U",
13925                          unformat_ip6_address, &remote6,
13926                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13927         {
13928           grp_set = remote_set = 1;
13929           ipv6_set = 1;
13930         }
13931       else if (unformat (line_input, "group %U",
13932                          unformat_ip6_address, &remote6))
13933         {
13934           grp_set = remote_set = 1;
13935           ipv6_set = 1;
13936         }
13937       else
13938         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13939         ;
13940       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13941         ;
13942       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13943         ;
13944       else if (unformat (line_input, "vni %d", &vni))
13945         vni_set = 1;
13946       else if (unformat (line_input, "next-ip4"))
13947         protocol = 1;
13948       else if (unformat (line_input, "next-ip6"))
13949         protocol = 2;
13950       else if (unformat (line_input, "next-ethernet"))
13951         protocol = 3;
13952       else if (unformat (line_input, "next-nsh"))
13953         protocol = 4;
13954       else
13955         {
13956           errmsg ("parse error '%U'", format_unformat_error, line_input);
13957           return -99;
13958         }
13959     }
13960
13961   if (local_set == 0)
13962     {
13963       errmsg ("tunnel local address not specified");
13964       return -99;
13965     }
13966   if (remote_set == 0)
13967     {
13968       errmsg ("tunnel remote address not specified");
13969       return -99;
13970     }
13971   if (grp_set && mcast_sw_if_index == ~0)
13972     {
13973       errmsg ("tunnel nonexistent multicast device");
13974       return -99;
13975     }
13976   if (ipv4_set && ipv6_set)
13977     {
13978       errmsg ("both IPv4 and IPv6 addresses specified");
13979       return -99;
13980     }
13981
13982   if (vni_set == 0)
13983     {
13984       errmsg ("vni not specified");
13985       return -99;
13986     }
13987
13988   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13989
13990
13991   if (ipv6_set)
13992     {
13993       clib_memcpy (&mp->local, &local6, sizeof (local6));
13994       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13995     }
13996   else
13997     {
13998       clib_memcpy (&mp->local, &local4, sizeof (local4));
13999       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14000     }
14001
14002   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14003   mp->encap_vrf_id = ntohl (encap_vrf_id);
14004   mp->decap_vrf_id = ntohl (decap_vrf_id);
14005   mp->protocol = protocol;
14006   mp->vni = ntohl (vni);
14007   mp->is_add = is_add;
14008   mp->is_ipv6 = ipv6_set;
14009
14010   S (mp);
14011   W (ret);
14012   return ret;
14013 }
14014
14015 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14016   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14017 {
14018   vat_main_t *vam = &vat_main;
14019   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14020   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14021
14022   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14023          ntohl (mp->sw_if_index),
14024          format_ip46_address, &local, IP46_TYPE_ANY,
14025          format_ip46_address, &remote, IP46_TYPE_ANY,
14026          ntohl (mp->vni), mp->protocol,
14027          ntohl (mp->mcast_sw_if_index),
14028          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14029 }
14030
14031
14032 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14033   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14034 {
14035   vat_main_t *vam = &vat_main;
14036   vat_json_node_t *node = NULL;
14037   struct in_addr ip4;
14038   struct in6_addr ip6;
14039
14040   if (VAT_JSON_ARRAY != vam->json_tree.type)
14041     {
14042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14043       vat_json_init_array (&vam->json_tree);
14044     }
14045   node = vat_json_array_add (&vam->json_tree);
14046
14047   vat_json_init_object (node);
14048   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14049   if (mp->is_ipv6)
14050     {
14051       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14052       vat_json_object_add_ip6 (node, "local", ip6);
14053       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14054       vat_json_object_add_ip6 (node, "remote", ip6);
14055     }
14056   else
14057     {
14058       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14059       vat_json_object_add_ip4 (node, "local", ip4);
14060       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14061       vat_json_object_add_ip4 (node, "remote", ip4);
14062     }
14063   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14064   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14065   vat_json_object_add_uint (node, "mcast_sw_if_index",
14066                             ntohl (mp->mcast_sw_if_index));
14067   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14068   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14069   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14070 }
14071
14072 static int
14073 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14074 {
14075   unformat_input_t *i = vam->input;
14076   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14077   vl_api_control_ping_t *mp_ping;
14078   u32 sw_if_index;
14079   u8 sw_if_index_set = 0;
14080   int ret;
14081
14082   /* Parse args required to build the message */
14083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14084     {
14085       if (unformat (i, "sw_if_index %d", &sw_if_index))
14086         sw_if_index_set = 1;
14087       else
14088         break;
14089     }
14090
14091   if (sw_if_index_set == 0)
14092     {
14093       sw_if_index = ~0;
14094     }
14095
14096   if (!vam->json_output)
14097     {
14098       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14099              "sw_if_index", "local", "remote", "vni",
14100              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14101     }
14102
14103   /* Get list of vxlan-tunnel interfaces */
14104   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14105
14106   mp->sw_if_index = htonl (sw_if_index);
14107
14108   S (mp);
14109
14110   /* Use a control ping for synchronization */
14111   MPING (CONTROL_PING, mp_ping);
14112   S (mp_ping);
14113
14114   W (ret);
14115   return ret;
14116 }
14117
14118 static void vl_api_l2_fib_table_details_t_handler
14119   (vl_api_l2_fib_table_details_t * mp)
14120 {
14121   vat_main_t *vam = &vat_main;
14122
14123   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14124          "       %d       %d     %d",
14125          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14126          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14127          mp->bvi_mac);
14128 }
14129
14130 static void vl_api_l2_fib_table_details_t_handler_json
14131   (vl_api_l2_fib_table_details_t * mp)
14132 {
14133   vat_main_t *vam = &vat_main;
14134   vat_json_node_t *node = NULL;
14135
14136   if (VAT_JSON_ARRAY != vam->json_tree.type)
14137     {
14138       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14139       vat_json_init_array (&vam->json_tree);
14140     }
14141   node = vat_json_array_add (&vam->json_tree);
14142
14143   vat_json_init_object (node);
14144   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14145   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14146   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14147   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14148   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14149   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14150 }
14151
14152 static int
14153 api_l2_fib_table_dump (vat_main_t * vam)
14154 {
14155   unformat_input_t *i = vam->input;
14156   vl_api_l2_fib_table_dump_t *mp;
14157   vl_api_control_ping_t *mp_ping;
14158   u32 bd_id;
14159   u8 bd_id_set = 0;
14160   int ret;
14161
14162   /* Parse args required to build the message */
14163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14164     {
14165       if (unformat (i, "bd_id %d", &bd_id))
14166         bd_id_set = 1;
14167       else
14168         break;
14169     }
14170
14171   if (bd_id_set == 0)
14172     {
14173       errmsg ("missing bridge domain");
14174       return -99;
14175     }
14176
14177   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14178
14179   /* Get list of l2 fib entries */
14180   M (L2_FIB_TABLE_DUMP, mp);
14181
14182   mp->bd_id = ntohl (bd_id);
14183   S (mp);
14184
14185   /* Use a control ping for synchronization */
14186   MPING (CONTROL_PING, mp_ping);
14187   S (mp_ping);
14188
14189   W (ret);
14190   return ret;
14191 }
14192
14193
14194 static int
14195 api_interface_name_renumber (vat_main_t * vam)
14196 {
14197   unformat_input_t *line_input = vam->input;
14198   vl_api_interface_name_renumber_t *mp;
14199   u32 sw_if_index = ~0;
14200   u32 new_show_dev_instance = ~0;
14201   int ret;
14202
14203   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14204     {
14205       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14206                     &sw_if_index))
14207         ;
14208       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14209         ;
14210       else if (unformat (line_input, "new_show_dev_instance %d",
14211                          &new_show_dev_instance))
14212         ;
14213       else
14214         break;
14215     }
14216
14217   if (sw_if_index == ~0)
14218     {
14219       errmsg ("missing interface name or sw_if_index");
14220       return -99;
14221     }
14222
14223   if (new_show_dev_instance == ~0)
14224     {
14225       errmsg ("missing new_show_dev_instance");
14226       return -99;
14227     }
14228
14229   M (INTERFACE_NAME_RENUMBER, mp);
14230
14231   mp->sw_if_index = ntohl (sw_if_index);
14232   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14233
14234   S (mp);
14235   W (ret);
14236   return ret;
14237 }
14238
14239 static int
14240 api_ip_probe_neighbor (vat_main_t * vam)
14241 {
14242   unformat_input_t *i = vam->input;
14243   vl_api_ip_probe_neighbor_t *mp;
14244   vl_api_address_t dst_adr;
14245   u8 int_set = 0;
14246   u8 adr_set = 0;
14247   u32 sw_if_index;
14248   int ret;
14249
14250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14251     {
14252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14253         int_set = 1;
14254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14255         int_set = 1;
14256       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14257         adr_set = 1;
14258       else
14259         break;
14260     }
14261
14262   if (int_set == 0)
14263     {
14264       errmsg ("missing interface");
14265       return -99;
14266     }
14267
14268   if (adr_set == 0)
14269     {
14270       errmsg ("missing addresses");
14271       return -99;
14272     }
14273
14274   M (IP_PROBE_NEIGHBOR, mp);
14275
14276   mp->sw_if_index = ntohl (sw_if_index);
14277   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14278
14279   S (mp);
14280   W (ret);
14281   return ret;
14282 }
14283
14284 static int
14285 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14286 {
14287   unformat_input_t *i = vam->input;
14288   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14289   u8 mode = IP_SCAN_V46_NEIGHBORS;
14290   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14291   int ret;
14292
14293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14294     {
14295       if (unformat (i, "ip4"))
14296         mode = IP_SCAN_V4_NEIGHBORS;
14297       else if (unformat (i, "ip6"))
14298         mode = IP_SCAN_V6_NEIGHBORS;
14299       if (unformat (i, "both"))
14300         mode = IP_SCAN_V46_NEIGHBORS;
14301       else if (unformat (i, "disable"))
14302         mode = IP_SCAN_DISABLED;
14303       else if (unformat (i, "interval %d", &interval))
14304         ;
14305       else if (unformat (i, "max-time %d", &time))
14306         ;
14307       else if (unformat (i, "max-update %d", &update))
14308         ;
14309       else if (unformat (i, "delay %d", &delay))
14310         ;
14311       else if (unformat (i, "stale %d", &stale))
14312         ;
14313       else
14314         break;
14315     }
14316
14317   if (interval > 255)
14318     {
14319       errmsg ("interval cannot exceed 255 minutes.");
14320       return -99;
14321     }
14322   if (time > 255)
14323     {
14324       errmsg ("max-time cannot exceed 255 usec.");
14325       return -99;
14326     }
14327   if (update > 255)
14328     {
14329       errmsg ("max-update cannot exceed 255.");
14330       return -99;
14331     }
14332   if (delay > 255)
14333     {
14334       errmsg ("delay cannot exceed 255 msec.");
14335       return -99;
14336     }
14337   if (stale > 255)
14338     {
14339       errmsg ("stale cannot exceed 255 minutes.");
14340       return -99;
14341     }
14342
14343   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14344   mp->mode = mode;
14345   mp->scan_interval = interval;
14346   mp->max_proc_time = time;
14347   mp->max_update = update;
14348   mp->scan_int_delay = delay;
14349   mp->stale_threshold = stale;
14350
14351   S (mp);
14352   W (ret);
14353   return ret;
14354 }
14355
14356 static int
14357 api_want_ip4_arp_events (vat_main_t * vam)
14358 {
14359   unformat_input_t *line_input = vam->input;
14360   vl_api_want_ip4_arp_events_t *mp;
14361   ip4_address_t address;
14362   int address_set = 0;
14363   u32 enable_disable = 1;
14364   int ret;
14365
14366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14367     {
14368       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14369         address_set = 1;
14370       else if (unformat (line_input, "del"))
14371         enable_disable = 0;
14372       else
14373         break;
14374     }
14375
14376   if (address_set == 0)
14377     {
14378       errmsg ("missing addresses");
14379       return -99;
14380     }
14381
14382   M (WANT_IP4_ARP_EVENTS, mp);
14383   mp->enable_disable = enable_disable;
14384   mp->pid = htonl (getpid ());
14385   clib_memcpy (mp->ip, &address, sizeof (address));
14386
14387   S (mp);
14388   W (ret);
14389   return ret;
14390 }
14391
14392 static int
14393 api_want_ip6_nd_events (vat_main_t * vam)
14394 {
14395   unformat_input_t *line_input = vam->input;
14396   vl_api_want_ip6_nd_events_t *mp;
14397   vl_api_ip6_address_t address;
14398   int address_set = 0;
14399   u32 enable_disable = 1;
14400   int ret;
14401
14402   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14403     {
14404       if (unformat
14405           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14406         address_set = 1;
14407       else if (unformat (line_input, "del"))
14408         enable_disable = 0;
14409       else
14410         break;
14411     }
14412
14413   if (address_set == 0)
14414     {
14415       errmsg ("missing addresses");
14416       return -99;
14417     }
14418
14419   M (WANT_IP6_ND_EVENTS, mp);
14420   mp->enable_disable = enable_disable;
14421   mp->pid = htonl (getpid ());
14422   clib_memcpy (&mp->ip, &address, sizeof (address));
14423
14424   S (mp);
14425   W (ret);
14426   return ret;
14427 }
14428
14429 static int
14430 api_want_l2_macs_events (vat_main_t * vam)
14431 {
14432   unformat_input_t *line_input = vam->input;
14433   vl_api_want_l2_macs_events_t *mp;
14434   u8 enable_disable = 1;
14435   u32 scan_delay = 0;
14436   u32 max_macs_in_event = 0;
14437   u32 learn_limit = 0;
14438   int ret;
14439
14440   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14441     {
14442       if (unformat (line_input, "learn-limit %d", &learn_limit))
14443         ;
14444       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14445         ;
14446       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14447         ;
14448       else if (unformat (line_input, "disable"))
14449         enable_disable = 0;
14450       else
14451         break;
14452     }
14453
14454   M (WANT_L2_MACS_EVENTS, mp);
14455   mp->enable_disable = enable_disable;
14456   mp->pid = htonl (getpid ());
14457   mp->learn_limit = htonl (learn_limit);
14458   mp->scan_delay = (u8) scan_delay;
14459   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14460   S (mp);
14461   W (ret);
14462   return ret;
14463 }
14464
14465 static int
14466 api_input_acl_set_interface (vat_main_t * vam)
14467 {
14468   unformat_input_t *i = vam->input;
14469   vl_api_input_acl_set_interface_t *mp;
14470   u32 sw_if_index;
14471   int sw_if_index_set;
14472   u32 ip4_table_index = ~0;
14473   u32 ip6_table_index = ~0;
14474   u32 l2_table_index = ~0;
14475   u8 is_add = 1;
14476   int ret;
14477
14478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14479     {
14480       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14481         sw_if_index_set = 1;
14482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14483         sw_if_index_set = 1;
14484       else if (unformat (i, "del"))
14485         is_add = 0;
14486       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14487         ;
14488       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14489         ;
14490       else if (unformat (i, "l2-table %d", &l2_table_index))
14491         ;
14492       else
14493         {
14494           clib_warning ("parse error '%U'", format_unformat_error, i);
14495           return -99;
14496         }
14497     }
14498
14499   if (sw_if_index_set == 0)
14500     {
14501       errmsg ("missing interface name or sw_if_index");
14502       return -99;
14503     }
14504
14505   M (INPUT_ACL_SET_INTERFACE, mp);
14506
14507   mp->sw_if_index = ntohl (sw_if_index);
14508   mp->ip4_table_index = ntohl (ip4_table_index);
14509   mp->ip6_table_index = ntohl (ip6_table_index);
14510   mp->l2_table_index = ntohl (l2_table_index);
14511   mp->is_add = is_add;
14512
14513   S (mp);
14514   W (ret);
14515   return ret;
14516 }
14517
14518 static int
14519 api_output_acl_set_interface (vat_main_t * vam)
14520 {
14521   unformat_input_t *i = vam->input;
14522   vl_api_output_acl_set_interface_t *mp;
14523   u32 sw_if_index;
14524   int sw_if_index_set;
14525   u32 ip4_table_index = ~0;
14526   u32 ip6_table_index = ~0;
14527   u32 l2_table_index = ~0;
14528   u8 is_add = 1;
14529   int ret;
14530
14531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14532     {
14533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14534         sw_if_index_set = 1;
14535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14536         sw_if_index_set = 1;
14537       else if (unformat (i, "del"))
14538         is_add = 0;
14539       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14540         ;
14541       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14542         ;
14543       else if (unformat (i, "l2-table %d", &l2_table_index))
14544         ;
14545       else
14546         {
14547           clib_warning ("parse error '%U'", format_unformat_error, i);
14548           return -99;
14549         }
14550     }
14551
14552   if (sw_if_index_set == 0)
14553     {
14554       errmsg ("missing interface name or sw_if_index");
14555       return -99;
14556     }
14557
14558   M (OUTPUT_ACL_SET_INTERFACE, mp);
14559
14560   mp->sw_if_index = ntohl (sw_if_index);
14561   mp->ip4_table_index = ntohl (ip4_table_index);
14562   mp->ip6_table_index = ntohl (ip6_table_index);
14563   mp->l2_table_index = ntohl (l2_table_index);
14564   mp->is_add = is_add;
14565
14566   S (mp);
14567   W (ret);
14568   return ret;
14569 }
14570
14571 static int
14572 api_ip_address_dump (vat_main_t * vam)
14573 {
14574   unformat_input_t *i = vam->input;
14575   vl_api_ip_address_dump_t *mp;
14576   vl_api_control_ping_t *mp_ping;
14577   u32 sw_if_index = ~0;
14578   u8 sw_if_index_set = 0;
14579   u8 ipv4_set = 0;
14580   u8 ipv6_set = 0;
14581   int ret;
14582
14583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14584     {
14585       if (unformat (i, "sw_if_index %d", &sw_if_index))
14586         sw_if_index_set = 1;
14587       else
14588         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14589         sw_if_index_set = 1;
14590       else if (unformat (i, "ipv4"))
14591         ipv4_set = 1;
14592       else if (unformat (i, "ipv6"))
14593         ipv6_set = 1;
14594       else
14595         break;
14596     }
14597
14598   if (ipv4_set && ipv6_set)
14599     {
14600       errmsg ("ipv4 and ipv6 flags cannot be both set");
14601       return -99;
14602     }
14603
14604   if ((!ipv4_set) && (!ipv6_set))
14605     {
14606       errmsg ("no ipv4 nor ipv6 flag set");
14607       return -99;
14608     }
14609
14610   if (sw_if_index_set == 0)
14611     {
14612       errmsg ("missing interface name or sw_if_index");
14613       return -99;
14614     }
14615
14616   vam->current_sw_if_index = sw_if_index;
14617   vam->is_ipv6 = ipv6_set;
14618
14619   M (IP_ADDRESS_DUMP, mp);
14620   mp->sw_if_index = ntohl (sw_if_index);
14621   mp->is_ipv6 = ipv6_set;
14622   S (mp);
14623
14624   /* Use a control ping for synchronization */
14625   MPING (CONTROL_PING, mp_ping);
14626   S (mp_ping);
14627
14628   W (ret);
14629   return ret;
14630 }
14631
14632 static int
14633 api_ip_dump (vat_main_t * vam)
14634 {
14635   vl_api_ip_dump_t *mp;
14636   vl_api_control_ping_t *mp_ping;
14637   unformat_input_t *in = vam->input;
14638   int ipv4_set = 0;
14639   int ipv6_set = 0;
14640   int is_ipv6;
14641   int i;
14642   int ret;
14643
14644   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14645     {
14646       if (unformat (in, "ipv4"))
14647         ipv4_set = 1;
14648       else if (unformat (in, "ipv6"))
14649         ipv6_set = 1;
14650       else
14651         break;
14652     }
14653
14654   if (ipv4_set && ipv6_set)
14655     {
14656       errmsg ("ipv4 and ipv6 flags cannot be both set");
14657       return -99;
14658     }
14659
14660   if ((!ipv4_set) && (!ipv6_set))
14661     {
14662       errmsg ("no ipv4 nor ipv6 flag set");
14663       return -99;
14664     }
14665
14666   is_ipv6 = ipv6_set;
14667   vam->is_ipv6 = is_ipv6;
14668
14669   /* free old data */
14670   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14671     {
14672       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14673     }
14674   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14675
14676   M (IP_DUMP, mp);
14677   mp->is_ipv6 = ipv6_set;
14678   S (mp);
14679
14680   /* Use a control ping for synchronization */
14681   MPING (CONTROL_PING, mp_ping);
14682   S (mp_ping);
14683
14684   W (ret);
14685   return ret;
14686 }
14687
14688 static int
14689 api_ipsec_spd_add_del (vat_main_t * vam)
14690 {
14691   unformat_input_t *i = vam->input;
14692   vl_api_ipsec_spd_add_del_t *mp;
14693   u32 spd_id = ~0;
14694   u8 is_add = 1;
14695   int ret;
14696
14697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14698     {
14699       if (unformat (i, "spd_id %d", &spd_id))
14700         ;
14701       else if (unformat (i, "del"))
14702         is_add = 0;
14703       else
14704         {
14705           clib_warning ("parse error '%U'", format_unformat_error, i);
14706           return -99;
14707         }
14708     }
14709   if (spd_id == ~0)
14710     {
14711       errmsg ("spd_id must be set");
14712       return -99;
14713     }
14714
14715   M (IPSEC_SPD_ADD_DEL, mp);
14716
14717   mp->spd_id = ntohl (spd_id);
14718   mp->is_add = is_add;
14719
14720   S (mp);
14721   W (ret);
14722   return ret;
14723 }
14724
14725 static int
14726 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14727 {
14728   unformat_input_t *i = vam->input;
14729   vl_api_ipsec_interface_add_del_spd_t *mp;
14730   u32 sw_if_index;
14731   u8 sw_if_index_set = 0;
14732   u32 spd_id = (u32) ~ 0;
14733   u8 is_add = 1;
14734   int ret;
14735
14736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14737     {
14738       if (unformat (i, "del"))
14739         is_add = 0;
14740       else if (unformat (i, "spd_id %d", &spd_id))
14741         ;
14742       else
14743         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14744         sw_if_index_set = 1;
14745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14746         sw_if_index_set = 1;
14747       else
14748         {
14749           clib_warning ("parse error '%U'", format_unformat_error, i);
14750           return -99;
14751         }
14752
14753     }
14754
14755   if (spd_id == (u32) ~ 0)
14756     {
14757       errmsg ("spd_id must be set");
14758       return -99;
14759     }
14760
14761   if (sw_if_index_set == 0)
14762     {
14763       errmsg ("missing interface name or sw_if_index");
14764       return -99;
14765     }
14766
14767   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14768
14769   mp->spd_id = ntohl (spd_id);
14770   mp->sw_if_index = ntohl (sw_if_index);
14771   mp->is_add = is_add;
14772
14773   S (mp);
14774   W (ret);
14775   return ret;
14776 }
14777
14778 static int
14779 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14780 {
14781   unformat_input_t *i = vam->input;
14782   vl_api_ipsec_spd_entry_add_del_t *mp;
14783   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14784   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14785   i32 priority = 0;
14786   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14787   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14788   vl_api_address_t laddr_start = { }, laddr_stop =
14789   {
14790   }, raddr_start =
14791   {
14792   }, raddr_stop =
14793   {
14794   };
14795   int ret;
14796
14797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14798     {
14799       if (unformat (i, "del"))
14800         is_add = 0;
14801       if (unformat (i, "outbound"))
14802         is_outbound = 1;
14803       if (unformat (i, "inbound"))
14804         is_outbound = 0;
14805       else if (unformat (i, "spd_id %d", &spd_id))
14806         ;
14807       else if (unformat (i, "sa_id %d", &sa_id))
14808         ;
14809       else if (unformat (i, "priority %d", &priority))
14810         ;
14811       else if (unformat (i, "protocol %d", &protocol))
14812         ;
14813       else if (unformat (i, "lport_start %d", &lport_start))
14814         ;
14815       else if (unformat (i, "lport_stop %d", &lport_stop))
14816         ;
14817       else if (unformat (i, "rport_start %d", &rport_start))
14818         ;
14819       else if (unformat (i, "rport_stop %d", &rport_stop))
14820         ;
14821       else if (unformat (i, "laddr_start %U",
14822                          unformat_vl_api_address, &laddr_start))
14823         is_ip_any = 0;
14824       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14825                          &laddr_stop))
14826         is_ip_any = 0;
14827       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14828                          &raddr_start))
14829         is_ip_any = 0;
14830       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14831                          &raddr_stop))
14832         is_ip_any = 0;
14833       else
14834         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14835         {
14836           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14837             {
14838               clib_warning ("unsupported action: 'resolve'");
14839               return -99;
14840             }
14841         }
14842       else
14843         {
14844           clib_warning ("parse error '%U'", format_unformat_error, i);
14845           return -99;
14846         }
14847
14848     }
14849
14850   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14851
14852   mp->is_add = is_add;
14853
14854   mp->entry.spd_id = ntohl (spd_id);
14855   mp->entry.priority = ntohl (priority);
14856   mp->entry.is_outbound = is_outbound;
14857
14858   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14859                sizeof (vl_api_address_t));
14860   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14861                sizeof (vl_api_address_t));
14862   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14863                sizeof (vl_api_address_t));
14864   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14865                sizeof (vl_api_address_t));
14866
14867   mp->entry.protocol = (u8) protocol;
14868   mp->entry.local_port_start = ntohs ((u16) lport_start);
14869   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14870   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14871   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14872   mp->entry.policy = (u8) policy;
14873   mp->entry.sa_id = ntohl (sa_id);
14874
14875   S (mp);
14876   W (ret);
14877   return ret;
14878 }
14879
14880 static int
14881 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14882 {
14883   unformat_input_t *i = vam->input;
14884   vl_api_ipsec_sad_entry_add_del_t *mp;
14885   u32 sad_id = 0, spi = 0;
14886   u8 *ck = 0, *ik = 0;
14887   u8 is_add = 1;
14888
14889   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14890   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14891   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14892   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14893   vl_api_address_t tun_src, tun_dst;
14894   int ret;
14895
14896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14897     {
14898       if (unformat (i, "del"))
14899         is_add = 0;
14900       else if (unformat (i, "sad_id %d", &sad_id))
14901         ;
14902       else if (unformat (i, "spi %d", &spi))
14903         ;
14904       else if (unformat (i, "esp"))
14905         protocol = IPSEC_API_PROTO_ESP;
14906       else
14907         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14908         {
14909           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14910           if (ADDRESS_IP6 == tun_src.af)
14911             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14912         }
14913       else
14914         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14915         {
14916           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14917           if (ADDRESS_IP6 == tun_src.af)
14918             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14919         }
14920       else
14921         if (unformat (i, "crypto_alg %U",
14922                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14923         ;
14924       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14925         ;
14926       else if (unformat (i, "integ_alg %U",
14927                          unformat_ipsec_api_integ_alg, &integ_alg))
14928         ;
14929       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14930         ;
14931       else
14932         {
14933           clib_warning ("parse error '%U'", format_unformat_error, i);
14934           return -99;
14935         }
14936
14937     }
14938
14939   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14940
14941   mp->is_add = is_add;
14942   mp->entry.sad_id = ntohl (sad_id);
14943   mp->entry.protocol = protocol;
14944   mp->entry.spi = ntohl (spi);
14945   mp->entry.flags = flags;
14946
14947   mp->entry.crypto_algorithm = crypto_alg;
14948   mp->entry.integrity_algorithm = integ_alg;
14949   mp->entry.crypto_key.length = vec_len (ck);
14950   mp->entry.integrity_key.length = vec_len (ik);
14951
14952   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14953     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14954
14955   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14956     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14957
14958   if (ck)
14959     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14960   if (ik)
14961     clib_memcpy (mp->entry.integrity_key.data, ik,
14962                  mp->entry.integrity_key.length);
14963
14964   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14965     {
14966       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14967                    sizeof (mp->entry.tunnel_src));
14968       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14969                    sizeof (mp->entry.tunnel_dst));
14970     }
14971
14972   S (mp);
14973   W (ret);
14974   return ret;
14975 }
14976
14977 static int
14978 api_ipsec_sa_set_key (vat_main_t * vam)
14979 {
14980   unformat_input_t *i = vam->input;
14981   vl_api_ipsec_sa_set_key_t *mp;
14982   u32 sa_id;
14983   u8 *ck = 0, *ik = 0;
14984   int ret;
14985
14986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14987     {
14988       if (unformat (i, "sa_id %d", &sa_id))
14989         ;
14990       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14991         ;
14992       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14993         ;
14994       else
14995         {
14996           clib_warning ("parse error '%U'", format_unformat_error, i);
14997           return -99;
14998         }
14999     }
15000
15001   M (IPSEC_SA_SET_KEY, mp);
15002
15003   mp->sa_id = ntohl (sa_id);
15004   mp->crypto_key.length = vec_len (ck);
15005   mp->integrity_key.length = vec_len (ik);
15006
15007   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15008     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15009
15010   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15011     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15012
15013   if (ck)
15014     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15015   if (ik)
15016     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15017
15018   S (mp);
15019   W (ret);
15020   return ret;
15021 }
15022
15023 static int
15024 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15025 {
15026   unformat_input_t *i = vam->input;
15027   vl_api_ipsec_tunnel_if_add_del_t *mp;
15028   u32 local_spi = 0, remote_spi = 0;
15029   u32 crypto_alg = 0, integ_alg = 0;
15030   u8 *lck = NULL, *rck = NULL;
15031   u8 *lik = NULL, *rik = NULL;
15032   ip4_address_t local_ip = { {0} };
15033   ip4_address_t remote_ip = { {0} };
15034   u8 is_add = 1;
15035   u8 esn = 0;
15036   u8 anti_replay = 0;
15037   u8 renumber = 0;
15038   u32 instance = ~0;
15039   int ret;
15040
15041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15042     {
15043       if (unformat (i, "del"))
15044         is_add = 0;
15045       else if (unformat (i, "esn"))
15046         esn = 1;
15047       else if (unformat (i, "anti_replay"))
15048         anti_replay = 1;
15049       else if (unformat (i, "local_spi %d", &local_spi))
15050         ;
15051       else if (unformat (i, "remote_spi %d", &remote_spi))
15052         ;
15053       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15054         ;
15055       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15056         ;
15057       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15058         ;
15059       else
15060         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15061         ;
15062       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15063         ;
15064       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15065         ;
15066       else
15067         if (unformat
15068             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15069         {
15070           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15071             {
15072               errmsg ("unsupported crypto-alg: '%U'\n",
15073                       format_ipsec_crypto_alg, crypto_alg);
15074               return -99;
15075             }
15076         }
15077       else
15078         if (unformat
15079             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15080         {
15081           if (integ_alg >= IPSEC_INTEG_N_ALG)
15082             {
15083               errmsg ("unsupported integ-alg: '%U'\n",
15084                       format_ipsec_integ_alg, integ_alg);
15085               return -99;
15086             }
15087         }
15088       else if (unformat (i, "instance %u", &instance))
15089         renumber = 1;
15090       else
15091         {
15092           errmsg ("parse error '%U'\n", format_unformat_error, i);
15093           return -99;
15094         }
15095     }
15096
15097   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15098
15099   mp->is_add = is_add;
15100   mp->esn = esn;
15101   mp->anti_replay = anti_replay;
15102
15103   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15104   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15105
15106   mp->local_spi = htonl (local_spi);
15107   mp->remote_spi = htonl (remote_spi);
15108   mp->crypto_alg = (u8) crypto_alg;
15109
15110   mp->local_crypto_key_len = 0;
15111   if (lck)
15112     {
15113       mp->local_crypto_key_len = vec_len (lck);
15114       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15115         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15116       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15117     }
15118
15119   mp->remote_crypto_key_len = 0;
15120   if (rck)
15121     {
15122       mp->remote_crypto_key_len = vec_len (rck);
15123       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15124         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15125       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15126     }
15127
15128   mp->integ_alg = (u8) integ_alg;
15129
15130   mp->local_integ_key_len = 0;
15131   if (lik)
15132     {
15133       mp->local_integ_key_len = vec_len (lik);
15134       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15135         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15136       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15137     }
15138
15139   mp->remote_integ_key_len = 0;
15140   if (rik)
15141     {
15142       mp->remote_integ_key_len = vec_len (rik);
15143       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15144         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15145       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15146     }
15147
15148   if (renumber)
15149     {
15150       mp->renumber = renumber;
15151       mp->show_instance = ntohl (instance);
15152     }
15153
15154   S (mp);
15155   W (ret);
15156   return ret;
15157 }
15158
15159 static void
15160 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15161 {
15162   vat_main_t *vam = &vat_main;
15163
15164   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15165          "crypto_key %U integ_alg %u integ_key %U flags %x "
15166          "tunnel_src_addr %U tunnel_dst_addr %U "
15167          "salt %u seq_outbound %lu last_seq_inbound %lu "
15168          "replay_window %lu\n",
15169          ntohl (mp->entry.sad_id),
15170          ntohl (mp->sw_if_index),
15171          ntohl (mp->entry.spi),
15172          ntohl (mp->entry.protocol),
15173          ntohl (mp->entry.crypto_algorithm),
15174          format_hex_bytes, mp->entry.crypto_key.data,
15175          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15176          format_hex_bytes, mp->entry.integrity_key.data,
15177          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15178          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15179          &mp->entry.tunnel_dst, ntohl (mp->salt),
15180          clib_net_to_host_u64 (mp->seq_outbound),
15181          clib_net_to_host_u64 (mp->last_seq_inbound),
15182          clib_net_to_host_u64 (mp->replay_window));
15183 }
15184
15185 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15186 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15187
15188 static void
15189 vat_json_object_add_address (vat_json_node_t * node,
15190                              const vl_api_address_t * addr)
15191 {
15192   if (ADDRESS_IP6 == addr->af)
15193     {
15194       struct in6_addr ip6;
15195
15196       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
15197       vat_json_object_add_ip6 (node, "ip_address", ip6);
15198     }
15199   else
15200     {
15201       struct in_addr ip4;
15202
15203       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
15204       vat_json_object_add_ip4 (node, "ip_address", ip4);
15205     }
15206 }
15207
15208 static void vl_api_ipsec_sa_details_t_handler_json
15209   (vl_api_ipsec_sa_details_t * mp)
15210 {
15211   vat_main_t *vam = &vat_main;
15212   vat_json_node_t *node = NULL;
15213   vl_api_ipsec_sad_flags_t flags;
15214
15215   if (VAT_JSON_ARRAY != vam->json_tree.type)
15216     {
15217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15218       vat_json_init_array (&vam->json_tree);
15219     }
15220   node = vat_json_array_add (&vam->json_tree);
15221
15222   vat_json_init_object (node);
15223   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15224   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15225   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15226   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15227   vat_json_object_add_uint (node, "crypto_alg",
15228                             ntohl (mp->entry.crypto_algorithm));
15229   vat_json_object_add_uint (node, "integ_alg",
15230                             ntohl (mp->entry.integrity_algorithm));
15231   flags = ntohl (mp->entry.flags);
15232   vat_json_object_add_uint (node, "use_esn",
15233                             ! !(flags &
15234                                 IPSEC_API_SAD_FLAG_USE_EXTENDED_SEQ_NUM));
15235   vat_json_object_add_uint (node, "use_anti_replay",
15236                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15237   vat_json_object_add_uint (node, "is_tunnel",
15238                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15239   vat_json_object_add_uint (node, "is_tunnel_ip6",
15240                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15241   vat_json_object_add_uint (node, "udp_encap",
15242                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15243   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15244                              mp->entry.crypto_key.length);
15245   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15246                              mp->entry.integrity_key.length);
15247   vat_json_object_add_address (node, &mp->entry.tunnel_src);
15248   vat_json_object_add_address (node, &mp->entry.tunnel_dst);
15249   vat_json_object_add_uint (node, "replay_window",
15250                             clib_net_to_host_u64 (mp->replay_window));
15251 }
15252
15253 static int
15254 api_ipsec_sa_dump (vat_main_t * vam)
15255 {
15256   unformat_input_t *i = vam->input;
15257   vl_api_ipsec_sa_dump_t *mp;
15258   vl_api_control_ping_t *mp_ping;
15259   u32 sa_id = ~0;
15260   int ret;
15261
15262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15263     {
15264       if (unformat (i, "sa_id %d", &sa_id))
15265         ;
15266       else
15267         {
15268           clib_warning ("parse error '%U'", format_unformat_error, i);
15269           return -99;
15270         }
15271     }
15272
15273   M (IPSEC_SA_DUMP, mp);
15274
15275   mp->sa_id = ntohl (sa_id);
15276
15277   S (mp);
15278
15279   /* Use a control ping for synchronization */
15280   M (CONTROL_PING, mp_ping);
15281   S (mp_ping);
15282
15283   W (ret);
15284   return ret;
15285 }
15286
15287 static int
15288 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15289 {
15290   unformat_input_t *i = vam->input;
15291   vl_api_ipsec_tunnel_if_set_key_t *mp;
15292   u32 sw_if_index = ~0;
15293   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15294   u8 *key = 0;
15295   u32 alg = ~0;
15296   int ret;
15297
15298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15299     {
15300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15301         ;
15302       else
15303         if (unformat
15304             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15305         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15306       else
15307         if (unformat
15308             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15309         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15310       else
15311         if (unformat
15312             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15313         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15314       else
15315         if (unformat
15316             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15317         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15318       else if (unformat (i, "%U", unformat_hex_string, &key))
15319         ;
15320       else
15321         {
15322           clib_warning ("parse error '%U'", format_unformat_error, i);
15323           return -99;
15324         }
15325     }
15326
15327   if (sw_if_index == ~0)
15328     {
15329       errmsg ("interface must be specified");
15330       return -99;
15331     }
15332
15333   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15334     {
15335       errmsg ("key type must be specified");
15336       return -99;
15337     }
15338
15339   if (alg == ~0)
15340     {
15341       errmsg ("algorithm must be specified");
15342       return -99;
15343     }
15344
15345   if (vec_len (key) == 0)
15346     {
15347       errmsg ("key must be specified");
15348       return -99;
15349     }
15350
15351   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15352
15353   mp->sw_if_index = htonl (sw_if_index);
15354   mp->alg = alg;
15355   mp->key_type = key_type;
15356   mp->key_len = vec_len (key);
15357   clib_memcpy (mp->key, key, vec_len (key));
15358
15359   S (mp);
15360   W (ret);
15361
15362   return ret;
15363 }
15364
15365 static int
15366 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15367 {
15368   unformat_input_t *i = vam->input;
15369   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15370   u32 sw_if_index = ~0;
15371   u32 sa_id = ~0;
15372   u8 is_outbound = (u8) ~ 0;
15373   int ret;
15374
15375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15376     {
15377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15378         ;
15379       else if (unformat (i, "sa_id %d", &sa_id))
15380         ;
15381       else if (unformat (i, "outbound"))
15382         is_outbound = 1;
15383       else if (unformat (i, "inbound"))
15384         is_outbound = 0;
15385       else
15386         {
15387           clib_warning ("parse error '%U'", format_unformat_error, i);
15388           return -99;
15389         }
15390     }
15391
15392   if (sw_if_index == ~0)
15393     {
15394       errmsg ("interface must be specified");
15395       return -99;
15396     }
15397
15398   if (sa_id == ~0)
15399     {
15400       errmsg ("SA ID must be specified");
15401       return -99;
15402     }
15403
15404   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15405
15406   mp->sw_if_index = htonl (sw_if_index);
15407   mp->sa_id = htonl (sa_id);
15408   mp->is_outbound = is_outbound;
15409
15410   S (mp);
15411   W (ret);
15412
15413   return ret;
15414 }
15415
15416 static int
15417 api_get_first_msg_id (vat_main_t * vam)
15418 {
15419   vl_api_get_first_msg_id_t *mp;
15420   unformat_input_t *i = vam->input;
15421   u8 *name;
15422   u8 name_set = 0;
15423   int ret;
15424
15425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15426     {
15427       if (unformat (i, "client %s", &name))
15428         name_set = 1;
15429       else
15430         break;
15431     }
15432
15433   if (name_set == 0)
15434     {
15435       errmsg ("missing client name");
15436       return -99;
15437     }
15438   vec_add1 (name, 0);
15439
15440   if (vec_len (name) > 63)
15441     {
15442       errmsg ("client name too long");
15443       return -99;
15444     }
15445
15446   M (GET_FIRST_MSG_ID, mp);
15447   clib_memcpy (mp->name, name, vec_len (name));
15448   S (mp);
15449   W (ret);
15450   return ret;
15451 }
15452
15453 static int
15454 api_cop_interface_enable_disable (vat_main_t * vam)
15455 {
15456   unformat_input_t *line_input = vam->input;
15457   vl_api_cop_interface_enable_disable_t *mp;
15458   u32 sw_if_index = ~0;
15459   u8 enable_disable = 1;
15460   int ret;
15461
15462   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15463     {
15464       if (unformat (line_input, "disable"))
15465         enable_disable = 0;
15466       if (unformat (line_input, "enable"))
15467         enable_disable = 1;
15468       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15469                          vam, &sw_if_index))
15470         ;
15471       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15472         ;
15473       else
15474         break;
15475     }
15476
15477   if (sw_if_index == ~0)
15478     {
15479       errmsg ("missing interface name or sw_if_index");
15480       return -99;
15481     }
15482
15483   /* Construct the API message */
15484   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15485   mp->sw_if_index = ntohl (sw_if_index);
15486   mp->enable_disable = enable_disable;
15487
15488   /* send it... */
15489   S (mp);
15490   /* Wait for the reply */
15491   W (ret);
15492   return ret;
15493 }
15494
15495 static int
15496 api_cop_whitelist_enable_disable (vat_main_t * vam)
15497 {
15498   unformat_input_t *line_input = vam->input;
15499   vl_api_cop_whitelist_enable_disable_t *mp;
15500   u32 sw_if_index = ~0;
15501   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15502   u32 fib_id = 0;
15503   int ret;
15504
15505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (line_input, "ip4"))
15508         ip4 = 1;
15509       else if (unformat (line_input, "ip6"))
15510         ip6 = 1;
15511       else if (unformat (line_input, "default"))
15512         default_cop = 1;
15513       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15514                          vam, &sw_if_index))
15515         ;
15516       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15517         ;
15518       else if (unformat (line_input, "fib-id %d", &fib_id))
15519         ;
15520       else
15521         break;
15522     }
15523
15524   if (sw_if_index == ~0)
15525     {
15526       errmsg ("missing interface name or sw_if_index");
15527       return -99;
15528     }
15529
15530   /* Construct the API message */
15531   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15532   mp->sw_if_index = ntohl (sw_if_index);
15533   mp->fib_id = ntohl (fib_id);
15534   mp->ip4 = ip4;
15535   mp->ip6 = ip6;
15536   mp->default_cop = default_cop;
15537
15538   /* send it... */
15539   S (mp);
15540   /* Wait for the reply */
15541   W (ret);
15542   return ret;
15543 }
15544
15545 static int
15546 api_get_node_graph (vat_main_t * vam)
15547 {
15548   vl_api_get_node_graph_t *mp;
15549   int ret;
15550
15551   M (GET_NODE_GRAPH, mp);
15552
15553   /* send it... */
15554   S (mp);
15555   /* Wait for the reply */
15556   W (ret);
15557   return ret;
15558 }
15559
15560 /* *INDENT-OFF* */
15561 /** Used for parsing LISP eids */
15562 typedef CLIB_PACKED(struct{
15563   u8 addr[16];   /**< eid address */
15564   u32 len;       /**< prefix length if IP */
15565   u8 type;      /**< type of eid */
15566 }) lisp_eid_vat_t;
15567 /* *INDENT-ON* */
15568
15569 static uword
15570 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15571 {
15572   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15573
15574   clib_memset (a, 0, sizeof (a[0]));
15575
15576   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15577     {
15578       a->type = 0;              /* ipv4 type */
15579     }
15580   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15581     {
15582       a->type = 1;              /* ipv6 type */
15583     }
15584   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15585     {
15586       a->type = 2;              /* mac type */
15587     }
15588   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15589     {
15590       a->type = 3;              /* NSH type */
15591       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15592       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15593     }
15594   else
15595     {
15596       return 0;
15597     }
15598
15599   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15600     {
15601       return 0;
15602     }
15603
15604   return 1;
15605 }
15606
15607 static int
15608 lisp_eid_size_vat (u8 type)
15609 {
15610   switch (type)
15611     {
15612     case 0:
15613       return 4;
15614     case 1:
15615       return 16;
15616     case 2:
15617       return 6;
15618     case 3:
15619       return 5;
15620     }
15621   return 0;
15622 }
15623
15624 static void
15625 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15626 {
15627   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15628 }
15629
15630 static int
15631 api_one_add_del_locator_set (vat_main_t * vam)
15632 {
15633   unformat_input_t *input = vam->input;
15634   vl_api_one_add_del_locator_set_t *mp;
15635   u8 is_add = 1;
15636   u8 *locator_set_name = NULL;
15637   u8 locator_set_name_set = 0;
15638   vl_api_local_locator_t locator, *locators = 0;
15639   u32 sw_if_index, priority, weight;
15640   u32 data_len = 0;
15641
15642   int ret;
15643   /* Parse args required to build the message */
15644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15645     {
15646       if (unformat (input, "del"))
15647         {
15648           is_add = 0;
15649         }
15650       else if (unformat (input, "locator-set %s", &locator_set_name))
15651         {
15652           locator_set_name_set = 1;
15653         }
15654       else if (unformat (input, "sw_if_index %u p %u w %u",
15655                          &sw_if_index, &priority, &weight))
15656         {
15657           locator.sw_if_index = htonl (sw_if_index);
15658           locator.priority = priority;
15659           locator.weight = weight;
15660           vec_add1 (locators, locator);
15661         }
15662       else
15663         if (unformat
15664             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15665              &sw_if_index, &priority, &weight))
15666         {
15667           locator.sw_if_index = htonl (sw_if_index);
15668           locator.priority = priority;
15669           locator.weight = weight;
15670           vec_add1 (locators, locator);
15671         }
15672       else
15673         break;
15674     }
15675
15676   if (locator_set_name_set == 0)
15677     {
15678       errmsg ("missing locator-set name");
15679       vec_free (locators);
15680       return -99;
15681     }
15682
15683   if (vec_len (locator_set_name) > 64)
15684     {
15685       errmsg ("locator-set name too long");
15686       vec_free (locator_set_name);
15687       vec_free (locators);
15688       return -99;
15689     }
15690   vec_add1 (locator_set_name, 0);
15691
15692   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15693
15694   /* Construct the API message */
15695   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15696
15697   mp->is_add = is_add;
15698   clib_memcpy (mp->locator_set_name, locator_set_name,
15699                vec_len (locator_set_name));
15700   vec_free (locator_set_name);
15701
15702   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15703   if (locators)
15704     clib_memcpy (mp->locators, locators, data_len);
15705   vec_free (locators);
15706
15707   /* send it... */
15708   S (mp);
15709
15710   /* Wait for a reply... */
15711   W (ret);
15712   return ret;
15713 }
15714
15715 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15716
15717 static int
15718 api_one_add_del_locator (vat_main_t * vam)
15719 {
15720   unformat_input_t *input = vam->input;
15721   vl_api_one_add_del_locator_t *mp;
15722   u32 tmp_if_index = ~0;
15723   u32 sw_if_index = ~0;
15724   u8 sw_if_index_set = 0;
15725   u8 sw_if_index_if_name_set = 0;
15726   u32 priority = ~0;
15727   u8 priority_set = 0;
15728   u32 weight = ~0;
15729   u8 weight_set = 0;
15730   u8 is_add = 1;
15731   u8 *locator_set_name = NULL;
15732   u8 locator_set_name_set = 0;
15733   int ret;
15734
15735   /* Parse args required to build the message */
15736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15737     {
15738       if (unformat (input, "del"))
15739         {
15740           is_add = 0;
15741         }
15742       else if (unformat (input, "locator-set %s", &locator_set_name))
15743         {
15744           locator_set_name_set = 1;
15745         }
15746       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15747                          &tmp_if_index))
15748         {
15749           sw_if_index_if_name_set = 1;
15750           sw_if_index = tmp_if_index;
15751         }
15752       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15753         {
15754           sw_if_index_set = 1;
15755           sw_if_index = tmp_if_index;
15756         }
15757       else if (unformat (input, "p %d", &priority))
15758         {
15759           priority_set = 1;
15760         }
15761       else if (unformat (input, "w %d", &weight))
15762         {
15763           weight_set = 1;
15764         }
15765       else
15766         break;
15767     }
15768
15769   if (locator_set_name_set == 0)
15770     {
15771       errmsg ("missing locator-set name");
15772       return -99;
15773     }
15774
15775   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15776     {
15777       errmsg ("missing sw_if_index");
15778       vec_free (locator_set_name);
15779       return -99;
15780     }
15781
15782   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15783     {
15784       errmsg ("cannot use both params interface name and sw_if_index");
15785       vec_free (locator_set_name);
15786       return -99;
15787     }
15788
15789   if (priority_set == 0)
15790     {
15791       errmsg ("missing locator-set priority");
15792       vec_free (locator_set_name);
15793       return -99;
15794     }
15795
15796   if (weight_set == 0)
15797     {
15798       errmsg ("missing locator-set weight");
15799       vec_free (locator_set_name);
15800       return -99;
15801     }
15802
15803   if (vec_len (locator_set_name) > 64)
15804     {
15805       errmsg ("locator-set name too long");
15806       vec_free (locator_set_name);
15807       return -99;
15808     }
15809   vec_add1 (locator_set_name, 0);
15810
15811   /* Construct the API message */
15812   M (ONE_ADD_DEL_LOCATOR, mp);
15813
15814   mp->is_add = is_add;
15815   mp->sw_if_index = ntohl (sw_if_index);
15816   mp->priority = priority;
15817   mp->weight = weight;
15818   clib_memcpy (mp->locator_set_name, locator_set_name,
15819                vec_len (locator_set_name));
15820   vec_free (locator_set_name);
15821
15822   /* send it... */
15823   S (mp);
15824
15825   /* Wait for a reply... */
15826   W (ret);
15827   return ret;
15828 }
15829
15830 #define api_lisp_add_del_locator api_one_add_del_locator
15831
15832 uword
15833 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15834 {
15835   u32 *key_id = va_arg (*args, u32 *);
15836   u8 *s = 0;
15837
15838   if (unformat (input, "%s", &s))
15839     {
15840       if (!strcmp ((char *) s, "sha1"))
15841         key_id[0] = HMAC_SHA_1_96;
15842       else if (!strcmp ((char *) s, "sha256"))
15843         key_id[0] = HMAC_SHA_256_128;
15844       else
15845         {
15846           clib_warning ("invalid key_id: '%s'", s);
15847           key_id[0] = HMAC_NO_KEY;
15848         }
15849     }
15850   else
15851     return 0;
15852
15853   vec_free (s);
15854   return 1;
15855 }
15856
15857 static int
15858 api_one_add_del_local_eid (vat_main_t * vam)
15859 {
15860   unformat_input_t *input = vam->input;
15861   vl_api_one_add_del_local_eid_t *mp;
15862   u8 is_add = 1;
15863   u8 eid_set = 0;
15864   lisp_eid_vat_t _eid, *eid = &_eid;
15865   u8 *locator_set_name = 0;
15866   u8 locator_set_name_set = 0;
15867   u32 vni = 0;
15868   u16 key_id = 0;
15869   u8 *key = 0;
15870   int ret;
15871
15872   /* Parse args required to build the message */
15873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15874     {
15875       if (unformat (input, "del"))
15876         {
15877           is_add = 0;
15878         }
15879       else if (unformat (input, "vni %d", &vni))
15880         {
15881           ;
15882         }
15883       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15884         {
15885           eid_set = 1;
15886         }
15887       else if (unformat (input, "locator-set %s", &locator_set_name))
15888         {
15889           locator_set_name_set = 1;
15890         }
15891       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15892         ;
15893       else if (unformat (input, "secret-key %_%v%_", &key))
15894         ;
15895       else
15896         break;
15897     }
15898
15899   if (locator_set_name_set == 0)
15900     {
15901       errmsg ("missing locator-set name");
15902       return -99;
15903     }
15904
15905   if (0 == eid_set)
15906     {
15907       errmsg ("EID address not set!");
15908       vec_free (locator_set_name);
15909       return -99;
15910     }
15911
15912   if (key && (0 == key_id))
15913     {
15914       errmsg ("invalid key_id!");
15915       return -99;
15916     }
15917
15918   if (vec_len (key) > 64)
15919     {
15920       errmsg ("key too long");
15921       vec_free (key);
15922       return -99;
15923     }
15924
15925   if (vec_len (locator_set_name) > 64)
15926     {
15927       errmsg ("locator-set name too long");
15928       vec_free (locator_set_name);
15929       return -99;
15930     }
15931   vec_add1 (locator_set_name, 0);
15932
15933   /* Construct the API message */
15934   M (ONE_ADD_DEL_LOCAL_EID, mp);
15935
15936   mp->is_add = is_add;
15937   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15938   mp->eid_type = eid->type;
15939   mp->prefix_len = eid->len;
15940   mp->vni = clib_host_to_net_u32 (vni);
15941   mp->key_id = clib_host_to_net_u16 (key_id);
15942   clib_memcpy (mp->locator_set_name, locator_set_name,
15943                vec_len (locator_set_name));
15944   clib_memcpy (mp->key, key, vec_len (key));
15945
15946   vec_free (locator_set_name);
15947   vec_free (key);
15948
15949   /* send it... */
15950   S (mp);
15951
15952   /* Wait for a reply... */
15953   W (ret);
15954   return ret;
15955 }
15956
15957 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15958
15959 static int
15960 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15961 {
15962   u32 dp_table = 0, vni = 0;;
15963   unformat_input_t *input = vam->input;
15964   vl_api_gpe_add_del_fwd_entry_t *mp;
15965   u8 is_add = 1;
15966   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15967   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15968   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15969   u32 action = ~0, w;
15970   ip4_address_t rmt_rloc4, lcl_rloc4;
15971   ip6_address_t rmt_rloc6, lcl_rloc6;
15972   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15973   int ret;
15974
15975   clib_memset (&rloc, 0, sizeof (rloc));
15976
15977   /* Parse args required to build the message */
15978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15979     {
15980       if (unformat (input, "del"))
15981         is_add = 0;
15982       else if (unformat (input, "add"))
15983         is_add = 1;
15984       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15985         {
15986           rmt_eid_set = 1;
15987         }
15988       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15989         {
15990           lcl_eid_set = 1;
15991         }
15992       else if (unformat (input, "vrf %d", &dp_table))
15993         ;
15994       else if (unformat (input, "bd %d", &dp_table))
15995         ;
15996       else if (unformat (input, "vni %d", &vni))
15997         ;
15998       else if (unformat (input, "w %d", &w))
15999         {
16000           if (!curr_rloc)
16001             {
16002               errmsg ("No RLOC configured for setting priority/weight!");
16003               return -99;
16004             }
16005           curr_rloc->weight = w;
16006         }
16007       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16008                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16009         {
16010           rloc.is_ip4 = 1;
16011
16012           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16013           rloc.weight = 0;
16014           vec_add1 (lcl_locs, rloc);
16015
16016           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16017           vec_add1 (rmt_locs, rloc);
16018           /* weight saved in rmt loc */
16019           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16020         }
16021       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16022                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16023         {
16024           rloc.is_ip4 = 0;
16025           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16026           rloc.weight = 0;
16027           vec_add1 (lcl_locs, rloc);
16028
16029           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16030           vec_add1 (rmt_locs, rloc);
16031           /* weight saved in rmt loc */
16032           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16033         }
16034       else if (unformat (input, "action %d", &action))
16035         {
16036           ;
16037         }
16038       else
16039         {
16040           clib_warning ("parse error '%U'", format_unformat_error, input);
16041           return -99;
16042         }
16043     }
16044
16045   if (!rmt_eid_set)
16046     {
16047       errmsg ("remote eid addresses not set");
16048       return -99;
16049     }
16050
16051   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16052     {
16053       errmsg ("eid types don't match");
16054       return -99;
16055     }
16056
16057   if (0 == rmt_locs && (u32) ~ 0 == action)
16058     {
16059       errmsg ("action not set for negative mapping");
16060       return -99;
16061     }
16062
16063   /* Construct the API message */
16064   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16065       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16066
16067   mp->is_add = is_add;
16068   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16069   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16070   mp->eid_type = rmt_eid->type;
16071   mp->dp_table = clib_host_to_net_u32 (dp_table);
16072   mp->vni = clib_host_to_net_u32 (vni);
16073   mp->rmt_len = rmt_eid->len;
16074   mp->lcl_len = lcl_eid->len;
16075   mp->action = action;
16076
16077   if (0 != rmt_locs && 0 != lcl_locs)
16078     {
16079       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16080       clib_memcpy (mp->locs, lcl_locs,
16081                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16082
16083       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16084       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16085                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16086     }
16087   vec_free (lcl_locs);
16088   vec_free (rmt_locs);
16089
16090   /* send it... */
16091   S (mp);
16092
16093   /* Wait for a reply... */
16094   W (ret);
16095   return ret;
16096 }
16097
16098 static int
16099 api_one_add_del_map_server (vat_main_t * vam)
16100 {
16101   unformat_input_t *input = vam->input;
16102   vl_api_one_add_del_map_server_t *mp;
16103   u8 is_add = 1;
16104   u8 ipv4_set = 0;
16105   u8 ipv6_set = 0;
16106   ip4_address_t ipv4;
16107   ip6_address_t ipv6;
16108   int ret;
16109
16110   /* Parse args required to build the message */
16111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16112     {
16113       if (unformat (input, "del"))
16114         {
16115           is_add = 0;
16116         }
16117       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16118         {
16119           ipv4_set = 1;
16120         }
16121       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16122         {
16123           ipv6_set = 1;
16124         }
16125       else
16126         break;
16127     }
16128
16129   if (ipv4_set && ipv6_set)
16130     {
16131       errmsg ("both eid v4 and v6 addresses set");
16132       return -99;
16133     }
16134
16135   if (!ipv4_set && !ipv6_set)
16136     {
16137       errmsg ("eid addresses not set");
16138       return -99;
16139     }
16140
16141   /* Construct the API message */
16142   M (ONE_ADD_DEL_MAP_SERVER, mp);
16143
16144   mp->is_add = is_add;
16145   if (ipv6_set)
16146     {
16147       mp->is_ipv6 = 1;
16148       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16149     }
16150   else
16151     {
16152       mp->is_ipv6 = 0;
16153       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16154     }
16155
16156   /* send it... */
16157   S (mp);
16158
16159   /* Wait for a reply... */
16160   W (ret);
16161   return ret;
16162 }
16163
16164 #define api_lisp_add_del_map_server api_one_add_del_map_server
16165
16166 static int
16167 api_one_add_del_map_resolver (vat_main_t * vam)
16168 {
16169   unformat_input_t *input = vam->input;
16170   vl_api_one_add_del_map_resolver_t *mp;
16171   u8 is_add = 1;
16172   u8 ipv4_set = 0;
16173   u8 ipv6_set = 0;
16174   ip4_address_t ipv4;
16175   ip6_address_t ipv6;
16176   int ret;
16177
16178   /* Parse args required to build the message */
16179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16180     {
16181       if (unformat (input, "del"))
16182         {
16183           is_add = 0;
16184         }
16185       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16186         {
16187           ipv4_set = 1;
16188         }
16189       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16190         {
16191           ipv6_set = 1;
16192         }
16193       else
16194         break;
16195     }
16196
16197   if (ipv4_set && ipv6_set)
16198     {
16199       errmsg ("both eid v4 and v6 addresses set");
16200       return -99;
16201     }
16202
16203   if (!ipv4_set && !ipv6_set)
16204     {
16205       errmsg ("eid addresses not set");
16206       return -99;
16207     }
16208
16209   /* Construct the API message */
16210   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16211
16212   mp->is_add = is_add;
16213   if (ipv6_set)
16214     {
16215       mp->is_ipv6 = 1;
16216       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16217     }
16218   else
16219     {
16220       mp->is_ipv6 = 0;
16221       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16222     }
16223
16224   /* send it... */
16225   S (mp);
16226
16227   /* Wait for a reply... */
16228   W (ret);
16229   return ret;
16230 }
16231
16232 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16233
16234 static int
16235 api_lisp_gpe_enable_disable (vat_main_t * vam)
16236 {
16237   unformat_input_t *input = vam->input;
16238   vl_api_gpe_enable_disable_t *mp;
16239   u8 is_set = 0;
16240   u8 is_en = 1;
16241   int ret;
16242
16243   /* Parse args required to build the message */
16244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (input, "enable"))
16247         {
16248           is_set = 1;
16249           is_en = 1;
16250         }
16251       else if (unformat (input, "disable"))
16252         {
16253           is_set = 1;
16254           is_en = 0;
16255         }
16256       else
16257         break;
16258     }
16259
16260   if (is_set == 0)
16261     {
16262       errmsg ("Value not set");
16263       return -99;
16264     }
16265
16266   /* Construct the API message */
16267   M (GPE_ENABLE_DISABLE, mp);
16268
16269   mp->is_en = is_en;
16270
16271   /* send it... */
16272   S (mp);
16273
16274   /* Wait for a reply... */
16275   W (ret);
16276   return ret;
16277 }
16278
16279 static int
16280 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16281 {
16282   unformat_input_t *input = vam->input;
16283   vl_api_one_rloc_probe_enable_disable_t *mp;
16284   u8 is_set = 0;
16285   u8 is_en = 0;
16286   int ret;
16287
16288   /* Parse args required to build the message */
16289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16290     {
16291       if (unformat (input, "enable"))
16292         {
16293           is_set = 1;
16294           is_en = 1;
16295         }
16296       else if (unformat (input, "disable"))
16297         is_set = 1;
16298       else
16299         break;
16300     }
16301
16302   if (!is_set)
16303     {
16304       errmsg ("Value not set");
16305       return -99;
16306     }
16307
16308   /* Construct the API message */
16309   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16310
16311   mp->is_enabled = is_en;
16312
16313   /* send it... */
16314   S (mp);
16315
16316   /* Wait for a reply... */
16317   W (ret);
16318   return ret;
16319 }
16320
16321 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16322
16323 static int
16324 api_one_map_register_enable_disable (vat_main_t * vam)
16325 {
16326   unformat_input_t *input = vam->input;
16327   vl_api_one_map_register_enable_disable_t *mp;
16328   u8 is_set = 0;
16329   u8 is_en = 0;
16330   int ret;
16331
16332   /* Parse args required to build the message */
16333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16334     {
16335       if (unformat (input, "enable"))
16336         {
16337           is_set = 1;
16338           is_en = 1;
16339         }
16340       else if (unformat (input, "disable"))
16341         is_set = 1;
16342       else
16343         break;
16344     }
16345
16346   if (!is_set)
16347     {
16348       errmsg ("Value not set");
16349       return -99;
16350     }
16351
16352   /* Construct the API message */
16353   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16354
16355   mp->is_enabled = is_en;
16356
16357   /* send it... */
16358   S (mp);
16359
16360   /* Wait for a reply... */
16361   W (ret);
16362   return ret;
16363 }
16364
16365 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16366
16367 static int
16368 api_one_enable_disable (vat_main_t * vam)
16369 {
16370   unformat_input_t *input = vam->input;
16371   vl_api_one_enable_disable_t *mp;
16372   u8 is_set = 0;
16373   u8 is_en = 0;
16374   int ret;
16375
16376   /* Parse args required to build the message */
16377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (input, "enable"))
16380         {
16381           is_set = 1;
16382           is_en = 1;
16383         }
16384       else if (unformat (input, "disable"))
16385         {
16386           is_set = 1;
16387         }
16388       else
16389         break;
16390     }
16391
16392   if (!is_set)
16393     {
16394       errmsg ("Value not set");
16395       return -99;
16396     }
16397
16398   /* Construct the API message */
16399   M (ONE_ENABLE_DISABLE, mp);
16400
16401   mp->is_en = is_en;
16402
16403   /* send it... */
16404   S (mp);
16405
16406   /* Wait for a reply... */
16407   W (ret);
16408   return ret;
16409 }
16410
16411 #define api_lisp_enable_disable api_one_enable_disable
16412
16413 static int
16414 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16415 {
16416   unformat_input_t *input = vam->input;
16417   vl_api_one_enable_disable_xtr_mode_t *mp;
16418   u8 is_set = 0;
16419   u8 is_en = 0;
16420   int ret;
16421
16422   /* Parse args required to build the message */
16423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16424     {
16425       if (unformat (input, "enable"))
16426         {
16427           is_set = 1;
16428           is_en = 1;
16429         }
16430       else if (unformat (input, "disable"))
16431         {
16432           is_set = 1;
16433         }
16434       else
16435         break;
16436     }
16437
16438   if (!is_set)
16439     {
16440       errmsg ("Value not set");
16441       return -99;
16442     }
16443
16444   /* Construct the API message */
16445   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16446
16447   mp->is_en = is_en;
16448
16449   /* send it... */
16450   S (mp);
16451
16452   /* Wait for a reply... */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 static int
16458 api_one_show_xtr_mode (vat_main_t * vam)
16459 {
16460   vl_api_one_show_xtr_mode_t *mp;
16461   int ret;
16462
16463   /* Construct the API message */
16464   M (ONE_SHOW_XTR_MODE, mp);
16465
16466   /* send it... */
16467   S (mp);
16468
16469   /* Wait for a reply... */
16470   W (ret);
16471   return ret;
16472 }
16473
16474 static int
16475 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16476 {
16477   unformat_input_t *input = vam->input;
16478   vl_api_one_enable_disable_pitr_mode_t *mp;
16479   u8 is_set = 0;
16480   u8 is_en = 0;
16481   int ret;
16482
16483   /* Parse args required to build the message */
16484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16485     {
16486       if (unformat (input, "enable"))
16487         {
16488           is_set = 1;
16489           is_en = 1;
16490         }
16491       else if (unformat (input, "disable"))
16492         {
16493           is_set = 1;
16494         }
16495       else
16496         break;
16497     }
16498
16499   if (!is_set)
16500     {
16501       errmsg ("Value not set");
16502       return -99;
16503     }
16504
16505   /* Construct the API message */
16506   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16507
16508   mp->is_en = is_en;
16509
16510   /* send it... */
16511   S (mp);
16512
16513   /* Wait for a reply... */
16514   W (ret);
16515   return ret;
16516 }
16517
16518 static int
16519 api_one_show_pitr_mode (vat_main_t * vam)
16520 {
16521   vl_api_one_show_pitr_mode_t *mp;
16522   int ret;
16523
16524   /* Construct the API message */
16525   M (ONE_SHOW_PITR_MODE, mp);
16526
16527   /* send it... */
16528   S (mp);
16529
16530   /* Wait for a reply... */
16531   W (ret);
16532   return ret;
16533 }
16534
16535 static int
16536 api_one_enable_disable_petr_mode (vat_main_t * vam)
16537 {
16538   unformat_input_t *input = vam->input;
16539   vl_api_one_enable_disable_petr_mode_t *mp;
16540   u8 is_set = 0;
16541   u8 is_en = 0;
16542   int ret;
16543
16544   /* Parse args required to build the message */
16545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16546     {
16547       if (unformat (input, "enable"))
16548         {
16549           is_set = 1;
16550           is_en = 1;
16551         }
16552       else if (unformat (input, "disable"))
16553         {
16554           is_set = 1;
16555         }
16556       else
16557         break;
16558     }
16559
16560   if (!is_set)
16561     {
16562       errmsg ("Value not set");
16563       return -99;
16564     }
16565
16566   /* Construct the API message */
16567   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16568
16569   mp->is_en = is_en;
16570
16571   /* send it... */
16572   S (mp);
16573
16574   /* Wait for a reply... */
16575   W (ret);
16576   return ret;
16577 }
16578
16579 static int
16580 api_one_show_petr_mode (vat_main_t * vam)
16581 {
16582   vl_api_one_show_petr_mode_t *mp;
16583   int ret;
16584
16585   /* Construct the API message */
16586   M (ONE_SHOW_PETR_MODE, mp);
16587
16588   /* send it... */
16589   S (mp);
16590
16591   /* Wait for a reply... */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 static int
16597 api_show_one_map_register_state (vat_main_t * vam)
16598 {
16599   vl_api_show_one_map_register_state_t *mp;
16600   int ret;
16601
16602   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16603
16604   /* send */
16605   S (mp);
16606
16607   /* wait for reply */
16608   W (ret);
16609   return ret;
16610 }
16611
16612 #define api_show_lisp_map_register_state api_show_one_map_register_state
16613
16614 static int
16615 api_show_one_rloc_probe_state (vat_main_t * vam)
16616 {
16617   vl_api_show_one_rloc_probe_state_t *mp;
16618   int ret;
16619
16620   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16621
16622   /* send */
16623   S (mp);
16624
16625   /* wait for reply */
16626   W (ret);
16627   return ret;
16628 }
16629
16630 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16631
16632 static int
16633 api_one_add_del_ndp_entry (vat_main_t * vam)
16634 {
16635   vl_api_one_add_del_ndp_entry_t *mp;
16636   unformat_input_t *input = vam->input;
16637   u8 is_add = 1;
16638   u8 mac_set = 0;
16639   u8 bd_set = 0;
16640   u8 ip_set = 0;
16641   u8 mac[6] = { 0, };
16642   u8 ip6[16] = { 0, };
16643   u32 bd = ~0;
16644   int ret;
16645
16646   /* Parse args required to build the message */
16647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16648     {
16649       if (unformat (input, "del"))
16650         is_add = 0;
16651       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16652         mac_set = 1;
16653       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16654         ip_set = 1;
16655       else if (unformat (input, "bd %d", &bd))
16656         bd_set = 1;
16657       else
16658         {
16659           errmsg ("parse error '%U'", format_unformat_error, input);
16660           return -99;
16661         }
16662     }
16663
16664   if (!bd_set || !ip_set || (!mac_set && is_add))
16665     {
16666       errmsg ("Missing BD, IP or MAC!");
16667       return -99;
16668     }
16669
16670   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16671   mp->is_add = is_add;
16672   clib_memcpy (mp->mac, mac, 6);
16673   mp->bd = clib_host_to_net_u32 (bd);
16674   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16675
16676   /* send */
16677   S (mp);
16678
16679   /* wait for reply */
16680   W (ret);
16681   return ret;
16682 }
16683
16684 static int
16685 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16686 {
16687   vl_api_one_add_del_l2_arp_entry_t *mp;
16688   unformat_input_t *input = vam->input;
16689   u8 is_add = 1;
16690   u8 mac_set = 0;
16691   u8 bd_set = 0;
16692   u8 ip_set = 0;
16693   u8 mac[6] = { 0, };
16694   u32 ip4 = 0, bd = ~0;
16695   int ret;
16696
16697   /* Parse args required to build the message */
16698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16699     {
16700       if (unformat (input, "del"))
16701         is_add = 0;
16702       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16703         mac_set = 1;
16704       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16705         ip_set = 1;
16706       else if (unformat (input, "bd %d", &bd))
16707         bd_set = 1;
16708       else
16709         {
16710           errmsg ("parse error '%U'", format_unformat_error, input);
16711           return -99;
16712         }
16713     }
16714
16715   if (!bd_set || !ip_set || (!mac_set && is_add))
16716     {
16717       errmsg ("Missing BD, IP or MAC!");
16718       return -99;
16719     }
16720
16721   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16722   mp->is_add = is_add;
16723   clib_memcpy (mp->mac, mac, 6);
16724   mp->bd = clib_host_to_net_u32 (bd);
16725   mp->ip4 = ip4;
16726
16727   /* send */
16728   S (mp);
16729
16730   /* wait for reply */
16731   W (ret);
16732   return ret;
16733 }
16734
16735 static int
16736 api_one_ndp_bd_get (vat_main_t * vam)
16737 {
16738   vl_api_one_ndp_bd_get_t *mp;
16739   int ret;
16740
16741   M (ONE_NDP_BD_GET, mp);
16742
16743   /* send */
16744   S (mp);
16745
16746   /* wait for reply */
16747   W (ret);
16748   return ret;
16749 }
16750
16751 static int
16752 api_one_ndp_entries_get (vat_main_t * vam)
16753 {
16754   vl_api_one_ndp_entries_get_t *mp;
16755   unformat_input_t *input = vam->input;
16756   u8 bd_set = 0;
16757   u32 bd = ~0;
16758   int ret;
16759
16760   /* Parse args required to build the message */
16761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16762     {
16763       if (unformat (input, "bd %d", &bd))
16764         bd_set = 1;
16765       else
16766         {
16767           errmsg ("parse error '%U'", format_unformat_error, input);
16768           return -99;
16769         }
16770     }
16771
16772   if (!bd_set)
16773     {
16774       errmsg ("Expected bridge domain!");
16775       return -99;
16776     }
16777
16778   M (ONE_NDP_ENTRIES_GET, mp);
16779   mp->bd = clib_host_to_net_u32 (bd);
16780
16781   /* send */
16782   S (mp);
16783
16784   /* wait for reply */
16785   W (ret);
16786   return ret;
16787 }
16788
16789 static int
16790 api_one_l2_arp_bd_get (vat_main_t * vam)
16791 {
16792   vl_api_one_l2_arp_bd_get_t *mp;
16793   int ret;
16794
16795   M (ONE_L2_ARP_BD_GET, mp);
16796
16797   /* send */
16798   S (mp);
16799
16800   /* wait for reply */
16801   W (ret);
16802   return ret;
16803 }
16804
16805 static int
16806 api_one_l2_arp_entries_get (vat_main_t * vam)
16807 {
16808   vl_api_one_l2_arp_entries_get_t *mp;
16809   unformat_input_t *input = vam->input;
16810   u8 bd_set = 0;
16811   u32 bd = ~0;
16812   int ret;
16813
16814   /* Parse args required to build the message */
16815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (input, "bd %d", &bd))
16818         bd_set = 1;
16819       else
16820         {
16821           errmsg ("parse error '%U'", format_unformat_error, input);
16822           return -99;
16823         }
16824     }
16825
16826   if (!bd_set)
16827     {
16828       errmsg ("Expected bridge domain!");
16829       return -99;
16830     }
16831
16832   M (ONE_L2_ARP_ENTRIES_GET, mp);
16833   mp->bd = clib_host_to_net_u32 (bd);
16834
16835   /* send */
16836   S (mp);
16837
16838   /* wait for reply */
16839   W (ret);
16840   return ret;
16841 }
16842
16843 static int
16844 api_one_stats_enable_disable (vat_main_t * vam)
16845 {
16846   vl_api_one_stats_enable_disable_t *mp;
16847   unformat_input_t *input = vam->input;
16848   u8 is_set = 0;
16849   u8 is_en = 0;
16850   int ret;
16851
16852   /* Parse args required to build the message */
16853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16854     {
16855       if (unformat (input, "enable"))
16856         {
16857           is_set = 1;
16858           is_en = 1;
16859         }
16860       else if (unformat (input, "disable"))
16861         {
16862           is_set = 1;
16863         }
16864       else
16865         break;
16866     }
16867
16868   if (!is_set)
16869     {
16870       errmsg ("Value not set");
16871       return -99;
16872     }
16873
16874   M (ONE_STATS_ENABLE_DISABLE, mp);
16875   mp->is_en = is_en;
16876
16877   /* send */
16878   S (mp);
16879
16880   /* wait for reply */
16881   W (ret);
16882   return ret;
16883 }
16884
16885 static int
16886 api_show_one_stats_enable_disable (vat_main_t * vam)
16887 {
16888   vl_api_show_one_stats_enable_disable_t *mp;
16889   int ret;
16890
16891   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16892
16893   /* send */
16894   S (mp);
16895
16896   /* wait for reply */
16897   W (ret);
16898   return ret;
16899 }
16900
16901 static int
16902 api_show_one_map_request_mode (vat_main_t * vam)
16903 {
16904   vl_api_show_one_map_request_mode_t *mp;
16905   int ret;
16906
16907   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16908
16909   /* send */
16910   S (mp);
16911
16912   /* wait for reply */
16913   W (ret);
16914   return ret;
16915 }
16916
16917 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16918
16919 static int
16920 api_one_map_request_mode (vat_main_t * vam)
16921 {
16922   unformat_input_t *input = vam->input;
16923   vl_api_one_map_request_mode_t *mp;
16924   u8 mode = 0;
16925   int ret;
16926
16927   /* Parse args required to build the message */
16928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16929     {
16930       if (unformat (input, "dst-only"))
16931         mode = 0;
16932       else if (unformat (input, "src-dst"))
16933         mode = 1;
16934       else
16935         {
16936           errmsg ("parse error '%U'", format_unformat_error, input);
16937           return -99;
16938         }
16939     }
16940
16941   M (ONE_MAP_REQUEST_MODE, mp);
16942
16943   mp->mode = mode;
16944
16945   /* send */
16946   S (mp);
16947
16948   /* wait for reply */
16949   W (ret);
16950   return ret;
16951 }
16952
16953 #define api_lisp_map_request_mode api_one_map_request_mode
16954
16955 /**
16956  * Enable/disable ONE proxy ITR.
16957  *
16958  * @param vam vpp API test context
16959  * @return return code
16960  */
16961 static int
16962 api_one_pitr_set_locator_set (vat_main_t * vam)
16963 {
16964   u8 ls_name_set = 0;
16965   unformat_input_t *input = vam->input;
16966   vl_api_one_pitr_set_locator_set_t *mp;
16967   u8 is_add = 1;
16968   u8 *ls_name = 0;
16969   int ret;
16970
16971   /* Parse args required to build the message */
16972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16973     {
16974       if (unformat (input, "del"))
16975         is_add = 0;
16976       else if (unformat (input, "locator-set %s", &ls_name))
16977         ls_name_set = 1;
16978       else
16979         {
16980           errmsg ("parse error '%U'", format_unformat_error, input);
16981           return -99;
16982         }
16983     }
16984
16985   if (!ls_name_set)
16986     {
16987       errmsg ("locator-set name not set!");
16988       return -99;
16989     }
16990
16991   M (ONE_PITR_SET_LOCATOR_SET, mp);
16992
16993   mp->is_add = is_add;
16994   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16995   vec_free (ls_name);
16996
16997   /* send */
16998   S (mp);
16999
17000   /* wait for reply */
17001   W (ret);
17002   return ret;
17003 }
17004
17005 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17006
17007 static int
17008 api_one_nsh_set_locator_set (vat_main_t * vam)
17009 {
17010   u8 ls_name_set = 0;
17011   unformat_input_t *input = vam->input;
17012   vl_api_one_nsh_set_locator_set_t *mp;
17013   u8 is_add = 1;
17014   u8 *ls_name = 0;
17015   int ret;
17016
17017   /* Parse args required to build the message */
17018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17019     {
17020       if (unformat (input, "del"))
17021         is_add = 0;
17022       else if (unformat (input, "ls %s", &ls_name))
17023         ls_name_set = 1;
17024       else
17025         {
17026           errmsg ("parse error '%U'", format_unformat_error, input);
17027           return -99;
17028         }
17029     }
17030
17031   if (!ls_name_set && is_add)
17032     {
17033       errmsg ("locator-set name not set!");
17034       return -99;
17035     }
17036
17037   M (ONE_NSH_SET_LOCATOR_SET, mp);
17038
17039   mp->is_add = is_add;
17040   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17041   vec_free (ls_name);
17042
17043   /* send */
17044   S (mp);
17045
17046   /* wait for reply */
17047   W (ret);
17048   return ret;
17049 }
17050
17051 static int
17052 api_show_one_pitr (vat_main_t * vam)
17053 {
17054   vl_api_show_one_pitr_t *mp;
17055   int ret;
17056
17057   if (!vam->json_output)
17058     {
17059       print (vam->ofp, "%=20s", "lisp status:");
17060     }
17061
17062   M (SHOW_ONE_PITR, mp);
17063   /* send it... */
17064   S (mp);
17065
17066   /* Wait for a reply... */
17067   W (ret);
17068   return ret;
17069 }
17070
17071 #define api_show_lisp_pitr api_show_one_pitr
17072
17073 static int
17074 api_one_use_petr (vat_main_t * vam)
17075 {
17076   unformat_input_t *input = vam->input;
17077   vl_api_one_use_petr_t *mp;
17078   u8 is_add = 0;
17079   ip_address_t ip;
17080   int ret;
17081
17082   clib_memset (&ip, 0, sizeof (ip));
17083
17084   /* Parse args required to build the message */
17085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17086     {
17087       if (unformat (input, "disable"))
17088         is_add = 0;
17089       else
17090         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17091         {
17092           is_add = 1;
17093           ip_addr_version (&ip) = IP4;
17094         }
17095       else
17096         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17097         {
17098           is_add = 1;
17099           ip_addr_version (&ip) = IP6;
17100         }
17101       else
17102         {
17103           errmsg ("parse error '%U'", format_unformat_error, input);
17104           return -99;
17105         }
17106     }
17107
17108   M (ONE_USE_PETR, mp);
17109
17110   mp->is_add = is_add;
17111   if (is_add)
17112     {
17113       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17114       if (mp->is_ip4)
17115         clib_memcpy (mp->address, &ip, 4);
17116       else
17117         clib_memcpy (mp->address, &ip, 16);
17118     }
17119
17120   /* send */
17121   S (mp);
17122
17123   /* wait for reply */
17124   W (ret);
17125   return ret;
17126 }
17127
17128 #define api_lisp_use_petr api_one_use_petr
17129
17130 static int
17131 api_show_one_nsh_mapping (vat_main_t * vam)
17132 {
17133   vl_api_show_one_use_petr_t *mp;
17134   int ret;
17135
17136   if (!vam->json_output)
17137     {
17138       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17139     }
17140
17141   M (SHOW_ONE_NSH_MAPPING, mp);
17142   /* send it... */
17143   S (mp);
17144
17145   /* Wait for a reply... */
17146   W (ret);
17147   return ret;
17148 }
17149
17150 static int
17151 api_show_one_use_petr (vat_main_t * vam)
17152 {
17153   vl_api_show_one_use_petr_t *mp;
17154   int ret;
17155
17156   if (!vam->json_output)
17157     {
17158       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17159     }
17160
17161   M (SHOW_ONE_USE_PETR, mp);
17162   /* send it... */
17163   S (mp);
17164
17165   /* Wait for a reply... */
17166   W (ret);
17167   return ret;
17168 }
17169
17170 #define api_show_lisp_use_petr api_show_one_use_petr
17171
17172 /**
17173  * Add/delete mapping between vni and vrf
17174  */
17175 static int
17176 api_one_eid_table_add_del_map (vat_main_t * vam)
17177 {
17178   unformat_input_t *input = vam->input;
17179   vl_api_one_eid_table_add_del_map_t *mp;
17180   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17181   u32 vni, vrf, bd_index;
17182   int ret;
17183
17184   /* Parse args required to build the message */
17185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17186     {
17187       if (unformat (input, "del"))
17188         is_add = 0;
17189       else if (unformat (input, "vrf %d", &vrf))
17190         vrf_set = 1;
17191       else if (unformat (input, "bd_index %d", &bd_index))
17192         bd_index_set = 1;
17193       else if (unformat (input, "vni %d", &vni))
17194         vni_set = 1;
17195       else
17196         break;
17197     }
17198
17199   if (!vni_set || (!vrf_set && !bd_index_set))
17200     {
17201       errmsg ("missing arguments!");
17202       return -99;
17203     }
17204
17205   if (vrf_set && bd_index_set)
17206     {
17207       errmsg ("error: both vrf and bd entered!");
17208       return -99;
17209     }
17210
17211   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17212
17213   mp->is_add = is_add;
17214   mp->vni = htonl (vni);
17215   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17216   mp->is_l2 = bd_index_set;
17217
17218   /* send */
17219   S (mp);
17220
17221   /* wait for reply */
17222   W (ret);
17223   return ret;
17224 }
17225
17226 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17227
17228 uword
17229 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17230 {
17231   u32 *action = va_arg (*args, u32 *);
17232   u8 *s = 0;
17233
17234   if (unformat (input, "%s", &s))
17235     {
17236       if (!strcmp ((char *) s, "no-action"))
17237         action[0] = 0;
17238       else if (!strcmp ((char *) s, "natively-forward"))
17239         action[0] = 1;
17240       else if (!strcmp ((char *) s, "send-map-request"))
17241         action[0] = 2;
17242       else if (!strcmp ((char *) s, "drop"))
17243         action[0] = 3;
17244       else
17245         {
17246           clib_warning ("invalid action: '%s'", s);
17247           action[0] = 3;
17248         }
17249     }
17250   else
17251     return 0;
17252
17253   vec_free (s);
17254   return 1;
17255 }
17256
17257 /**
17258  * Add/del remote mapping to/from ONE control plane
17259  *
17260  * @param vam vpp API test context
17261  * @return return code
17262  */
17263 static int
17264 api_one_add_del_remote_mapping (vat_main_t * vam)
17265 {
17266   unformat_input_t *input = vam->input;
17267   vl_api_one_add_del_remote_mapping_t *mp;
17268   u32 vni = 0;
17269   lisp_eid_vat_t _eid, *eid = &_eid;
17270   lisp_eid_vat_t _seid, *seid = &_seid;
17271   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17272   u32 action = ~0, p, w, data_len;
17273   ip4_address_t rloc4;
17274   ip6_address_t rloc6;
17275   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17276   int ret;
17277
17278   clib_memset (&rloc, 0, sizeof (rloc));
17279
17280   /* Parse args required to build the message */
17281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17282     {
17283       if (unformat (input, "del-all"))
17284         {
17285           del_all = 1;
17286         }
17287       else if (unformat (input, "del"))
17288         {
17289           is_add = 0;
17290         }
17291       else if (unformat (input, "add"))
17292         {
17293           is_add = 1;
17294         }
17295       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17296         {
17297           eid_set = 1;
17298         }
17299       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17300         {
17301           seid_set = 1;
17302         }
17303       else if (unformat (input, "vni %d", &vni))
17304         {
17305           ;
17306         }
17307       else if (unformat (input, "p %d w %d", &p, &w))
17308         {
17309           if (!curr_rloc)
17310             {
17311               errmsg ("No RLOC configured for setting priority/weight!");
17312               return -99;
17313             }
17314           curr_rloc->priority = p;
17315           curr_rloc->weight = w;
17316         }
17317       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17318         {
17319           rloc.is_ip4 = 1;
17320           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17321           vec_add1 (rlocs, rloc);
17322           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17323         }
17324       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17325         {
17326           rloc.is_ip4 = 0;
17327           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17328           vec_add1 (rlocs, rloc);
17329           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17330         }
17331       else if (unformat (input, "action %U",
17332                          unformat_negative_mapping_action, &action))
17333         {
17334           ;
17335         }
17336       else
17337         {
17338           clib_warning ("parse error '%U'", format_unformat_error, input);
17339           return -99;
17340         }
17341     }
17342
17343   if (0 == eid_set)
17344     {
17345       errmsg ("missing params!");
17346       return -99;
17347     }
17348
17349   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17350     {
17351       errmsg ("no action set for negative map-reply!");
17352       return -99;
17353     }
17354
17355   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17356
17357   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17358   mp->is_add = is_add;
17359   mp->vni = htonl (vni);
17360   mp->action = (u8) action;
17361   mp->is_src_dst = seid_set;
17362   mp->eid_len = eid->len;
17363   mp->seid_len = seid->len;
17364   mp->del_all = del_all;
17365   mp->eid_type = eid->type;
17366   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17367   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17368
17369   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17370   clib_memcpy (mp->rlocs, rlocs, data_len);
17371   vec_free (rlocs);
17372
17373   /* send it... */
17374   S (mp);
17375
17376   /* Wait for a reply... */
17377   W (ret);
17378   return ret;
17379 }
17380
17381 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17382
17383 /**
17384  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17385  * forwarding entries in data-plane accordingly.
17386  *
17387  * @param vam vpp API test context
17388  * @return return code
17389  */
17390 static int
17391 api_one_add_del_adjacency (vat_main_t * vam)
17392 {
17393   unformat_input_t *input = vam->input;
17394   vl_api_one_add_del_adjacency_t *mp;
17395   u32 vni = 0;
17396   ip4_address_t leid4, reid4;
17397   ip6_address_t leid6, reid6;
17398   u8 reid_mac[6] = { 0 };
17399   u8 leid_mac[6] = { 0 };
17400   u8 reid_type, leid_type;
17401   u32 leid_len = 0, reid_len = 0, len;
17402   u8 is_add = 1;
17403   int ret;
17404
17405   leid_type = reid_type = (u8) ~ 0;
17406
17407   /* Parse args required to build the message */
17408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17409     {
17410       if (unformat (input, "del"))
17411         {
17412           is_add = 0;
17413         }
17414       else if (unformat (input, "add"))
17415         {
17416           is_add = 1;
17417         }
17418       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17419                          &reid4, &len))
17420         {
17421           reid_type = 0;        /* ipv4 */
17422           reid_len = len;
17423         }
17424       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17425                          &reid6, &len))
17426         {
17427           reid_type = 1;        /* ipv6 */
17428           reid_len = len;
17429         }
17430       else if (unformat (input, "reid %U", unformat_ethernet_address,
17431                          reid_mac))
17432         {
17433           reid_type = 2;        /* mac */
17434         }
17435       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17436                          &leid4, &len))
17437         {
17438           leid_type = 0;        /* ipv4 */
17439           leid_len = len;
17440         }
17441       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17442                          &leid6, &len))
17443         {
17444           leid_type = 1;        /* ipv6 */
17445           leid_len = len;
17446         }
17447       else if (unformat (input, "leid %U", unformat_ethernet_address,
17448                          leid_mac))
17449         {
17450           leid_type = 2;        /* mac */
17451         }
17452       else if (unformat (input, "vni %d", &vni))
17453         {
17454           ;
17455         }
17456       else
17457         {
17458           errmsg ("parse error '%U'", format_unformat_error, input);
17459           return -99;
17460         }
17461     }
17462
17463   if ((u8) ~ 0 == reid_type)
17464     {
17465       errmsg ("missing params!");
17466       return -99;
17467     }
17468
17469   if (leid_type != reid_type)
17470     {
17471       errmsg ("remote and local EIDs are of different types!");
17472       return -99;
17473     }
17474
17475   M (ONE_ADD_DEL_ADJACENCY, mp);
17476   mp->is_add = is_add;
17477   mp->vni = htonl (vni);
17478   mp->leid_len = leid_len;
17479   mp->reid_len = reid_len;
17480   mp->eid_type = reid_type;
17481
17482   switch (mp->eid_type)
17483     {
17484     case 0:
17485       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17486       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17487       break;
17488     case 1:
17489       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17490       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17491       break;
17492     case 2:
17493       clib_memcpy (mp->leid, leid_mac, 6);
17494       clib_memcpy (mp->reid, reid_mac, 6);
17495       break;
17496     default:
17497       errmsg ("unknown EID type %d!", mp->eid_type);
17498       return 0;
17499     }
17500
17501   /* send it... */
17502   S (mp);
17503
17504   /* Wait for a reply... */
17505   W (ret);
17506   return ret;
17507 }
17508
17509 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17510
17511 uword
17512 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17513 {
17514   u32 *mode = va_arg (*args, u32 *);
17515
17516   if (unformat (input, "lisp"))
17517     *mode = 0;
17518   else if (unformat (input, "vxlan"))
17519     *mode = 1;
17520   else
17521     return 0;
17522
17523   return 1;
17524 }
17525
17526 static int
17527 api_gpe_get_encap_mode (vat_main_t * vam)
17528 {
17529   vl_api_gpe_get_encap_mode_t *mp;
17530   int ret;
17531
17532   /* Construct the API message */
17533   M (GPE_GET_ENCAP_MODE, mp);
17534
17535   /* send it... */
17536   S (mp);
17537
17538   /* Wait for a reply... */
17539   W (ret);
17540   return ret;
17541 }
17542
17543 static int
17544 api_gpe_set_encap_mode (vat_main_t * vam)
17545 {
17546   unformat_input_t *input = vam->input;
17547   vl_api_gpe_set_encap_mode_t *mp;
17548   int ret;
17549   u32 mode = 0;
17550
17551   /* Parse args required to build the message */
17552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17553     {
17554       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17555         ;
17556       else
17557         break;
17558     }
17559
17560   /* Construct the API message */
17561   M (GPE_SET_ENCAP_MODE, mp);
17562
17563   mp->mode = mode;
17564
17565   /* send it... */
17566   S (mp);
17567
17568   /* Wait for a reply... */
17569   W (ret);
17570   return ret;
17571 }
17572
17573 static int
17574 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17575 {
17576   unformat_input_t *input = vam->input;
17577   vl_api_gpe_add_del_iface_t *mp;
17578   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17579   u32 dp_table = 0, vni = 0;
17580   int ret;
17581
17582   /* Parse args required to build the message */
17583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17584     {
17585       if (unformat (input, "up"))
17586         {
17587           action_set = 1;
17588           is_add = 1;
17589         }
17590       else if (unformat (input, "down"))
17591         {
17592           action_set = 1;
17593           is_add = 0;
17594         }
17595       else if (unformat (input, "table_id %d", &dp_table))
17596         {
17597           dp_table_set = 1;
17598         }
17599       else if (unformat (input, "bd_id %d", &dp_table))
17600         {
17601           dp_table_set = 1;
17602           is_l2 = 1;
17603         }
17604       else if (unformat (input, "vni %d", &vni))
17605         {
17606           vni_set = 1;
17607         }
17608       else
17609         break;
17610     }
17611
17612   if (action_set == 0)
17613     {
17614       errmsg ("Action not set");
17615       return -99;
17616     }
17617   if (dp_table_set == 0 || vni_set == 0)
17618     {
17619       errmsg ("vni and dp_table must be set");
17620       return -99;
17621     }
17622
17623   /* Construct the API message */
17624   M (GPE_ADD_DEL_IFACE, mp);
17625
17626   mp->is_add = is_add;
17627   mp->dp_table = clib_host_to_net_u32 (dp_table);
17628   mp->is_l2 = is_l2;
17629   mp->vni = clib_host_to_net_u32 (vni);
17630
17631   /* send it... */
17632   S (mp);
17633
17634   /* Wait for a reply... */
17635   W (ret);
17636   return ret;
17637 }
17638
17639 static int
17640 api_one_map_register_fallback_threshold (vat_main_t * vam)
17641 {
17642   unformat_input_t *input = vam->input;
17643   vl_api_one_map_register_fallback_threshold_t *mp;
17644   u32 value = 0;
17645   u8 is_set = 0;
17646   int ret;
17647
17648   /* Parse args required to build the message */
17649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17650     {
17651       if (unformat (input, "%u", &value))
17652         is_set = 1;
17653       else
17654         {
17655           clib_warning ("parse error '%U'", format_unformat_error, input);
17656           return -99;
17657         }
17658     }
17659
17660   if (!is_set)
17661     {
17662       errmsg ("fallback threshold value is missing!");
17663       return -99;
17664     }
17665
17666   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17667   mp->value = clib_host_to_net_u32 (value);
17668
17669   /* send it... */
17670   S (mp);
17671
17672   /* Wait for a reply... */
17673   W (ret);
17674   return ret;
17675 }
17676
17677 static int
17678 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17679 {
17680   vl_api_show_one_map_register_fallback_threshold_t *mp;
17681   int ret;
17682
17683   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17684
17685   /* send it... */
17686   S (mp);
17687
17688   /* Wait for a reply... */
17689   W (ret);
17690   return ret;
17691 }
17692
17693 uword
17694 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17695 {
17696   u32 *proto = va_arg (*args, u32 *);
17697
17698   if (unformat (input, "udp"))
17699     *proto = 1;
17700   else if (unformat (input, "api"))
17701     *proto = 2;
17702   else
17703     return 0;
17704
17705   return 1;
17706 }
17707
17708 static int
17709 api_one_set_transport_protocol (vat_main_t * vam)
17710 {
17711   unformat_input_t *input = vam->input;
17712   vl_api_one_set_transport_protocol_t *mp;
17713   u8 is_set = 0;
17714   u32 protocol = 0;
17715   int ret;
17716
17717   /* Parse args required to build the message */
17718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17719     {
17720       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17721         is_set = 1;
17722       else
17723         {
17724           clib_warning ("parse error '%U'", format_unformat_error, input);
17725           return -99;
17726         }
17727     }
17728
17729   if (!is_set)
17730     {
17731       errmsg ("Transport protocol missing!");
17732       return -99;
17733     }
17734
17735   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17736   mp->protocol = (u8) protocol;
17737
17738   /* send it... */
17739   S (mp);
17740
17741   /* Wait for a reply... */
17742   W (ret);
17743   return ret;
17744 }
17745
17746 static int
17747 api_one_get_transport_protocol (vat_main_t * vam)
17748 {
17749   vl_api_one_get_transport_protocol_t *mp;
17750   int ret;
17751
17752   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17753
17754   /* send it... */
17755   S (mp);
17756
17757   /* Wait for a reply... */
17758   W (ret);
17759   return ret;
17760 }
17761
17762 static int
17763 api_one_map_register_set_ttl (vat_main_t * vam)
17764 {
17765   unformat_input_t *input = vam->input;
17766   vl_api_one_map_register_set_ttl_t *mp;
17767   u32 ttl = 0;
17768   u8 is_set = 0;
17769   int ret;
17770
17771   /* Parse args required to build the message */
17772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17773     {
17774       if (unformat (input, "%u", &ttl))
17775         is_set = 1;
17776       else
17777         {
17778           clib_warning ("parse error '%U'", format_unformat_error, input);
17779           return -99;
17780         }
17781     }
17782
17783   if (!is_set)
17784     {
17785       errmsg ("TTL value missing!");
17786       return -99;
17787     }
17788
17789   M (ONE_MAP_REGISTER_SET_TTL, mp);
17790   mp->ttl = clib_host_to_net_u32 (ttl);
17791
17792   /* send it... */
17793   S (mp);
17794
17795   /* Wait for a reply... */
17796   W (ret);
17797   return ret;
17798 }
17799
17800 static int
17801 api_show_one_map_register_ttl (vat_main_t * vam)
17802 {
17803   vl_api_show_one_map_register_ttl_t *mp;
17804   int ret;
17805
17806   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17807
17808   /* send it... */
17809   S (mp);
17810
17811   /* Wait for a reply... */
17812   W (ret);
17813   return ret;
17814 }
17815
17816 /**
17817  * Add/del map request itr rlocs from ONE control plane and updates
17818  *
17819  * @param vam vpp API test context
17820  * @return return code
17821  */
17822 static int
17823 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17824 {
17825   unformat_input_t *input = vam->input;
17826   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17827   u8 *locator_set_name = 0;
17828   u8 locator_set_name_set = 0;
17829   u8 is_add = 1;
17830   int ret;
17831
17832   /* Parse args required to build the message */
17833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17834     {
17835       if (unformat (input, "del"))
17836         {
17837           is_add = 0;
17838         }
17839       else if (unformat (input, "%_%v%_", &locator_set_name))
17840         {
17841           locator_set_name_set = 1;
17842         }
17843       else
17844         {
17845           clib_warning ("parse error '%U'", format_unformat_error, input);
17846           return -99;
17847         }
17848     }
17849
17850   if (is_add && !locator_set_name_set)
17851     {
17852       errmsg ("itr-rloc is not set!");
17853       return -99;
17854     }
17855
17856   if (is_add && vec_len (locator_set_name) > 64)
17857     {
17858       errmsg ("itr-rloc locator-set name too long");
17859       vec_free (locator_set_name);
17860       return -99;
17861     }
17862
17863   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17864   mp->is_add = is_add;
17865   if (is_add)
17866     {
17867       clib_memcpy (mp->locator_set_name, locator_set_name,
17868                    vec_len (locator_set_name));
17869     }
17870   else
17871     {
17872       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17873     }
17874   vec_free (locator_set_name);
17875
17876   /* send it... */
17877   S (mp);
17878
17879   /* Wait for a reply... */
17880   W (ret);
17881   return ret;
17882 }
17883
17884 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17885
17886 static int
17887 api_one_locator_dump (vat_main_t * vam)
17888 {
17889   unformat_input_t *input = vam->input;
17890   vl_api_one_locator_dump_t *mp;
17891   vl_api_control_ping_t *mp_ping;
17892   u8 is_index_set = 0, is_name_set = 0;
17893   u8 *ls_name = 0;
17894   u32 ls_index = ~0;
17895   int ret;
17896
17897   /* Parse args required to build the message */
17898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17899     {
17900       if (unformat (input, "ls_name %_%v%_", &ls_name))
17901         {
17902           is_name_set = 1;
17903         }
17904       else if (unformat (input, "ls_index %d", &ls_index))
17905         {
17906           is_index_set = 1;
17907         }
17908       else
17909         {
17910           errmsg ("parse error '%U'", format_unformat_error, input);
17911           return -99;
17912         }
17913     }
17914
17915   if (!is_index_set && !is_name_set)
17916     {
17917       errmsg ("error: expected one of index or name!");
17918       return -99;
17919     }
17920
17921   if (is_index_set && is_name_set)
17922     {
17923       errmsg ("error: only one param expected!");
17924       return -99;
17925     }
17926
17927   if (vec_len (ls_name) > 62)
17928     {
17929       errmsg ("error: locator set name too long!");
17930       return -99;
17931     }
17932
17933   if (!vam->json_output)
17934     {
17935       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17936     }
17937
17938   M (ONE_LOCATOR_DUMP, mp);
17939   mp->is_index_set = is_index_set;
17940
17941   if (is_index_set)
17942     mp->ls_index = clib_host_to_net_u32 (ls_index);
17943   else
17944     {
17945       vec_add1 (ls_name, 0);
17946       strncpy ((char *) mp->ls_name, (char *) ls_name,
17947                sizeof (mp->ls_name) - 1);
17948     }
17949
17950   /* send it... */
17951   S (mp);
17952
17953   /* Use a control ping for synchronization */
17954   MPING (CONTROL_PING, mp_ping);
17955   S (mp_ping);
17956
17957   /* Wait for a reply... */
17958   W (ret);
17959   return ret;
17960 }
17961
17962 #define api_lisp_locator_dump api_one_locator_dump
17963
17964 static int
17965 api_one_locator_set_dump (vat_main_t * vam)
17966 {
17967   vl_api_one_locator_set_dump_t *mp;
17968   vl_api_control_ping_t *mp_ping;
17969   unformat_input_t *input = vam->input;
17970   u8 filter = 0;
17971   int ret;
17972
17973   /* Parse args required to build the message */
17974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17975     {
17976       if (unformat (input, "local"))
17977         {
17978           filter = 1;
17979         }
17980       else if (unformat (input, "remote"))
17981         {
17982           filter = 2;
17983         }
17984       else
17985         {
17986           errmsg ("parse error '%U'", format_unformat_error, input);
17987           return -99;
17988         }
17989     }
17990
17991   if (!vam->json_output)
17992     {
17993       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17994     }
17995
17996   M (ONE_LOCATOR_SET_DUMP, mp);
17997
17998   mp->filter = filter;
17999
18000   /* send it... */
18001   S (mp);
18002
18003   /* Use a control ping for synchronization */
18004   MPING (CONTROL_PING, mp_ping);
18005   S (mp_ping);
18006
18007   /* Wait for a reply... */
18008   W (ret);
18009   return ret;
18010 }
18011
18012 #define api_lisp_locator_set_dump api_one_locator_set_dump
18013
18014 static int
18015 api_one_eid_table_map_dump (vat_main_t * vam)
18016 {
18017   u8 is_l2 = 0;
18018   u8 mode_set = 0;
18019   unformat_input_t *input = vam->input;
18020   vl_api_one_eid_table_map_dump_t *mp;
18021   vl_api_control_ping_t *mp_ping;
18022   int ret;
18023
18024   /* Parse args required to build the message */
18025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18026     {
18027       if (unformat (input, "l2"))
18028         {
18029           is_l2 = 1;
18030           mode_set = 1;
18031         }
18032       else if (unformat (input, "l3"))
18033         {
18034           is_l2 = 0;
18035           mode_set = 1;
18036         }
18037       else
18038         {
18039           errmsg ("parse error '%U'", format_unformat_error, input);
18040           return -99;
18041         }
18042     }
18043
18044   if (!mode_set)
18045     {
18046       errmsg ("expected one of 'l2' or 'l3' parameter!");
18047       return -99;
18048     }
18049
18050   if (!vam->json_output)
18051     {
18052       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18053     }
18054
18055   M (ONE_EID_TABLE_MAP_DUMP, mp);
18056   mp->is_l2 = is_l2;
18057
18058   /* send it... */
18059   S (mp);
18060
18061   /* Use a control ping for synchronization */
18062   MPING (CONTROL_PING, mp_ping);
18063   S (mp_ping);
18064
18065   /* Wait for a reply... */
18066   W (ret);
18067   return ret;
18068 }
18069
18070 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18071
18072 static int
18073 api_one_eid_table_vni_dump (vat_main_t * vam)
18074 {
18075   vl_api_one_eid_table_vni_dump_t *mp;
18076   vl_api_control_ping_t *mp_ping;
18077   int ret;
18078
18079   if (!vam->json_output)
18080     {
18081       print (vam->ofp, "VNI");
18082     }
18083
18084   M (ONE_EID_TABLE_VNI_DUMP, mp);
18085
18086   /* send it... */
18087   S (mp);
18088
18089   /* Use a control ping for synchronization */
18090   MPING (CONTROL_PING, mp_ping);
18091   S (mp_ping);
18092
18093   /* Wait for a reply... */
18094   W (ret);
18095   return ret;
18096 }
18097
18098 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18099
18100 static int
18101 api_one_eid_table_dump (vat_main_t * vam)
18102 {
18103   unformat_input_t *i = vam->input;
18104   vl_api_one_eid_table_dump_t *mp;
18105   vl_api_control_ping_t *mp_ping;
18106   struct in_addr ip4;
18107   struct in6_addr ip6;
18108   u8 mac[6];
18109   u8 eid_type = ~0, eid_set = 0;
18110   u32 prefix_length = ~0, t, vni = 0;
18111   u8 filter = 0;
18112   int ret;
18113   lisp_nsh_api_t nsh;
18114
18115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18116     {
18117       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18118         {
18119           eid_set = 1;
18120           eid_type = 0;
18121           prefix_length = t;
18122         }
18123       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18124         {
18125           eid_set = 1;
18126           eid_type = 1;
18127           prefix_length = t;
18128         }
18129       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18130         {
18131           eid_set = 1;
18132           eid_type = 2;
18133         }
18134       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18135         {
18136           eid_set = 1;
18137           eid_type = 3;
18138         }
18139       else if (unformat (i, "vni %d", &t))
18140         {
18141           vni = t;
18142         }
18143       else if (unformat (i, "local"))
18144         {
18145           filter = 1;
18146         }
18147       else if (unformat (i, "remote"))
18148         {
18149           filter = 2;
18150         }
18151       else
18152         {
18153           errmsg ("parse error '%U'", format_unformat_error, i);
18154           return -99;
18155         }
18156     }
18157
18158   if (!vam->json_output)
18159     {
18160       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18161              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18162     }
18163
18164   M (ONE_EID_TABLE_DUMP, mp);
18165
18166   mp->filter = filter;
18167   if (eid_set)
18168     {
18169       mp->eid_set = 1;
18170       mp->vni = htonl (vni);
18171       mp->eid_type = eid_type;
18172       switch (eid_type)
18173         {
18174         case 0:
18175           mp->prefix_length = prefix_length;
18176           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18177           break;
18178         case 1:
18179           mp->prefix_length = prefix_length;
18180           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18181           break;
18182         case 2:
18183           clib_memcpy (mp->eid, mac, sizeof (mac));
18184           break;
18185         case 3:
18186           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18187           break;
18188         default:
18189           errmsg ("unknown EID type %d!", eid_type);
18190           return -99;
18191         }
18192     }
18193
18194   /* send it... */
18195   S (mp);
18196
18197   /* Use a control ping for synchronization */
18198   MPING (CONTROL_PING, mp_ping);
18199   S (mp_ping);
18200
18201   /* Wait for a reply... */
18202   W (ret);
18203   return ret;
18204 }
18205
18206 #define api_lisp_eid_table_dump api_one_eid_table_dump
18207
18208 static int
18209 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18210 {
18211   unformat_input_t *i = vam->input;
18212   vl_api_gpe_fwd_entries_get_t *mp;
18213   u8 vni_set = 0;
18214   u32 vni = ~0;
18215   int ret;
18216
18217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18218     {
18219       if (unformat (i, "vni %d", &vni))
18220         {
18221           vni_set = 1;
18222         }
18223       else
18224         {
18225           errmsg ("parse error '%U'", format_unformat_error, i);
18226           return -99;
18227         }
18228     }
18229
18230   if (!vni_set)
18231     {
18232       errmsg ("vni not set!");
18233       return -99;
18234     }
18235
18236   if (!vam->json_output)
18237     {
18238       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18239              "leid", "reid");
18240     }
18241
18242   M (GPE_FWD_ENTRIES_GET, mp);
18243   mp->vni = clib_host_to_net_u32 (vni);
18244
18245   /* send it... */
18246   S (mp);
18247
18248   /* Wait for a reply... */
18249   W (ret);
18250   return ret;
18251 }
18252
18253 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18254 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18255 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18256 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18257 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18258 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18259 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18260 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18261
18262 static int
18263 api_one_adjacencies_get (vat_main_t * vam)
18264 {
18265   unformat_input_t *i = vam->input;
18266   vl_api_one_adjacencies_get_t *mp;
18267   u8 vni_set = 0;
18268   u32 vni = ~0;
18269   int ret;
18270
18271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18272     {
18273       if (unformat (i, "vni %d", &vni))
18274         {
18275           vni_set = 1;
18276         }
18277       else
18278         {
18279           errmsg ("parse error '%U'", format_unformat_error, i);
18280           return -99;
18281         }
18282     }
18283
18284   if (!vni_set)
18285     {
18286       errmsg ("vni not set!");
18287       return -99;
18288     }
18289
18290   if (!vam->json_output)
18291     {
18292       print (vam->ofp, "%s %40s", "leid", "reid");
18293     }
18294
18295   M (ONE_ADJACENCIES_GET, mp);
18296   mp->vni = clib_host_to_net_u32 (vni);
18297
18298   /* send it... */
18299   S (mp);
18300
18301   /* Wait for a reply... */
18302   W (ret);
18303   return ret;
18304 }
18305
18306 #define api_lisp_adjacencies_get api_one_adjacencies_get
18307
18308 static int
18309 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18310 {
18311   unformat_input_t *i = vam->input;
18312   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18313   int ret;
18314   u8 ip_family_set = 0, is_ip4 = 1;
18315
18316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18317     {
18318       if (unformat (i, "ip4"))
18319         {
18320           ip_family_set = 1;
18321           is_ip4 = 1;
18322         }
18323       else if (unformat (i, "ip6"))
18324         {
18325           ip_family_set = 1;
18326           is_ip4 = 0;
18327         }
18328       else
18329         {
18330           errmsg ("parse error '%U'", format_unformat_error, i);
18331           return -99;
18332         }
18333     }
18334
18335   if (!ip_family_set)
18336     {
18337       errmsg ("ip family not set!");
18338       return -99;
18339     }
18340
18341   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18342   mp->is_ip4 = is_ip4;
18343
18344   /* send it... */
18345   S (mp);
18346
18347   /* Wait for a reply... */
18348   W (ret);
18349   return ret;
18350 }
18351
18352 static int
18353 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18354 {
18355   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18356   int ret;
18357
18358   if (!vam->json_output)
18359     {
18360       print (vam->ofp, "VNIs");
18361     }
18362
18363   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18364
18365   /* send it... */
18366   S (mp);
18367
18368   /* Wait for a reply... */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 static int
18374 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18375 {
18376   unformat_input_t *i = vam->input;
18377   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18378   int ret = 0;
18379   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18380   struct in_addr ip4;
18381   struct in6_addr ip6;
18382   u32 table_id = 0, nh_sw_if_index = ~0;
18383
18384   clib_memset (&ip4, 0, sizeof (ip4));
18385   clib_memset (&ip6, 0, sizeof (ip6));
18386
18387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18388     {
18389       if (unformat (i, "del"))
18390         is_add = 0;
18391       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18392                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18393         {
18394           ip_set = 1;
18395           is_ip4 = 1;
18396         }
18397       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18398                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18399         {
18400           ip_set = 1;
18401           is_ip4 = 0;
18402         }
18403       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18404         {
18405           ip_set = 1;
18406           is_ip4 = 1;
18407           nh_sw_if_index = ~0;
18408         }
18409       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18410         {
18411           ip_set = 1;
18412           is_ip4 = 0;
18413           nh_sw_if_index = ~0;
18414         }
18415       else if (unformat (i, "table %d", &table_id))
18416         ;
18417       else
18418         {
18419           errmsg ("parse error '%U'", format_unformat_error, i);
18420           return -99;
18421         }
18422     }
18423
18424   if (!ip_set)
18425     {
18426       errmsg ("nh addr not set!");
18427       return -99;
18428     }
18429
18430   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18431   mp->is_add = is_add;
18432   mp->table_id = clib_host_to_net_u32 (table_id);
18433   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18434   mp->is_ip4 = is_ip4;
18435   if (is_ip4)
18436     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18437   else
18438     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18439
18440   /* send it... */
18441   S (mp);
18442
18443   /* Wait for a reply... */
18444   W (ret);
18445   return ret;
18446 }
18447
18448 static int
18449 api_one_map_server_dump (vat_main_t * vam)
18450 {
18451   vl_api_one_map_server_dump_t *mp;
18452   vl_api_control_ping_t *mp_ping;
18453   int ret;
18454
18455   if (!vam->json_output)
18456     {
18457       print (vam->ofp, "%=20s", "Map server");
18458     }
18459
18460   M (ONE_MAP_SERVER_DUMP, mp);
18461   /* send it... */
18462   S (mp);
18463
18464   /* Use a control ping for synchronization */
18465   MPING (CONTROL_PING, mp_ping);
18466   S (mp_ping);
18467
18468   /* Wait for a reply... */
18469   W (ret);
18470   return ret;
18471 }
18472
18473 #define api_lisp_map_server_dump api_one_map_server_dump
18474
18475 static int
18476 api_one_map_resolver_dump (vat_main_t * vam)
18477 {
18478   vl_api_one_map_resolver_dump_t *mp;
18479   vl_api_control_ping_t *mp_ping;
18480   int ret;
18481
18482   if (!vam->json_output)
18483     {
18484       print (vam->ofp, "%=20s", "Map resolver");
18485     }
18486
18487   M (ONE_MAP_RESOLVER_DUMP, mp);
18488   /* send it... */
18489   S (mp);
18490
18491   /* Use a control ping for synchronization */
18492   MPING (CONTROL_PING, mp_ping);
18493   S (mp_ping);
18494
18495   /* Wait for a reply... */
18496   W (ret);
18497   return ret;
18498 }
18499
18500 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18501
18502 static int
18503 api_one_stats_flush (vat_main_t * vam)
18504 {
18505   vl_api_one_stats_flush_t *mp;
18506   int ret = 0;
18507
18508   M (ONE_STATS_FLUSH, mp);
18509   S (mp);
18510   W (ret);
18511   return ret;
18512 }
18513
18514 static int
18515 api_one_stats_dump (vat_main_t * vam)
18516 {
18517   vl_api_one_stats_dump_t *mp;
18518   vl_api_control_ping_t *mp_ping;
18519   int ret;
18520
18521   M (ONE_STATS_DUMP, mp);
18522   /* send it... */
18523   S (mp);
18524
18525   /* Use a control ping for synchronization */
18526   MPING (CONTROL_PING, mp_ping);
18527   S (mp_ping);
18528
18529   /* Wait for a reply... */
18530   W (ret);
18531   return ret;
18532 }
18533
18534 static int
18535 api_show_one_status (vat_main_t * vam)
18536 {
18537   vl_api_show_one_status_t *mp;
18538   int ret;
18539
18540   if (!vam->json_output)
18541     {
18542       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18543     }
18544
18545   M (SHOW_ONE_STATUS, mp);
18546   /* send it... */
18547   S (mp);
18548   /* Wait for a reply... */
18549   W (ret);
18550   return ret;
18551 }
18552
18553 #define api_show_lisp_status api_show_one_status
18554
18555 static int
18556 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18557 {
18558   vl_api_gpe_fwd_entry_path_dump_t *mp;
18559   vl_api_control_ping_t *mp_ping;
18560   unformat_input_t *i = vam->input;
18561   u32 fwd_entry_index = ~0;
18562   int ret;
18563
18564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18565     {
18566       if (unformat (i, "index %d", &fwd_entry_index))
18567         ;
18568       else
18569         break;
18570     }
18571
18572   if (~0 == fwd_entry_index)
18573     {
18574       errmsg ("no index specified!");
18575       return -99;
18576     }
18577
18578   if (!vam->json_output)
18579     {
18580       print (vam->ofp, "first line");
18581     }
18582
18583   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18584
18585   /* send it... */
18586   S (mp);
18587   /* Use a control ping for synchronization */
18588   MPING (CONTROL_PING, mp_ping);
18589   S (mp_ping);
18590
18591   /* Wait for a reply... */
18592   W (ret);
18593   return ret;
18594 }
18595
18596 static int
18597 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18598 {
18599   vl_api_one_get_map_request_itr_rlocs_t *mp;
18600   int ret;
18601
18602   if (!vam->json_output)
18603     {
18604       print (vam->ofp, "%=20s", "itr-rlocs:");
18605     }
18606
18607   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18608   /* send it... */
18609   S (mp);
18610   /* Wait for a reply... */
18611   W (ret);
18612   return ret;
18613 }
18614
18615 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18616
18617 static int
18618 api_af_packet_create (vat_main_t * vam)
18619 {
18620   unformat_input_t *i = vam->input;
18621   vl_api_af_packet_create_t *mp;
18622   u8 *host_if_name = 0;
18623   u8 hw_addr[6];
18624   u8 random_hw_addr = 1;
18625   int ret;
18626
18627   clib_memset (hw_addr, 0, sizeof (hw_addr));
18628
18629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18630     {
18631       if (unformat (i, "name %s", &host_if_name))
18632         vec_add1 (host_if_name, 0);
18633       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18634         random_hw_addr = 0;
18635       else
18636         break;
18637     }
18638
18639   if (!vec_len (host_if_name))
18640     {
18641       errmsg ("host-interface name must be specified");
18642       return -99;
18643     }
18644
18645   if (vec_len (host_if_name) > 64)
18646     {
18647       errmsg ("host-interface name too long");
18648       return -99;
18649     }
18650
18651   M (AF_PACKET_CREATE, mp);
18652
18653   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18654   clib_memcpy (mp->hw_addr, hw_addr, 6);
18655   mp->use_random_hw_addr = random_hw_addr;
18656   vec_free (host_if_name);
18657
18658   S (mp);
18659
18660   /* *INDENT-OFF* */
18661   W2 (ret,
18662       ({
18663         if (ret == 0)
18664           fprintf (vam->ofp ? vam->ofp : stderr,
18665                    " new sw_if_index = %d\n", vam->sw_if_index);
18666       }));
18667   /* *INDENT-ON* */
18668   return ret;
18669 }
18670
18671 static int
18672 api_af_packet_delete (vat_main_t * vam)
18673 {
18674   unformat_input_t *i = vam->input;
18675   vl_api_af_packet_delete_t *mp;
18676   u8 *host_if_name = 0;
18677   int ret;
18678
18679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18680     {
18681       if (unformat (i, "name %s", &host_if_name))
18682         vec_add1 (host_if_name, 0);
18683       else
18684         break;
18685     }
18686
18687   if (!vec_len (host_if_name))
18688     {
18689       errmsg ("host-interface name must be specified");
18690       return -99;
18691     }
18692
18693   if (vec_len (host_if_name) > 64)
18694     {
18695       errmsg ("host-interface name too long");
18696       return -99;
18697     }
18698
18699   M (AF_PACKET_DELETE, mp);
18700
18701   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18702   vec_free (host_if_name);
18703
18704   S (mp);
18705   W (ret);
18706   return ret;
18707 }
18708
18709 static void vl_api_af_packet_details_t_handler
18710   (vl_api_af_packet_details_t * mp)
18711 {
18712   vat_main_t *vam = &vat_main;
18713
18714   print (vam->ofp, "%-16s %d",
18715          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18716 }
18717
18718 static void vl_api_af_packet_details_t_handler_json
18719   (vl_api_af_packet_details_t * mp)
18720 {
18721   vat_main_t *vam = &vat_main;
18722   vat_json_node_t *node = NULL;
18723
18724   if (VAT_JSON_ARRAY != vam->json_tree.type)
18725     {
18726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18727       vat_json_init_array (&vam->json_tree);
18728     }
18729   node = vat_json_array_add (&vam->json_tree);
18730
18731   vat_json_init_object (node);
18732   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18733   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18734 }
18735
18736 static int
18737 api_af_packet_dump (vat_main_t * vam)
18738 {
18739   vl_api_af_packet_dump_t *mp;
18740   vl_api_control_ping_t *mp_ping;
18741   int ret;
18742
18743   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18744   /* Get list of tap interfaces */
18745   M (AF_PACKET_DUMP, mp);
18746   S (mp);
18747
18748   /* Use a control ping for synchronization */
18749   MPING (CONTROL_PING, mp_ping);
18750   S (mp_ping);
18751
18752   W (ret);
18753   return ret;
18754 }
18755
18756 static int
18757 api_policer_add_del (vat_main_t * vam)
18758 {
18759   unformat_input_t *i = vam->input;
18760   vl_api_policer_add_del_t *mp;
18761   u8 is_add = 1;
18762   u8 *name = 0;
18763   u32 cir = 0;
18764   u32 eir = 0;
18765   u64 cb = 0;
18766   u64 eb = 0;
18767   u8 rate_type = 0;
18768   u8 round_type = 0;
18769   u8 type = 0;
18770   u8 color_aware = 0;
18771   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18772   int ret;
18773
18774   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18775   conform_action.dscp = 0;
18776   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18777   exceed_action.dscp = 0;
18778   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18779   violate_action.dscp = 0;
18780
18781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18782     {
18783       if (unformat (i, "del"))
18784         is_add = 0;
18785       else if (unformat (i, "name %s", &name))
18786         vec_add1 (name, 0);
18787       else if (unformat (i, "cir %u", &cir))
18788         ;
18789       else if (unformat (i, "eir %u", &eir))
18790         ;
18791       else if (unformat (i, "cb %u", &cb))
18792         ;
18793       else if (unformat (i, "eb %u", &eb))
18794         ;
18795       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18796                          &rate_type))
18797         ;
18798       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18799                          &round_type))
18800         ;
18801       else if (unformat (i, "type %U", unformat_policer_type, &type))
18802         ;
18803       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18804                          &conform_action))
18805         ;
18806       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18807                          &exceed_action))
18808         ;
18809       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18810                          &violate_action))
18811         ;
18812       else if (unformat (i, "color-aware"))
18813         color_aware = 1;
18814       else
18815         break;
18816     }
18817
18818   if (!vec_len (name))
18819     {
18820       errmsg ("policer name must be specified");
18821       return -99;
18822     }
18823
18824   if (vec_len (name) > 64)
18825     {
18826       errmsg ("policer name too long");
18827       return -99;
18828     }
18829
18830   M (POLICER_ADD_DEL, mp);
18831
18832   clib_memcpy (mp->name, name, vec_len (name));
18833   vec_free (name);
18834   mp->is_add = is_add;
18835   mp->cir = ntohl (cir);
18836   mp->eir = ntohl (eir);
18837   mp->cb = clib_net_to_host_u64 (cb);
18838   mp->eb = clib_net_to_host_u64 (eb);
18839   mp->rate_type = rate_type;
18840   mp->round_type = round_type;
18841   mp->type = type;
18842   mp->conform_action_type = conform_action.action_type;
18843   mp->conform_dscp = conform_action.dscp;
18844   mp->exceed_action_type = exceed_action.action_type;
18845   mp->exceed_dscp = exceed_action.dscp;
18846   mp->violate_action_type = violate_action.action_type;
18847   mp->violate_dscp = violate_action.dscp;
18848   mp->color_aware = color_aware;
18849
18850   S (mp);
18851   W (ret);
18852   return ret;
18853 }
18854
18855 static int
18856 api_policer_dump (vat_main_t * vam)
18857 {
18858   unformat_input_t *i = vam->input;
18859   vl_api_policer_dump_t *mp;
18860   vl_api_control_ping_t *mp_ping;
18861   u8 *match_name = 0;
18862   u8 match_name_valid = 0;
18863   int ret;
18864
18865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18866     {
18867       if (unformat (i, "name %s", &match_name))
18868         {
18869           vec_add1 (match_name, 0);
18870           match_name_valid = 1;
18871         }
18872       else
18873         break;
18874     }
18875
18876   M (POLICER_DUMP, mp);
18877   mp->match_name_valid = match_name_valid;
18878   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18879   vec_free (match_name);
18880   /* send it... */
18881   S (mp);
18882
18883   /* Use a control ping for synchronization */
18884   MPING (CONTROL_PING, mp_ping);
18885   S (mp_ping);
18886
18887   /* Wait for a reply... */
18888   W (ret);
18889   return ret;
18890 }
18891
18892 static int
18893 api_policer_classify_set_interface (vat_main_t * vam)
18894 {
18895   unformat_input_t *i = vam->input;
18896   vl_api_policer_classify_set_interface_t *mp;
18897   u32 sw_if_index;
18898   int sw_if_index_set;
18899   u32 ip4_table_index = ~0;
18900   u32 ip6_table_index = ~0;
18901   u32 l2_table_index = ~0;
18902   u8 is_add = 1;
18903   int ret;
18904
18905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18906     {
18907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18908         sw_if_index_set = 1;
18909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18910         sw_if_index_set = 1;
18911       else if (unformat (i, "del"))
18912         is_add = 0;
18913       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18914         ;
18915       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18916         ;
18917       else if (unformat (i, "l2-table %d", &l2_table_index))
18918         ;
18919       else
18920         {
18921           clib_warning ("parse error '%U'", format_unformat_error, i);
18922           return -99;
18923         }
18924     }
18925
18926   if (sw_if_index_set == 0)
18927     {
18928       errmsg ("missing interface name or sw_if_index");
18929       return -99;
18930     }
18931
18932   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18933
18934   mp->sw_if_index = ntohl (sw_if_index);
18935   mp->ip4_table_index = ntohl (ip4_table_index);
18936   mp->ip6_table_index = ntohl (ip6_table_index);
18937   mp->l2_table_index = ntohl (l2_table_index);
18938   mp->is_add = is_add;
18939
18940   S (mp);
18941   W (ret);
18942   return ret;
18943 }
18944
18945 static int
18946 api_policer_classify_dump (vat_main_t * vam)
18947 {
18948   unformat_input_t *i = vam->input;
18949   vl_api_policer_classify_dump_t *mp;
18950   vl_api_control_ping_t *mp_ping;
18951   u8 type = POLICER_CLASSIFY_N_TABLES;
18952   int ret;
18953
18954   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18955     ;
18956   else
18957     {
18958       errmsg ("classify table type must be specified");
18959       return -99;
18960     }
18961
18962   if (!vam->json_output)
18963     {
18964       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18965     }
18966
18967   M (POLICER_CLASSIFY_DUMP, mp);
18968   mp->type = type;
18969   /* send it... */
18970   S (mp);
18971
18972   /* Use a control ping for synchronization */
18973   MPING (CONTROL_PING, mp_ping);
18974   S (mp_ping);
18975
18976   /* Wait for a reply... */
18977   W (ret);
18978   return ret;
18979 }
18980
18981 static int
18982 api_netmap_create (vat_main_t * vam)
18983 {
18984   unformat_input_t *i = vam->input;
18985   vl_api_netmap_create_t *mp;
18986   u8 *if_name = 0;
18987   u8 hw_addr[6];
18988   u8 random_hw_addr = 1;
18989   u8 is_pipe = 0;
18990   u8 is_master = 0;
18991   int ret;
18992
18993   clib_memset (hw_addr, 0, sizeof (hw_addr));
18994
18995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18996     {
18997       if (unformat (i, "name %s", &if_name))
18998         vec_add1 (if_name, 0);
18999       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19000         random_hw_addr = 0;
19001       else if (unformat (i, "pipe"))
19002         is_pipe = 1;
19003       else if (unformat (i, "master"))
19004         is_master = 1;
19005       else if (unformat (i, "slave"))
19006         is_master = 0;
19007       else
19008         break;
19009     }
19010
19011   if (!vec_len (if_name))
19012     {
19013       errmsg ("interface name must be specified");
19014       return -99;
19015     }
19016
19017   if (vec_len (if_name) > 64)
19018     {
19019       errmsg ("interface name too long");
19020       return -99;
19021     }
19022
19023   M (NETMAP_CREATE, mp);
19024
19025   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19026   clib_memcpy (mp->hw_addr, hw_addr, 6);
19027   mp->use_random_hw_addr = random_hw_addr;
19028   mp->is_pipe = is_pipe;
19029   mp->is_master = is_master;
19030   vec_free (if_name);
19031
19032   S (mp);
19033   W (ret);
19034   return ret;
19035 }
19036
19037 static int
19038 api_netmap_delete (vat_main_t * vam)
19039 {
19040   unformat_input_t *i = vam->input;
19041   vl_api_netmap_delete_t *mp;
19042   u8 *if_name = 0;
19043   int ret;
19044
19045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19046     {
19047       if (unformat (i, "name %s", &if_name))
19048         vec_add1 (if_name, 0);
19049       else
19050         break;
19051     }
19052
19053   if (!vec_len (if_name))
19054     {
19055       errmsg ("interface name must be specified");
19056       return -99;
19057     }
19058
19059   if (vec_len (if_name) > 64)
19060     {
19061       errmsg ("interface name too long");
19062       return -99;
19063     }
19064
19065   M (NETMAP_DELETE, mp);
19066
19067   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19068   vec_free (if_name);
19069
19070   S (mp);
19071   W (ret);
19072   return ret;
19073 }
19074
19075 static void
19076 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19077 {
19078   if (fp->afi == IP46_TYPE_IP6)
19079     print (vam->ofp,
19080            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19081            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19082            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19083            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19084            format_ip6_address, fp->next_hop);
19085   else if (fp->afi == IP46_TYPE_IP4)
19086     print (vam->ofp,
19087            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19088            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19089            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19090            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19091            format_ip4_address, fp->next_hop);
19092 }
19093
19094 static void
19095 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19096                                  vl_api_fib_path_t * fp)
19097 {
19098   struct in_addr ip4;
19099   struct in6_addr ip6;
19100
19101   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19102   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19103   vat_json_object_add_uint (node, "is_local", fp->is_local);
19104   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19105   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19106   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19107   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19108   if (fp->afi == IP46_TYPE_IP4)
19109     {
19110       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19111       vat_json_object_add_ip4 (node, "next_hop", ip4);
19112     }
19113   else if (fp->afi == IP46_TYPE_IP6)
19114     {
19115       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19116       vat_json_object_add_ip6 (node, "next_hop", ip6);
19117     }
19118 }
19119
19120 static void
19121 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19122 {
19123   vat_main_t *vam = &vat_main;
19124   int count = ntohl (mp->mt_count);
19125   vl_api_fib_path_t *fp;
19126   i32 i;
19127
19128   print (vam->ofp, "[%d]: sw_if_index %d via:",
19129          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19130   fp = mp->mt_paths;
19131   for (i = 0; i < count; i++)
19132     {
19133       vl_api_mpls_fib_path_print (vam, fp);
19134       fp++;
19135     }
19136
19137   print (vam->ofp, "");
19138 }
19139
19140 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19141 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19142
19143 static void
19144 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19145 {
19146   vat_main_t *vam = &vat_main;
19147   vat_json_node_t *node = NULL;
19148   int count = ntohl (mp->mt_count);
19149   vl_api_fib_path_t *fp;
19150   i32 i;
19151
19152   if (VAT_JSON_ARRAY != vam->json_tree.type)
19153     {
19154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19155       vat_json_init_array (&vam->json_tree);
19156     }
19157   node = vat_json_array_add (&vam->json_tree);
19158
19159   vat_json_init_object (node);
19160   vat_json_object_add_uint (node, "tunnel_index",
19161                             ntohl (mp->mt_tunnel_index));
19162   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19163
19164   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19165
19166   fp = mp->mt_paths;
19167   for (i = 0; i < count; i++)
19168     {
19169       vl_api_mpls_fib_path_json_print (node, fp);
19170       fp++;
19171     }
19172 }
19173
19174 static int
19175 api_mpls_tunnel_dump (vat_main_t * vam)
19176 {
19177   vl_api_mpls_tunnel_dump_t *mp;
19178   vl_api_control_ping_t *mp_ping;
19179   u32 sw_if_index = ~0;
19180   int ret;
19181
19182   /* Parse args required to build the message */
19183   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19184     {
19185       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19186         ;
19187     }
19188
19189   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19190
19191   M (MPLS_TUNNEL_DUMP, mp);
19192   mp->sw_if_index = htonl (sw_if_index);
19193   S (mp);
19194
19195   /* Use a control ping for synchronization */
19196   MPING (CONTROL_PING, mp_ping);
19197   S (mp_ping);
19198
19199   W (ret);
19200   return ret;
19201 }
19202
19203 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19204 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19205
19206
19207 static void
19208 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19209 {
19210   vat_main_t *vam = &vat_main;
19211   int count = ntohl (mp->count);
19212   vl_api_fib_path_t *fp;
19213   int i;
19214
19215   print (vam->ofp,
19216          "table-id %d, label %u, ess_bit %u",
19217          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19218   fp = mp->path;
19219   for (i = 0; i < count; i++)
19220     {
19221       vl_api_mpls_fib_path_print (vam, fp);
19222       fp++;
19223     }
19224 }
19225
19226 static void vl_api_mpls_fib_details_t_handler_json
19227   (vl_api_mpls_fib_details_t * mp)
19228 {
19229   vat_main_t *vam = &vat_main;
19230   int count = ntohl (mp->count);
19231   vat_json_node_t *node = NULL;
19232   vl_api_fib_path_t *fp;
19233   int i;
19234
19235   if (VAT_JSON_ARRAY != vam->json_tree.type)
19236     {
19237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19238       vat_json_init_array (&vam->json_tree);
19239     }
19240   node = vat_json_array_add (&vam->json_tree);
19241
19242   vat_json_init_object (node);
19243   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19244   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19245   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19246   vat_json_object_add_uint (node, "path_count", count);
19247   fp = mp->path;
19248   for (i = 0; i < count; i++)
19249     {
19250       vl_api_mpls_fib_path_json_print (node, fp);
19251       fp++;
19252     }
19253 }
19254
19255 static int
19256 api_mpls_fib_dump (vat_main_t * vam)
19257 {
19258   vl_api_mpls_fib_dump_t *mp;
19259   vl_api_control_ping_t *mp_ping;
19260   int ret;
19261
19262   M (MPLS_FIB_DUMP, mp);
19263   S (mp);
19264
19265   /* Use a control ping for synchronization */
19266   MPING (CONTROL_PING, mp_ping);
19267   S (mp_ping);
19268
19269   W (ret);
19270   return ret;
19271 }
19272
19273 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19274 #define vl_api_ip_fib_details_t_print vl_noop_handler
19275
19276 static void
19277 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19278 {
19279   vat_main_t *vam = &vat_main;
19280   int count = ntohl (mp->count);
19281   vl_api_fib_path_t *fp;
19282   int i;
19283
19284   print (vam->ofp,
19285          "table-id %d, prefix %U/%d stats-index %d",
19286          ntohl (mp->table_id), format_ip4_address, mp->address,
19287          mp->address_length, ntohl (mp->stats_index));
19288   fp = mp->path;
19289   for (i = 0; i < count; i++)
19290     {
19291       if (fp->afi == IP46_TYPE_IP6)
19292         print (vam->ofp,
19293                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19294                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19295                "next_hop_table %d",
19296                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19297                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19298                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19299       else if (fp->afi == IP46_TYPE_IP4)
19300         print (vam->ofp,
19301                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19302                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19303                "next_hop_table %d",
19304                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19305                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19306                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19307       fp++;
19308     }
19309 }
19310
19311 static void vl_api_ip_fib_details_t_handler_json
19312   (vl_api_ip_fib_details_t * mp)
19313 {
19314   vat_main_t *vam = &vat_main;
19315   int count = ntohl (mp->count);
19316   vat_json_node_t *node = NULL;
19317   struct in_addr ip4;
19318   struct in6_addr ip6;
19319   vl_api_fib_path_t *fp;
19320   int i;
19321
19322   if (VAT_JSON_ARRAY != vam->json_tree.type)
19323     {
19324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19325       vat_json_init_array (&vam->json_tree);
19326     }
19327   node = vat_json_array_add (&vam->json_tree);
19328
19329   vat_json_init_object (node);
19330   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19331   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19332   vat_json_object_add_ip4 (node, "prefix", ip4);
19333   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19334   vat_json_object_add_uint (node, "path_count", count);
19335   fp = mp->path;
19336   for (i = 0; i < count; i++)
19337     {
19338       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19339       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19340       vat_json_object_add_uint (node, "is_local", fp->is_local);
19341       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19342       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19343       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19344       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19345       if (fp->afi == IP46_TYPE_IP4)
19346         {
19347           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19348           vat_json_object_add_ip4 (node, "next_hop", ip4);
19349         }
19350       else if (fp->afi == IP46_TYPE_IP6)
19351         {
19352           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19353           vat_json_object_add_ip6 (node, "next_hop", ip6);
19354         }
19355     }
19356 }
19357
19358 static int
19359 api_ip_fib_dump (vat_main_t * vam)
19360 {
19361   vl_api_ip_fib_dump_t *mp;
19362   vl_api_control_ping_t *mp_ping;
19363   int ret;
19364
19365   M (IP_FIB_DUMP, mp);
19366   S (mp);
19367
19368   /* Use a control ping for synchronization */
19369   MPING (CONTROL_PING, mp_ping);
19370   S (mp_ping);
19371
19372   W (ret);
19373   return ret;
19374 }
19375
19376 static int
19377 api_ip_mfib_dump (vat_main_t * vam)
19378 {
19379   vl_api_ip_mfib_dump_t *mp;
19380   vl_api_control_ping_t *mp_ping;
19381   int ret;
19382
19383   M (IP_MFIB_DUMP, mp);
19384   S (mp);
19385
19386   /* Use a control ping for synchronization */
19387   MPING (CONTROL_PING, mp_ping);
19388   S (mp_ping);
19389
19390   W (ret);
19391   return ret;
19392 }
19393
19394 static void vl_api_ip_neighbor_details_t_handler
19395   (vl_api_ip_neighbor_details_t * mp)
19396 {
19397   vat_main_t *vam = &vat_main;
19398
19399   print (vam->ofp, "%c %U %U",
19400          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19401          format_vl_api_mac_address, &mp->neighbor.mac_address,
19402          format_vl_api_address, &mp->neighbor.ip_address);
19403 }
19404
19405 static void vl_api_ip_neighbor_details_t_handler_json
19406   (vl_api_ip_neighbor_details_t * mp)
19407 {
19408
19409   vat_main_t *vam = &vat_main;
19410   vat_json_node_t *node;
19411
19412   if (VAT_JSON_ARRAY != vam->json_tree.type)
19413     {
19414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19415       vat_json_init_array (&vam->json_tree);
19416     }
19417   node = vat_json_array_add (&vam->json_tree);
19418
19419   vat_json_init_object (node);
19420   vat_json_object_add_string_copy
19421     (node, "flag",
19422      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19423       (u8 *) "static" : (u8 *) "dynamic"));
19424
19425   vat_json_object_add_string_copy (node, "link_layer",
19426                                    format (0, "%U", format_vl_api_mac_address,
19427                                            &mp->neighbor.mac_address));
19428   vat_json_object_add_address (node, &mp->neighbor.ip_address);
19429 }
19430
19431 static int
19432 api_ip_neighbor_dump (vat_main_t * vam)
19433 {
19434   unformat_input_t *i = vam->input;
19435   vl_api_ip_neighbor_dump_t *mp;
19436   vl_api_control_ping_t *mp_ping;
19437   u8 is_ipv6 = 0;
19438   u32 sw_if_index = ~0;
19439   int ret;
19440
19441   /* Parse args required to build the message */
19442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19443     {
19444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19445         ;
19446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19447         ;
19448       else if (unformat (i, "ip6"))
19449         is_ipv6 = 1;
19450       else
19451         break;
19452     }
19453
19454   if (sw_if_index == ~0)
19455     {
19456       errmsg ("missing interface name or sw_if_index");
19457       return -99;
19458     }
19459
19460   M (IP_NEIGHBOR_DUMP, mp);
19461   mp->is_ipv6 = (u8) is_ipv6;
19462   mp->sw_if_index = ntohl (sw_if_index);
19463   S (mp);
19464
19465   /* Use a control ping for synchronization */
19466   MPING (CONTROL_PING, mp_ping);
19467   S (mp_ping);
19468
19469   W (ret);
19470   return ret;
19471 }
19472
19473 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19474 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19475
19476 static void
19477 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19478 {
19479   vat_main_t *vam = &vat_main;
19480   int count = ntohl (mp->count);
19481   vl_api_fib_path_t *fp;
19482   int i;
19483
19484   print (vam->ofp,
19485          "table-id %d, prefix %U/%d stats-index %d",
19486          ntohl (mp->table_id), format_ip6_address, mp->address,
19487          mp->address_length, ntohl (mp->stats_index));
19488   fp = mp->path;
19489   for (i = 0; i < count; i++)
19490     {
19491       if (fp->afi == IP46_TYPE_IP6)
19492         print (vam->ofp,
19493                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19494                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19495                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19496                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19497                format_ip6_address, fp->next_hop);
19498       else if (fp->afi == IP46_TYPE_IP4)
19499         print (vam->ofp,
19500                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19501                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19502                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19503                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19504                format_ip4_address, fp->next_hop);
19505       fp++;
19506     }
19507 }
19508
19509 static void vl_api_ip6_fib_details_t_handler_json
19510   (vl_api_ip6_fib_details_t * mp)
19511 {
19512   vat_main_t *vam = &vat_main;
19513   int count = ntohl (mp->count);
19514   vat_json_node_t *node = NULL;
19515   struct in_addr ip4;
19516   struct in6_addr ip6;
19517   vl_api_fib_path_t *fp;
19518   int i;
19519
19520   if (VAT_JSON_ARRAY != vam->json_tree.type)
19521     {
19522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19523       vat_json_init_array (&vam->json_tree);
19524     }
19525   node = vat_json_array_add (&vam->json_tree);
19526
19527   vat_json_init_object (node);
19528   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19529   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19530   vat_json_object_add_ip6 (node, "prefix", ip6);
19531   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19532   vat_json_object_add_uint (node, "path_count", count);
19533   fp = mp->path;
19534   for (i = 0; i < count; i++)
19535     {
19536       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19537       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19538       vat_json_object_add_uint (node, "is_local", fp->is_local);
19539       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19540       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19541       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19542       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19543       if (fp->afi == IP46_TYPE_IP4)
19544         {
19545           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19546           vat_json_object_add_ip4 (node, "next_hop", ip4);
19547         }
19548       else if (fp->afi == IP46_TYPE_IP6)
19549         {
19550           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19551           vat_json_object_add_ip6 (node, "next_hop", ip6);
19552         }
19553     }
19554 }
19555
19556 static int
19557 api_ip6_fib_dump (vat_main_t * vam)
19558 {
19559   vl_api_ip6_fib_dump_t *mp;
19560   vl_api_control_ping_t *mp_ping;
19561   int ret;
19562
19563   M (IP6_FIB_DUMP, mp);
19564   S (mp);
19565
19566   /* Use a control ping for synchronization */
19567   MPING (CONTROL_PING, mp_ping);
19568   S (mp_ping);
19569
19570   W (ret);
19571   return ret;
19572 }
19573
19574 static int
19575 api_ip6_mfib_dump (vat_main_t * vam)
19576 {
19577   vl_api_ip6_mfib_dump_t *mp;
19578   vl_api_control_ping_t *mp_ping;
19579   int ret;
19580
19581   M (IP6_MFIB_DUMP, mp);
19582   S (mp);
19583
19584   /* Use a control ping for synchronization */
19585   MPING (CONTROL_PING, mp_ping);
19586   S (mp_ping);
19587
19588   W (ret);
19589   return ret;
19590 }
19591
19592 int
19593 api_classify_table_ids (vat_main_t * vam)
19594 {
19595   vl_api_classify_table_ids_t *mp;
19596   int ret;
19597
19598   /* Construct the API message */
19599   M (CLASSIFY_TABLE_IDS, mp);
19600   mp->context = 0;
19601
19602   S (mp);
19603   W (ret);
19604   return ret;
19605 }
19606
19607 int
19608 api_classify_table_by_interface (vat_main_t * vam)
19609 {
19610   unformat_input_t *input = vam->input;
19611   vl_api_classify_table_by_interface_t *mp;
19612
19613   u32 sw_if_index = ~0;
19614   int ret;
19615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19616     {
19617       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19618         ;
19619       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19620         ;
19621       else
19622         break;
19623     }
19624   if (sw_if_index == ~0)
19625     {
19626       errmsg ("missing interface name or sw_if_index");
19627       return -99;
19628     }
19629
19630   /* Construct the API message */
19631   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19632   mp->context = 0;
19633   mp->sw_if_index = ntohl (sw_if_index);
19634
19635   S (mp);
19636   W (ret);
19637   return ret;
19638 }
19639
19640 int
19641 api_classify_table_info (vat_main_t * vam)
19642 {
19643   unformat_input_t *input = vam->input;
19644   vl_api_classify_table_info_t *mp;
19645
19646   u32 table_id = ~0;
19647   int ret;
19648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19649     {
19650       if (unformat (input, "table_id %d", &table_id))
19651         ;
19652       else
19653         break;
19654     }
19655   if (table_id == ~0)
19656     {
19657       errmsg ("missing table id");
19658       return -99;
19659     }
19660
19661   /* Construct the API message */
19662   M (CLASSIFY_TABLE_INFO, mp);
19663   mp->context = 0;
19664   mp->table_id = ntohl (table_id);
19665
19666   S (mp);
19667   W (ret);
19668   return ret;
19669 }
19670
19671 int
19672 api_classify_session_dump (vat_main_t * vam)
19673 {
19674   unformat_input_t *input = vam->input;
19675   vl_api_classify_session_dump_t *mp;
19676   vl_api_control_ping_t *mp_ping;
19677
19678   u32 table_id = ~0;
19679   int ret;
19680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19681     {
19682       if (unformat (input, "table_id %d", &table_id))
19683         ;
19684       else
19685         break;
19686     }
19687   if (table_id == ~0)
19688     {
19689       errmsg ("missing table id");
19690       return -99;
19691     }
19692
19693   /* Construct the API message */
19694   M (CLASSIFY_SESSION_DUMP, mp);
19695   mp->context = 0;
19696   mp->table_id = ntohl (table_id);
19697   S (mp);
19698
19699   /* Use a control ping for synchronization */
19700   MPING (CONTROL_PING, mp_ping);
19701   S (mp_ping);
19702
19703   W (ret);
19704   return ret;
19705 }
19706
19707 static void
19708 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19709 {
19710   vat_main_t *vam = &vat_main;
19711
19712   print (vam->ofp, "collector_address %U, collector_port %d, "
19713          "src_address %U, vrf_id %d, path_mtu %u, "
19714          "template_interval %u, udp_checksum %d",
19715          format_ip4_address, mp->collector_address,
19716          ntohs (mp->collector_port),
19717          format_ip4_address, mp->src_address,
19718          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19719          ntohl (mp->template_interval), mp->udp_checksum);
19720
19721   vam->retval = 0;
19722   vam->result_ready = 1;
19723 }
19724
19725 static void
19726   vl_api_ipfix_exporter_details_t_handler_json
19727   (vl_api_ipfix_exporter_details_t * mp)
19728 {
19729   vat_main_t *vam = &vat_main;
19730   vat_json_node_t node;
19731   struct in_addr collector_address;
19732   struct in_addr src_address;
19733
19734   vat_json_init_object (&node);
19735   clib_memcpy (&collector_address, &mp->collector_address,
19736                sizeof (collector_address));
19737   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19738   vat_json_object_add_uint (&node, "collector_port",
19739                             ntohs (mp->collector_port));
19740   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19741   vat_json_object_add_ip4 (&node, "src_address", src_address);
19742   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19743   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19744   vat_json_object_add_uint (&node, "template_interval",
19745                             ntohl (mp->template_interval));
19746   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19747
19748   vat_json_print (vam->ofp, &node);
19749   vat_json_free (&node);
19750   vam->retval = 0;
19751   vam->result_ready = 1;
19752 }
19753
19754 int
19755 api_ipfix_exporter_dump (vat_main_t * vam)
19756 {
19757   vl_api_ipfix_exporter_dump_t *mp;
19758   int ret;
19759
19760   /* Construct the API message */
19761   M (IPFIX_EXPORTER_DUMP, mp);
19762   mp->context = 0;
19763
19764   S (mp);
19765   W (ret);
19766   return ret;
19767 }
19768
19769 static int
19770 api_ipfix_classify_stream_dump (vat_main_t * vam)
19771 {
19772   vl_api_ipfix_classify_stream_dump_t *mp;
19773   int ret;
19774
19775   /* Construct the API message */
19776   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19777   mp->context = 0;
19778
19779   S (mp);
19780   W (ret);
19781   return ret;
19782   /* NOTREACHED */
19783   return 0;
19784 }
19785
19786 static void
19787   vl_api_ipfix_classify_stream_details_t_handler
19788   (vl_api_ipfix_classify_stream_details_t * mp)
19789 {
19790   vat_main_t *vam = &vat_main;
19791   print (vam->ofp, "domain_id %d, src_port %d",
19792          ntohl (mp->domain_id), ntohs (mp->src_port));
19793   vam->retval = 0;
19794   vam->result_ready = 1;
19795 }
19796
19797 static void
19798   vl_api_ipfix_classify_stream_details_t_handler_json
19799   (vl_api_ipfix_classify_stream_details_t * mp)
19800 {
19801   vat_main_t *vam = &vat_main;
19802   vat_json_node_t node;
19803
19804   vat_json_init_object (&node);
19805   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19806   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19807
19808   vat_json_print (vam->ofp, &node);
19809   vat_json_free (&node);
19810   vam->retval = 0;
19811   vam->result_ready = 1;
19812 }
19813
19814 static int
19815 api_ipfix_classify_table_dump (vat_main_t * vam)
19816 {
19817   vl_api_ipfix_classify_table_dump_t *mp;
19818   vl_api_control_ping_t *mp_ping;
19819   int ret;
19820
19821   if (!vam->json_output)
19822     {
19823       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19824              "transport_protocol");
19825     }
19826
19827   /* Construct the API message */
19828   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19829
19830   /* send it... */
19831   S (mp);
19832
19833   /* Use a control ping for synchronization */
19834   MPING (CONTROL_PING, mp_ping);
19835   S (mp_ping);
19836
19837   W (ret);
19838   return ret;
19839 }
19840
19841 static void
19842   vl_api_ipfix_classify_table_details_t_handler
19843   (vl_api_ipfix_classify_table_details_t * mp)
19844 {
19845   vat_main_t *vam = &vat_main;
19846   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19847          mp->transport_protocol);
19848 }
19849
19850 static void
19851   vl_api_ipfix_classify_table_details_t_handler_json
19852   (vl_api_ipfix_classify_table_details_t * mp)
19853 {
19854   vat_json_node_t *node = NULL;
19855   vat_main_t *vam = &vat_main;
19856
19857   if (VAT_JSON_ARRAY != vam->json_tree.type)
19858     {
19859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19860       vat_json_init_array (&vam->json_tree);
19861     }
19862
19863   node = vat_json_array_add (&vam->json_tree);
19864   vat_json_init_object (node);
19865
19866   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19867   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19868   vat_json_object_add_uint (node, "transport_protocol",
19869                             mp->transport_protocol);
19870 }
19871
19872 static int
19873 api_sw_interface_span_enable_disable (vat_main_t * vam)
19874 {
19875   unformat_input_t *i = vam->input;
19876   vl_api_sw_interface_span_enable_disable_t *mp;
19877   u32 src_sw_if_index = ~0;
19878   u32 dst_sw_if_index = ~0;
19879   u8 state = 3;
19880   int ret;
19881   u8 is_l2 = 0;
19882
19883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19884     {
19885       if (unformat
19886           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19887         ;
19888       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19889         ;
19890       else
19891         if (unformat
19892             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19893         ;
19894       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19895         ;
19896       else if (unformat (i, "disable"))
19897         state = 0;
19898       else if (unformat (i, "rx"))
19899         state = 1;
19900       else if (unformat (i, "tx"))
19901         state = 2;
19902       else if (unformat (i, "both"))
19903         state = 3;
19904       else if (unformat (i, "l2"))
19905         is_l2 = 1;
19906       else
19907         break;
19908     }
19909
19910   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19911
19912   mp->sw_if_index_from = htonl (src_sw_if_index);
19913   mp->sw_if_index_to = htonl (dst_sw_if_index);
19914   mp->state = state;
19915   mp->is_l2 = is_l2;
19916
19917   S (mp);
19918   W (ret);
19919   return ret;
19920 }
19921
19922 static void
19923 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19924                                             * mp)
19925 {
19926   vat_main_t *vam = &vat_main;
19927   u8 *sw_if_from_name = 0;
19928   u8 *sw_if_to_name = 0;
19929   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19930   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19931   char *states[] = { "none", "rx", "tx", "both" };
19932   hash_pair_t *p;
19933
19934   /* *INDENT-OFF* */
19935   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19936   ({
19937     if ((u32) p->value[0] == sw_if_index_from)
19938       {
19939         sw_if_from_name = (u8 *)(p->key);
19940         if (sw_if_to_name)
19941           break;
19942       }
19943     if ((u32) p->value[0] == sw_if_index_to)
19944       {
19945         sw_if_to_name = (u8 *)(p->key);
19946         if (sw_if_from_name)
19947           break;
19948       }
19949   }));
19950   /* *INDENT-ON* */
19951   print (vam->ofp, "%20s => %20s (%s) %s",
19952          sw_if_from_name, sw_if_to_name, states[mp->state],
19953          mp->is_l2 ? "l2" : "device");
19954 }
19955
19956 static void
19957   vl_api_sw_interface_span_details_t_handler_json
19958   (vl_api_sw_interface_span_details_t * mp)
19959 {
19960   vat_main_t *vam = &vat_main;
19961   vat_json_node_t *node = NULL;
19962   u8 *sw_if_from_name = 0;
19963   u8 *sw_if_to_name = 0;
19964   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19965   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19966   hash_pair_t *p;
19967
19968   /* *INDENT-OFF* */
19969   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19970   ({
19971     if ((u32) p->value[0] == sw_if_index_from)
19972       {
19973         sw_if_from_name = (u8 *)(p->key);
19974         if (sw_if_to_name)
19975           break;
19976       }
19977     if ((u32) p->value[0] == sw_if_index_to)
19978       {
19979         sw_if_to_name = (u8 *)(p->key);
19980         if (sw_if_from_name)
19981           break;
19982       }
19983   }));
19984   /* *INDENT-ON* */
19985
19986   if (VAT_JSON_ARRAY != vam->json_tree.type)
19987     {
19988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19989       vat_json_init_array (&vam->json_tree);
19990     }
19991   node = vat_json_array_add (&vam->json_tree);
19992
19993   vat_json_init_object (node);
19994   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19995   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19996   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19997   if (0 != sw_if_to_name)
19998     {
19999       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20000     }
20001   vat_json_object_add_uint (node, "state", mp->state);
20002   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20003 }
20004
20005 static int
20006 api_sw_interface_span_dump (vat_main_t * vam)
20007 {
20008   unformat_input_t *input = vam->input;
20009   vl_api_sw_interface_span_dump_t *mp;
20010   vl_api_control_ping_t *mp_ping;
20011   u8 is_l2 = 0;
20012   int ret;
20013
20014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20015     {
20016       if (unformat (input, "l2"))
20017         is_l2 = 1;
20018       else
20019         break;
20020     }
20021
20022   M (SW_INTERFACE_SPAN_DUMP, mp);
20023   mp->is_l2 = is_l2;
20024   S (mp);
20025
20026   /* Use a control ping for synchronization */
20027   MPING (CONTROL_PING, mp_ping);
20028   S (mp_ping);
20029
20030   W (ret);
20031   return ret;
20032 }
20033
20034 int
20035 api_pg_create_interface (vat_main_t * vam)
20036 {
20037   unformat_input_t *input = vam->input;
20038   vl_api_pg_create_interface_t *mp;
20039
20040   u32 if_id = ~0;
20041   int ret;
20042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20043     {
20044       if (unformat (input, "if_id %d", &if_id))
20045         ;
20046       else
20047         break;
20048     }
20049   if (if_id == ~0)
20050     {
20051       errmsg ("missing pg interface index");
20052       return -99;
20053     }
20054
20055   /* Construct the API message */
20056   M (PG_CREATE_INTERFACE, mp);
20057   mp->context = 0;
20058   mp->interface_id = ntohl (if_id);
20059
20060   S (mp);
20061   W (ret);
20062   return ret;
20063 }
20064
20065 int
20066 api_pg_capture (vat_main_t * vam)
20067 {
20068   unformat_input_t *input = vam->input;
20069   vl_api_pg_capture_t *mp;
20070
20071   u32 if_id = ~0;
20072   u8 enable = 1;
20073   u32 count = 1;
20074   u8 pcap_file_set = 0;
20075   u8 *pcap_file = 0;
20076   int ret;
20077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20078     {
20079       if (unformat (input, "if_id %d", &if_id))
20080         ;
20081       else if (unformat (input, "pcap %s", &pcap_file))
20082         pcap_file_set = 1;
20083       else if (unformat (input, "count %d", &count))
20084         ;
20085       else if (unformat (input, "disable"))
20086         enable = 0;
20087       else
20088         break;
20089     }
20090   if (if_id == ~0)
20091     {
20092       errmsg ("missing pg interface index");
20093       return -99;
20094     }
20095   if (pcap_file_set > 0)
20096     {
20097       if (vec_len (pcap_file) > 255)
20098         {
20099           errmsg ("pcap file name is too long");
20100           return -99;
20101         }
20102     }
20103
20104   u32 name_len = vec_len (pcap_file);
20105   /* Construct the API message */
20106   M (PG_CAPTURE, mp);
20107   mp->context = 0;
20108   mp->interface_id = ntohl (if_id);
20109   mp->is_enabled = enable;
20110   mp->count = ntohl (count);
20111   mp->pcap_name_length = ntohl (name_len);
20112   if (pcap_file_set != 0)
20113     {
20114       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20115     }
20116   vec_free (pcap_file);
20117
20118   S (mp);
20119   W (ret);
20120   return ret;
20121 }
20122
20123 int
20124 api_pg_enable_disable (vat_main_t * vam)
20125 {
20126   unformat_input_t *input = vam->input;
20127   vl_api_pg_enable_disable_t *mp;
20128
20129   u8 enable = 1;
20130   u8 stream_name_set = 0;
20131   u8 *stream_name = 0;
20132   int ret;
20133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20134     {
20135       if (unformat (input, "stream %s", &stream_name))
20136         stream_name_set = 1;
20137       else if (unformat (input, "disable"))
20138         enable = 0;
20139       else
20140         break;
20141     }
20142
20143   if (stream_name_set > 0)
20144     {
20145       if (vec_len (stream_name) > 255)
20146         {
20147           errmsg ("stream name too long");
20148           return -99;
20149         }
20150     }
20151
20152   u32 name_len = vec_len (stream_name);
20153   /* Construct the API message */
20154   M (PG_ENABLE_DISABLE, mp);
20155   mp->context = 0;
20156   mp->is_enabled = enable;
20157   if (stream_name_set != 0)
20158     {
20159       mp->stream_name_length = ntohl (name_len);
20160       clib_memcpy (mp->stream_name, stream_name, name_len);
20161     }
20162   vec_free (stream_name);
20163
20164   S (mp);
20165   W (ret);
20166   return ret;
20167 }
20168
20169 int
20170 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20171 {
20172   unformat_input_t *input = vam->input;
20173   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20174
20175   u16 *low_ports = 0;
20176   u16 *high_ports = 0;
20177   u16 this_low;
20178   u16 this_hi;
20179   vl_api_prefix_t prefix;
20180   u32 tmp, tmp2;
20181   u8 prefix_set = 0;
20182   u32 vrf_id = ~0;
20183   u8 is_add = 1;
20184   u8 is_ipv6 = 0;
20185   int ret;
20186
20187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20188     {
20189       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20190         prefix_set = 1;
20191       else if (unformat (input, "vrf %d", &vrf_id))
20192         ;
20193       else if (unformat (input, "del"))
20194         is_add = 0;
20195       else if (unformat (input, "port %d", &tmp))
20196         {
20197           if (tmp == 0 || tmp > 65535)
20198             {
20199               errmsg ("port %d out of range", tmp);
20200               return -99;
20201             }
20202           this_low = tmp;
20203           this_hi = this_low + 1;
20204           vec_add1 (low_ports, this_low);
20205           vec_add1 (high_ports, this_hi);
20206         }
20207       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20208         {
20209           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20210             {
20211               errmsg ("incorrect range parameters");
20212               return -99;
20213             }
20214           this_low = tmp;
20215           /* Note: in debug CLI +1 is added to high before
20216              passing to real fn that does "the work"
20217              (ip_source_and_port_range_check_add_del).
20218              This fn is a wrapper around the binary API fn a
20219              control plane will call, which expects this increment
20220              to have occurred. Hence letting the binary API control
20221              plane fn do the increment for consistency between VAT
20222              and other control planes.
20223            */
20224           this_hi = tmp2;
20225           vec_add1 (low_ports, this_low);
20226           vec_add1 (high_ports, this_hi);
20227         }
20228       else
20229         break;
20230     }
20231
20232   if (prefix_set == 0)
20233     {
20234       errmsg ("<address>/<mask> not specified");
20235       return -99;
20236     }
20237
20238   if (vrf_id == ~0)
20239     {
20240       errmsg ("VRF ID required, not specified");
20241       return -99;
20242     }
20243
20244   if (vrf_id == 0)
20245     {
20246       errmsg
20247         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20248       return -99;
20249     }
20250
20251   if (vec_len (low_ports) == 0)
20252     {
20253       errmsg ("At least one port or port range required");
20254       return -99;
20255     }
20256
20257   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20258
20259   mp->is_add = is_add;
20260
20261   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20262
20263   mp->number_of_ranges = vec_len (low_ports);
20264
20265   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20266   vec_free (low_ports);
20267
20268   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20269   vec_free (high_ports);
20270
20271   mp->vrf_id = ntohl (vrf_id);
20272
20273   S (mp);
20274   W (ret);
20275   return ret;
20276 }
20277
20278 int
20279 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20280 {
20281   unformat_input_t *input = vam->input;
20282   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20283   u32 sw_if_index = ~0;
20284   int vrf_set = 0;
20285   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20286   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20287   u8 is_add = 1;
20288   int ret;
20289
20290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20291     {
20292       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20293         ;
20294       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20295         ;
20296       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20297         vrf_set = 1;
20298       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20299         vrf_set = 1;
20300       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20301         vrf_set = 1;
20302       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20303         vrf_set = 1;
20304       else if (unformat (input, "del"))
20305         is_add = 0;
20306       else
20307         break;
20308     }
20309
20310   if (sw_if_index == ~0)
20311     {
20312       errmsg ("Interface required but not specified");
20313       return -99;
20314     }
20315
20316   if (vrf_set == 0)
20317     {
20318       errmsg ("VRF ID required but not specified");
20319       return -99;
20320     }
20321
20322   if (tcp_out_vrf_id == 0
20323       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20324     {
20325       errmsg
20326         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20327       return -99;
20328     }
20329
20330   /* Construct the API message */
20331   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20332
20333   mp->sw_if_index = ntohl (sw_if_index);
20334   mp->is_add = is_add;
20335   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20336   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20337   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20338   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20339
20340   /* send it... */
20341   S (mp);
20342
20343   /* Wait for a reply... */
20344   W (ret);
20345   return ret;
20346 }
20347
20348 static int
20349 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20350 {
20351   unformat_input_t *i = vam->input;
20352   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20353   u32 local_sa_id = 0;
20354   u32 remote_sa_id = 0;
20355   ip4_address_t src_address;
20356   ip4_address_t dst_address;
20357   u8 is_add = 1;
20358   int ret;
20359
20360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20361     {
20362       if (unformat (i, "local_sa %d", &local_sa_id))
20363         ;
20364       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20365         ;
20366       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20367         ;
20368       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20369         ;
20370       else if (unformat (i, "del"))
20371         is_add = 0;
20372       else
20373         {
20374           clib_warning ("parse error '%U'", format_unformat_error, i);
20375           return -99;
20376         }
20377     }
20378
20379   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20380
20381   mp->local_sa_id = ntohl (local_sa_id);
20382   mp->remote_sa_id = ntohl (remote_sa_id);
20383   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20384   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20385   mp->is_add = is_add;
20386
20387   S (mp);
20388   W (ret);
20389   return ret;
20390 }
20391
20392 static int
20393 api_set_punt (vat_main_t * vam)
20394 {
20395   unformat_input_t *i = vam->input;
20396   vl_api_set_punt_t *mp;
20397   u32 ipv = ~0;
20398   u32 protocol = ~0;
20399   u32 port = ~0;
20400   int is_add = 1;
20401   int ret;
20402
20403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20404     {
20405       if (unformat (i, "ip %d", &ipv))
20406         ;
20407       else if (unformat (i, "protocol %d", &protocol))
20408         ;
20409       else if (unformat (i, "port %d", &port))
20410         ;
20411       else if (unformat (i, "del"))
20412         is_add = 0;
20413       else
20414         {
20415           clib_warning ("parse error '%U'", format_unformat_error, i);
20416           return -99;
20417         }
20418     }
20419
20420   M (SET_PUNT, mp);
20421
20422   mp->is_add = (u8) is_add;
20423   mp->punt.ipv = (u8) ipv;
20424   mp->punt.l4_protocol = (u8) protocol;
20425   mp->punt.l4_port = htons ((u16) port);
20426
20427   S (mp);
20428   W (ret);
20429   return ret;
20430 }
20431
20432 static void vl_api_ipsec_gre_tunnel_details_t_handler
20433   (vl_api_ipsec_gre_tunnel_details_t * mp)
20434 {
20435   vat_main_t *vam = &vat_main;
20436
20437   print (vam->ofp, "%11d%15U%15U%14d%14d",
20438          ntohl (mp->sw_if_index),
20439          format_ip4_address, &mp->src_address,
20440          format_ip4_address, &mp->dst_address,
20441          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20442 }
20443
20444 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20445   (vl_api_ipsec_gre_tunnel_details_t * mp)
20446 {
20447   vat_main_t *vam = &vat_main;
20448   vat_json_node_t *node = NULL;
20449   struct in_addr ip4;
20450
20451   if (VAT_JSON_ARRAY != vam->json_tree.type)
20452     {
20453       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20454       vat_json_init_array (&vam->json_tree);
20455     }
20456   node = vat_json_array_add (&vam->json_tree);
20457
20458   vat_json_init_object (node);
20459   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20460   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20461   vat_json_object_add_ip4 (node, "src_address", ip4);
20462   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20463   vat_json_object_add_ip4 (node, "dst_address", ip4);
20464   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20465   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20466 }
20467
20468 static int
20469 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20470 {
20471   unformat_input_t *i = vam->input;
20472   vl_api_ipsec_gre_tunnel_dump_t *mp;
20473   vl_api_control_ping_t *mp_ping;
20474   u32 sw_if_index;
20475   u8 sw_if_index_set = 0;
20476   int ret;
20477
20478   /* Parse args required to build the message */
20479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20480     {
20481       if (unformat (i, "sw_if_index %d", &sw_if_index))
20482         sw_if_index_set = 1;
20483       else
20484         break;
20485     }
20486
20487   if (sw_if_index_set == 0)
20488     {
20489       sw_if_index = ~0;
20490     }
20491
20492   if (!vam->json_output)
20493     {
20494       print (vam->ofp, "%11s%15s%15s%14s%14s",
20495              "sw_if_index", "src_address", "dst_address",
20496              "local_sa_id", "remote_sa_id");
20497     }
20498
20499   /* Get list of gre-tunnel interfaces */
20500   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20501
20502   mp->sw_if_index = htonl (sw_if_index);
20503
20504   S (mp);
20505
20506   /* Use a control ping for synchronization */
20507   MPING (CONTROL_PING, mp_ping);
20508   S (mp_ping);
20509
20510   W (ret);
20511   return ret;
20512 }
20513
20514 static int
20515 api_delete_subif (vat_main_t * vam)
20516 {
20517   unformat_input_t *i = vam->input;
20518   vl_api_delete_subif_t *mp;
20519   u32 sw_if_index = ~0;
20520   int ret;
20521
20522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20523     {
20524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20525         ;
20526       if (unformat (i, "sw_if_index %d", &sw_if_index))
20527         ;
20528       else
20529         break;
20530     }
20531
20532   if (sw_if_index == ~0)
20533     {
20534       errmsg ("missing sw_if_index");
20535       return -99;
20536     }
20537
20538   /* Construct the API message */
20539   M (DELETE_SUBIF, mp);
20540   mp->sw_if_index = ntohl (sw_if_index);
20541
20542   S (mp);
20543   W (ret);
20544   return ret;
20545 }
20546
20547 #define foreach_pbb_vtr_op      \
20548 _("disable",  L2_VTR_DISABLED)  \
20549 _("pop",  L2_VTR_POP_2)         \
20550 _("push",  L2_VTR_PUSH_2)
20551
20552 static int
20553 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20554 {
20555   unformat_input_t *i = vam->input;
20556   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20557   u32 sw_if_index = ~0, vtr_op = ~0;
20558   u16 outer_tag = ~0;
20559   u8 dmac[6], smac[6];
20560   u8 dmac_set = 0, smac_set = 0;
20561   u16 vlanid = 0;
20562   u32 sid = ~0;
20563   u32 tmp;
20564   int ret;
20565
20566   /* Shut up coverity */
20567   clib_memset (dmac, 0, sizeof (dmac));
20568   clib_memset (smac, 0, sizeof (smac));
20569
20570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20571     {
20572       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20573         ;
20574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20575         ;
20576       else if (unformat (i, "vtr_op %d", &vtr_op))
20577         ;
20578 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20579       foreach_pbb_vtr_op
20580 #undef _
20581         else if (unformat (i, "translate_pbb_stag"))
20582         {
20583           if (unformat (i, "%d", &tmp))
20584             {
20585               vtr_op = L2_VTR_TRANSLATE_2_1;
20586               outer_tag = tmp;
20587             }
20588           else
20589             {
20590               errmsg
20591                 ("translate_pbb_stag operation requires outer tag definition");
20592               return -99;
20593             }
20594         }
20595       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20596         dmac_set++;
20597       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20598         smac_set++;
20599       else if (unformat (i, "sid %d", &sid))
20600         ;
20601       else if (unformat (i, "vlanid %d", &tmp))
20602         vlanid = tmp;
20603       else
20604         {
20605           clib_warning ("parse error '%U'", format_unformat_error, i);
20606           return -99;
20607         }
20608     }
20609
20610   if ((sw_if_index == ~0) || (vtr_op == ~0))
20611     {
20612       errmsg ("missing sw_if_index or vtr operation");
20613       return -99;
20614     }
20615   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20616       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20617     {
20618       errmsg
20619         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20620       return -99;
20621     }
20622
20623   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20624   mp->sw_if_index = ntohl (sw_if_index);
20625   mp->vtr_op = ntohl (vtr_op);
20626   mp->outer_tag = ntohs (outer_tag);
20627   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20628   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20629   mp->b_vlanid = ntohs (vlanid);
20630   mp->i_sid = ntohl (sid);
20631
20632   S (mp);
20633   W (ret);
20634   return ret;
20635 }
20636
20637 static int
20638 api_flow_classify_set_interface (vat_main_t * vam)
20639 {
20640   unformat_input_t *i = vam->input;
20641   vl_api_flow_classify_set_interface_t *mp;
20642   u32 sw_if_index;
20643   int sw_if_index_set;
20644   u32 ip4_table_index = ~0;
20645   u32 ip6_table_index = ~0;
20646   u8 is_add = 1;
20647   int ret;
20648
20649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20650     {
20651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20652         sw_if_index_set = 1;
20653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20654         sw_if_index_set = 1;
20655       else if (unformat (i, "del"))
20656         is_add = 0;
20657       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20658         ;
20659       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20660         ;
20661       else
20662         {
20663           clib_warning ("parse error '%U'", format_unformat_error, i);
20664           return -99;
20665         }
20666     }
20667
20668   if (sw_if_index_set == 0)
20669     {
20670       errmsg ("missing interface name or sw_if_index");
20671       return -99;
20672     }
20673
20674   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20675
20676   mp->sw_if_index = ntohl (sw_if_index);
20677   mp->ip4_table_index = ntohl (ip4_table_index);
20678   mp->ip6_table_index = ntohl (ip6_table_index);
20679   mp->is_add = is_add;
20680
20681   S (mp);
20682   W (ret);
20683   return ret;
20684 }
20685
20686 static int
20687 api_flow_classify_dump (vat_main_t * vam)
20688 {
20689   unformat_input_t *i = vam->input;
20690   vl_api_flow_classify_dump_t *mp;
20691   vl_api_control_ping_t *mp_ping;
20692   u8 type = FLOW_CLASSIFY_N_TABLES;
20693   int ret;
20694
20695   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20696     ;
20697   else
20698     {
20699       errmsg ("classify table type must be specified");
20700       return -99;
20701     }
20702
20703   if (!vam->json_output)
20704     {
20705       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20706     }
20707
20708   M (FLOW_CLASSIFY_DUMP, mp);
20709   mp->type = type;
20710   /* send it... */
20711   S (mp);
20712
20713   /* Use a control ping for synchronization */
20714   MPING (CONTROL_PING, mp_ping);
20715   S (mp_ping);
20716
20717   /* Wait for a reply... */
20718   W (ret);
20719   return ret;
20720 }
20721
20722 static int
20723 api_feature_enable_disable (vat_main_t * vam)
20724 {
20725   unformat_input_t *i = vam->input;
20726   vl_api_feature_enable_disable_t *mp;
20727   u8 *arc_name = 0;
20728   u8 *feature_name = 0;
20729   u32 sw_if_index = ~0;
20730   u8 enable = 1;
20731   int ret;
20732
20733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20734     {
20735       if (unformat (i, "arc_name %s", &arc_name))
20736         ;
20737       else if (unformat (i, "feature_name %s", &feature_name))
20738         ;
20739       else
20740         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20741         ;
20742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20743         ;
20744       else if (unformat (i, "disable"))
20745         enable = 0;
20746       else
20747         break;
20748     }
20749
20750   if (arc_name == 0)
20751     {
20752       errmsg ("missing arc name");
20753       return -99;
20754     }
20755   if (vec_len (arc_name) > 63)
20756     {
20757       errmsg ("arc name too long");
20758     }
20759
20760   if (feature_name == 0)
20761     {
20762       errmsg ("missing feature name");
20763       return -99;
20764     }
20765   if (vec_len (feature_name) > 63)
20766     {
20767       errmsg ("feature name too long");
20768     }
20769
20770   if (sw_if_index == ~0)
20771     {
20772       errmsg ("missing interface name or sw_if_index");
20773       return -99;
20774     }
20775
20776   /* Construct the API message */
20777   M (FEATURE_ENABLE_DISABLE, mp);
20778   mp->sw_if_index = ntohl (sw_if_index);
20779   mp->enable = enable;
20780   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20781   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20782   vec_free (arc_name);
20783   vec_free (feature_name);
20784
20785   S (mp);
20786   W (ret);
20787   return ret;
20788 }
20789
20790 static int
20791 api_sw_interface_tag_add_del (vat_main_t * vam)
20792 {
20793   unformat_input_t *i = vam->input;
20794   vl_api_sw_interface_tag_add_del_t *mp;
20795   u32 sw_if_index = ~0;
20796   u8 *tag = 0;
20797   u8 enable = 1;
20798   int ret;
20799
20800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20801     {
20802       if (unformat (i, "tag %s", &tag))
20803         ;
20804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20805         ;
20806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20807         ;
20808       else if (unformat (i, "del"))
20809         enable = 0;
20810       else
20811         break;
20812     }
20813
20814   if (sw_if_index == ~0)
20815     {
20816       errmsg ("missing interface name or sw_if_index");
20817       return -99;
20818     }
20819
20820   if (enable && (tag == 0))
20821     {
20822       errmsg ("no tag specified");
20823       return -99;
20824     }
20825
20826   /* Construct the API message */
20827   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20828   mp->sw_if_index = ntohl (sw_if_index);
20829   mp->is_add = enable;
20830   if (enable)
20831     vl_api_to_api_string (strlen ((char *) tag), tag, &mp->tag);
20832   vec_free (tag);
20833
20834   S (mp);
20835   W (ret);
20836   return ret;
20837 }
20838
20839 static void vl_api_l2_xconnect_details_t_handler
20840   (vl_api_l2_xconnect_details_t * mp)
20841 {
20842   vat_main_t *vam = &vat_main;
20843
20844   print (vam->ofp, "%15d%15d",
20845          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20846 }
20847
20848 static void vl_api_l2_xconnect_details_t_handler_json
20849   (vl_api_l2_xconnect_details_t * mp)
20850 {
20851   vat_main_t *vam = &vat_main;
20852   vat_json_node_t *node = NULL;
20853
20854   if (VAT_JSON_ARRAY != vam->json_tree.type)
20855     {
20856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20857       vat_json_init_array (&vam->json_tree);
20858     }
20859   node = vat_json_array_add (&vam->json_tree);
20860
20861   vat_json_init_object (node);
20862   vat_json_object_add_uint (node, "rx_sw_if_index",
20863                             ntohl (mp->rx_sw_if_index));
20864   vat_json_object_add_uint (node, "tx_sw_if_index",
20865                             ntohl (mp->tx_sw_if_index));
20866 }
20867
20868 static int
20869 api_l2_xconnect_dump (vat_main_t * vam)
20870 {
20871   vl_api_l2_xconnect_dump_t *mp;
20872   vl_api_control_ping_t *mp_ping;
20873   int ret;
20874
20875   if (!vam->json_output)
20876     {
20877       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20878     }
20879
20880   M (L2_XCONNECT_DUMP, mp);
20881
20882   S (mp);
20883
20884   /* Use a control ping for synchronization */
20885   MPING (CONTROL_PING, mp_ping);
20886   S (mp_ping);
20887
20888   W (ret);
20889   return ret;
20890 }
20891
20892 static int
20893 api_hw_interface_set_mtu (vat_main_t * vam)
20894 {
20895   unformat_input_t *i = vam->input;
20896   vl_api_hw_interface_set_mtu_t *mp;
20897   u32 sw_if_index = ~0;
20898   u32 mtu = 0;
20899   int ret;
20900
20901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20902     {
20903       if (unformat (i, "mtu %d", &mtu))
20904         ;
20905       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20906         ;
20907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20908         ;
20909       else
20910         break;
20911     }
20912
20913   if (sw_if_index == ~0)
20914     {
20915       errmsg ("missing interface name or sw_if_index");
20916       return -99;
20917     }
20918
20919   if (mtu == 0)
20920     {
20921       errmsg ("no mtu specified");
20922       return -99;
20923     }
20924
20925   /* Construct the API message */
20926   M (HW_INTERFACE_SET_MTU, mp);
20927   mp->sw_if_index = ntohl (sw_if_index);
20928   mp->mtu = ntohs ((u16) mtu);
20929
20930   S (mp);
20931   W (ret);
20932   return ret;
20933 }
20934
20935 static int
20936 api_p2p_ethernet_add (vat_main_t * vam)
20937 {
20938   unformat_input_t *i = vam->input;
20939   vl_api_p2p_ethernet_add_t *mp;
20940   u32 parent_if_index = ~0;
20941   u32 sub_id = ~0;
20942   u8 remote_mac[6];
20943   u8 mac_set = 0;
20944   int ret;
20945
20946   clib_memset (remote_mac, 0, sizeof (remote_mac));
20947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20948     {
20949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20950         ;
20951       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20952         ;
20953       else
20954         if (unformat
20955             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20956         mac_set++;
20957       else if (unformat (i, "sub_id %d", &sub_id))
20958         ;
20959       else
20960         {
20961           clib_warning ("parse error '%U'", format_unformat_error, i);
20962           return -99;
20963         }
20964     }
20965
20966   if (parent_if_index == ~0)
20967     {
20968       errmsg ("missing interface name or sw_if_index");
20969       return -99;
20970     }
20971   if (mac_set == 0)
20972     {
20973       errmsg ("missing remote mac address");
20974       return -99;
20975     }
20976   if (sub_id == ~0)
20977     {
20978       errmsg ("missing sub-interface id");
20979       return -99;
20980     }
20981
20982   M (P2P_ETHERNET_ADD, mp);
20983   mp->parent_if_index = ntohl (parent_if_index);
20984   mp->subif_id = ntohl (sub_id);
20985   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20986
20987   S (mp);
20988   W (ret);
20989   return ret;
20990 }
20991
20992 static int
20993 api_p2p_ethernet_del (vat_main_t * vam)
20994 {
20995   unformat_input_t *i = vam->input;
20996   vl_api_p2p_ethernet_del_t *mp;
20997   u32 parent_if_index = ~0;
20998   u8 remote_mac[6];
20999   u8 mac_set = 0;
21000   int ret;
21001
21002   clib_memset (remote_mac, 0, sizeof (remote_mac));
21003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21004     {
21005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21006         ;
21007       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21008         ;
21009       else
21010         if (unformat
21011             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21012         mac_set++;
21013       else
21014         {
21015           clib_warning ("parse error '%U'", format_unformat_error, i);
21016           return -99;
21017         }
21018     }
21019
21020   if (parent_if_index == ~0)
21021     {
21022       errmsg ("missing interface name or sw_if_index");
21023       return -99;
21024     }
21025   if (mac_set == 0)
21026     {
21027       errmsg ("missing remote mac address");
21028       return -99;
21029     }
21030
21031   M (P2P_ETHERNET_DEL, mp);
21032   mp->parent_if_index = ntohl (parent_if_index);
21033   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21034
21035   S (mp);
21036   W (ret);
21037   return ret;
21038 }
21039
21040 static int
21041 api_lldp_config (vat_main_t * vam)
21042 {
21043   unformat_input_t *i = vam->input;
21044   vl_api_lldp_config_t *mp;
21045   int tx_hold = 0;
21046   int tx_interval = 0;
21047   u8 *sys_name = NULL;
21048   int ret;
21049
21050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21051     {
21052       if (unformat (i, "system-name %s", &sys_name))
21053         ;
21054       else if (unformat (i, "tx-hold %d", &tx_hold))
21055         ;
21056       else if (unformat (i, "tx-interval %d", &tx_interval))
21057         ;
21058       else
21059         {
21060           clib_warning ("parse error '%U'", format_unformat_error, i);
21061           return -99;
21062         }
21063     }
21064
21065   vec_add1 (sys_name, 0);
21066
21067   M (LLDP_CONFIG, mp);
21068   mp->tx_hold = htonl (tx_hold);
21069   mp->tx_interval = htonl (tx_interval);
21070   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21071   vec_free (sys_name);
21072
21073   S (mp);
21074   W (ret);
21075   return ret;
21076 }
21077
21078 static int
21079 api_sw_interface_set_lldp (vat_main_t * vam)
21080 {
21081   unformat_input_t *i = vam->input;
21082   vl_api_sw_interface_set_lldp_t *mp;
21083   u32 sw_if_index = ~0;
21084   u32 enable = 1;
21085   u8 *port_desc = NULL, *mgmt_oid = NULL;
21086   ip4_address_t ip4_addr;
21087   ip6_address_t ip6_addr;
21088   int ret;
21089
21090   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21091   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21092
21093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21094     {
21095       if (unformat (i, "disable"))
21096         enable = 0;
21097       else
21098         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21099         ;
21100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21101         ;
21102       else if (unformat (i, "port-desc %s", &port_desc))
21103         ;
21104       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21105         ;
21106       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21107         ;
21108       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21109         ;
21110       else
21111         break;
21112     }
21113
21114   if (sw_if_index == ~0)
21115     {
21116       errmsg ("missing interface name or sw_if_index");
21117       return -99;
21118     }
21119
21120   /* Construct the API message */
21121   vec_add1 (port_desc, 0);
21122   vec_add1 (mgmt_oid, 0);
21123   M (SW_INTERFACE_SET_LLDP, mp);
21124   mp->sw_if_index = ntohl (sw_if_index);
21125   mp->enable = enable;
21126   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21127   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21128   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21129   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21130   vec_free (port_desc);
21131   vec_free (mgmt_oid);
21132
21133   S (mp);
21134   W (ret);
21135   return ret;
21136 }
21137
21138 static int
21139 api_tcp_configure_src_addresses (vat_main_t * vam)
21140 {
21141   vl_api_tcp_configure_src_addresses_t *mp;
21142   unformat_input_t *i = vam->input;
21143   ip4_address_t v4first, v4last;
21144   ip6_address_t v6first, v6last;
21145   u8 range_set = 0;
21146   u32 vrf_id = 0;
21147   int ret;
21148
21149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21150     {
21151       if (unformat (i, "%U - %U",
21152                     unformat_ip4_address, &v4first,
21153                     unformat_ip4_address, &v4last))
21154         {
21155           if (range_set)
21156             {
21157               errmsg ("one range per message (range already set)");
21158               return -99;
21159             }
21160           range_set = 1;
21161         }
21162       else if (unformat (i, "%U - %U",
21163                          unformat_ip6_address, &v6first,
21164                          unformat_ip6_address, &v6last))
21165         {
21166           if (range_set)
21167             {
21168               errmsg ("one range per message (range already set)");
21169               return -99;
21170             }
21171           range_set = 2;
21172         }
21173       else if (unformat (i, "vrf %d", &vrf_id))
21174         ;
21175       else
21176         break;
21177     }
21178
21179   if (range_set == 0)
21180     {
21181       errmsg ("address range not set");
21182       return -99;
21183     }
21184
21185   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21186   mp->vrf_id = ntohl (vrf_id);
21187   /* ipv6? */
21188   if (range_set == 2)
21189     {
21190       mp->is_ipv6 = 1;
21191       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21192       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21193     }
21194   else
21195     {
21196       mp->is_ipv6 = 0;
21197       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21198       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21199     }
21200   S (mp);
21201   W (ret);
21202   return ret;
21203 }
21204
21205 static void vl_api_app_namespace_add_del_reply_t_handler
21206   (vl_api_app_namespace_add_del_reply_t * mp)
21207 {
21208   vat_main_t *vam = &vat_main;
21209   i32 retval = ntohl (mp->retval);
21210   if (vam->async_mode)
21211     {
21212       vam->async_errors += (retval < 0);
21213     }
21214   else
21215     {
21216       vam->retval = retval;
21217       if (retval == 0)
21218         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21219       vam->result_ready = 1;
21220     }
21221 }
21222
21223 static void vl_api_app_namespace_add_del_reply_t_handler_json
21224   (vl_api_app_namespace_add_del_reply_t * mp)
21225 {
21226   vat_main_t *vam = &vat_main;
21227   vat_json_node_t node;
21228
21229   vat_json_init_object (&node);
21230   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21231   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21232
21233   vat_json_print (vam->ofp, &node);
21234   vat_json_free (&node);
21235
21236   vam->retval = ntohl (mp->retval);
21237   vam->result_ready = 1;
21238 }
21239
21240 static int
21241 api_app_namespace_add_del (vat_main_t * vam)
21242 {
21243   vl_api_app_namespace_add_del_t *mp;
21244   unformat_input_t *i = vam->input;
21245   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21246   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21247   u64 secret;
21248   int ret;
21249
21250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21251     {
21252       if (unformat (i, "id %_%v%_", &ns_id))
21253         ;
21254       else if (unformat (i, "secret %lu", &secret))
21255         secret_set = 1;
21256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21257         sw_if_index_set = 1;
21258       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21259         ;
21260       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21261         ;
21262       else
21263         break;
21264     }
21265   if (!ns_id || !secret_set || !sw_if_index_set)
21266     {
21267       errmsg ("namespace id, secret and sw_if_index must be set");
21268       return -99;
21269     }
21270   if (vec_len (ns_id) > 64)
21271     {
21272       errmsg ("namespace id too long");
21273       return -99;
21274     }
21275   M (APP_NAMESPACE_ADD_DEL, mp);
21276
21277   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21278   mp->namespace_id_len = vec_len (ns_id);
21279   mp->secret = clib_host_to_net_u64 (secret);
21280   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21281   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21282   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21283   vec_free (ns_id);
21284   S (mp);
21285   W (ret);
21286   return ret;
21287 }
21288
21289 static int
21290 api_sock_init_shm (vat_main_t * vam)
21291 {
21292 #if VPP_API_TEST_BUILTIN == 0
21293   unformat_input_t *i = vam->input;
21294   vl_api_shm_elem_config_t *config = 0;
21295   u64 size = 64 << 20;
21296   int rv;
21297
21298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21299     {
21300       if (unformat (i, "size %U", unformat_memory_size, &size))
21301         ;
21302       else
21303         break;
21304     }
21305
21306   /*
21307    * Canned custom ring allocator config.
21308    * Should probably parse all of this
21309    */
21310   vec_validate (config, 6);
21311   config[0].type = VL_API_VLIB_RING;
21312   config[0].size = 256;
21313   config[0].count = 32;
21314
21315   config[1].type = VL_API_VLIB_RING;
21316   config[1].size = 1024;
21317   config[1].count = 16;
21318
21319   config[2].type = VL_API_VLIB_RING;
21320   config[2].size = 4096;
21321   config[2].count = 2;
21322
21323   config[3].type = VL_API_CLIENT_RING;
21324   config[3].size = 256;
21325   config[3].count = 32;
21326
21327   config[4].type = VL_API_CLIENT_RING;
21328   config[4].size = 1024;
21329   config[4].count = 16;
21330
21331   config[5].type = VL_API_CLIENT_RING;
21332   config[5].size = 4096;
21333   config[5].count = 2;
21334
21335   config[6].type = VL_API_QUEUE;
21336   config[6].count = 128;
21337   config[6].size = sizeof (uword);
21338
21339   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21340   if (!rv)
21341     vam->client_index_invalid = 1;
21342   return rv;
21343 #else
21344   return -99;
21345 #endif
21346 }
21347
21348 static int
21349 api_dns_enable_disable (vat_main_t * vam)
21350 {
21351   unformat_input_t *line_input = vam->input;
21352   vl_api_dns_enable_disable_t *mp;
21353   u8 enable_disable = 1;
21354   int ret;
21355
21356   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21357     {
21358       if (unformat (line_input, "disable"))
21359         enable_disable = 0;
21360       if (unformat (line_input, "enable"))
21361         enable_disable = 1;
21362       else
21363         break;
21364     }
21365
21366   /* Construct the API message */
21367   M (DNS_ENABLE_DISABLE, mp);
21368   mp->enable = enable_disable;
21369
21370   /* send it... */
21371   S (mp);
21372   /* Wait for the reply */
21373   W (ret);
21374   return ret;
21375 }
21376
21377 static int
21378 api_dns_resolve_name (vat_main_t * vam)
21379 {
21380   unformat_input_t *line_input = vam->input;
21381   vl_api_dns_resolve_name_t *mp;
21382   u8 *name = 0;
21383   int ret;
21384
21385   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21386     {
21387       if (unformat (line_input, "%s", &name))
21388         ;
21389       else
21390         break;
21391     }
21392
21393   if (vec_len (name) > 127)
21394     {
21395       errmsg ("name too long");
21396       return -99;
21397     }
21398
21399   /* Construct the API message */
21400   M (DNS_RESOLVE_NAME, mp);
21401   memcpy (mp->name, name, vec_len (name));
21402   vec_free (name);
21403
21404   /* send it... */
21405   S (mp);
21406   /* Wait for the reply */
21407   W (ret);
21408   return ret;
21409 }
21410
21411 static int
21412 api_dns_resolve_ip (vat_main_t * vam)
21413 {
21414   unformat_input_t *line_input = vam->input;
21415   vl_api_dns_resolve_ip_t *mp;
21416   int is_ip6 = -1;
21417   ip4_address_t addr4;
21418   ip6_address_t addr6;
21419   int ret;
21420
21421   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21422     {
21423       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21424         is_ip6 = 1;
21425       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21426         is_ip6 = 0;
21427       else
21428         break;
21429     }
21430
21431   if (is_ip6 == -1)
21432     {
21433       errmsg ("missing address");
21434       return -99;
21435     }
21436
21437   /* Construct the API message */
21438   M (DNS_RESOLVE_IP, mp);
21439   mp->is_ip6 = is_ip6;
21440   if (is_ip6)
21441     memcpy (mp->address, &addr6, sizeof (addr6));
21442   else
21443     memcpy (mp->address, &addr4, sizeof (addr4));
21444
21445   /* send it... */
21446   S (mp);
21447   /* Wait for the reply */
21448   W (ret);
21449   return ret;
21450 }
21451
21452 static int
21453 api_dns_name_server_add_del (vat_main_t * vam)
21454 {
21455   unformat_input_t *i = vam->input;
21456   vl_api_dns_name_server_add_del_t *mp;
21457   u8 is_add = 1;
21458   ip6_address_t ip6_server;
21459   ip4_address_t ip4_server;
21460   int ip6_set = 0;
21461   int ip4_set = 0;
21462   int ret = 0;
21463
21464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21465     {
21466       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21467         ip6_set = 1;
21468       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21469         ip4_set = 1;
21470       else if (unformat (i, "del"))
21471         is_add = 0;
21472       else
21473         {
21474           clib_warning ("parse error '%U'", format_unformat_error, i);
21475           return -99;
21476         }
21477     }
21478
21479   if (ip4_set && ip6_set)
21480     {
21481       errmsg ("Only one server address allowed per message");
21482       return -99;
21483     }
21484   if ((ip4_set + ip6_set) == 0)
21485     {
21486       errmsg ("Server address required");
21487       return -99;
21488     }
21489
21490   /* Construct the API message */
21491   M (DNS_NAME_SERVER_ADD_DEL, mp);
21492
21493   if (ip6_set)
21494     {
21495       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21496       mp->is_ip6 = 1;
21497     }
21498   else
21499     {
21500       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21501       mp->is_ip6 = 0;
21502     }
21503
21504   mp->is_add = is_add;
21505
21506   /* send it... */
21507   S (mp);
21508
21509   /* Wait for a reply, return good/bad news  */
21510   W (ret);
21511   return ret;
21512 }
21513
21514 static void
21515 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21516 {
21517   vat_main_t *vam = &vat_main;
21518
21519   if (mp->is_ip4)
21520     {
21521       print (vam->ofp,
21522              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21523              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21524              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21525              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21526              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21527              clib_net_to_host_u32 (mp->action_index), mp->tag);
21528     }
21529   else
21530     {
21531       print (vam->ofp,
21532              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21533              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21534              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21535              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21536              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21537              clib_net_to_host_u32 (mp->action_index), mp->tag);
21538     }
21539 }
21540
21541 static void
21542 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21543                                              mp)
21544 {
21545   vat_main_t *vam = &vat_main;
21546   vat_json_node_t *node = NULL;
21547   struct in6_addr ip6;
21548   struct in_addr ip4;
21549
21550   if (VAT_JSON_ARRAY != vam->json_tree.type)
21551     {
21552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21553       vat_json_init_array (&vam->json_tree);
21554     }
21555   node = vat_json_array_add (&vam->json_tree);
21556   vat_json_init_object (node);
21557
21558   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21559   vat_json_object_add_uint (node, "appns_index",
21560                             clib_net_to_host_u32 (mp->appns_index));
21561   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21562   vat_json_object_add_uint (node, "scope", mp->scope);
21563   vat_json_object_add_uint (node, "action_index",
21564                             clib_net_to_host_u32 (mp->action_index));
21565   vat_json_object_add_uint (node, "lcl_port",
21566                             clib_net_to_host_u16 (mp->lcl_port));
21567   vat_json_object_add_uint (node, "rmt_port",
21568                             clib_net_to_host_u16 (mp->rmt_port));
21569   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21570   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21571   vat_json_object_add_string_copy (node, "tag", mp->tag);
21572   if (mp->is_ip4)
21573     {
21574       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21575       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21576       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21577       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21578     }
21579   else
21580     {
21581       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21582       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21583       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21584       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21585     }
21586 }
21587
21588 static int
21589 api_session_rule_add_del (vat_main_t * vam)
21590 {
21591   vl_api_session_rule_add_del_t *mp;
21592   unformat_input_t *i = vam->input;
21593   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21594   u32 appns_index = 0, scope = 0;
21595   ip4_address_t lcl_ip4, rmt_ip4;
21596   ip6_address_t lcl_ip6, rmt_ip6;
21597   u8 is_ip4 = 1, conn_set = 0;
21598   u8 is_add = 1, *tag = 0;
21599   int ret;
21600
21601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21602     {
21603       if (unformat (i, "del"))
21604         is_add = 0;
21605       else if (unformat (i, "add"))
21606         ;
21607       else if (unformat (i, "proto tcp"))
21608         proto = 0;
21609       else if (unformat (i, "proto udp"))
21610         proto = 1;
21611       else if (unformat (i, "appns %d", &appns_index))
21612         ;
21613       else if (unformat (i, "scope %d", &scope))
21614         ;
21615       else if (unformat (i, "tag %_%v%_", &tag))
21616         ;
21617       else
21618         if (unformat
21619             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21620              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21621              &rmt_port))
21622         {
21623           is_ip4 = 1;
21624           conn_set = 1;
21625         }
21626       else
21627         if (unformat
21628             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21629              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21630              &rmt_port))
21631         {
21632           is_ip4 = 0;
21633           conn_set = 1;
21634         }
21635       else if (unformat (i, "action %d", &action))
21636         ;
21637       else
21638         break;
21639     }
21640   if (proto == ~0 || !conn_set || action == ~0)
21641     {
21642       errmsg ("transport proto, connection and action must be set");
21643       return -99;
21644     }
21645
21646   if (scope > 3)
21647     {
21648       errmsg ("scope should be 0-3");
21649       return -99;
21650     }
21651
21652   M (SESSION_RULE_ADD_DEL, mp);
21653
21654   mp->is_ip4 = is_ip4;
21655   mp->transport_proto = proto;
21656   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21657   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21658   mp->lcl_plen = lcl_plen;
21659   mp->rmt_plen = rmt_plen;
21660   mp->action_index = clib_host_to_net_u32 (action);
21661   mp->appns_index = clib_host_to_net_u32 (appns_index);
21662   mp->scope = scope;
21663   mp->is_add = is_add;
21664   if (is_ip4)
21665     {
21666       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21667       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21668     }
21669   else
21670     {
21671       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21672       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21673     }
21674   if (tag)
21675     {
21676       clib_memcpy (mp->tag, tag, vec_len (tag));
21677       vec_free (tag);
21678     }
21679
21680   S (mp);
21681   W (ret);
21682   return ret;
21683 }
21684
21685 static int
21686 api_session_rules_dump (vat_main_t * vam)
21687 {
21688   vl_api_session_rules_dump_t *mp;
21689   vl_api_control_ping_t *mp_ping;
21690   int ret;
21691
21692   if (!vam->json_output)
21693     {
21694       print (vam->ofp, "%=20s", "Session Rules");
21695     }
21696
21697   M (SESSION_RULES_DUMP, mp);
21698   /* send it... */
21699   S (mp);
21700
21701   /* Use a control ping for synchronization */
21702   MPING (CONTROL_PING, mp_ping);
21703   S (mp_ping);
21704
21705   /* Wait for a reply... */
21706   W (ret);
21707   return ret;
21708 }
21709
21710 static int
21711 api_ip_container_proxy_add_del (vat_main_t * vam)
21712 {
21713   vl_api_ip_container_proxy_add_del_t *mp;
21714   unformat_input_t *i = vam->input;
21715   u32 sw_if_index = ~0;
21716   vl_api_prefix_t pfx = { };
21717   u8 is_add = 1;
21718   int ret;
21719
21720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21721     {
21722       if (unformat (i, "del"))
21723         is_add = 0;
21724       else if (unformat (i, "add"))
21725         ;
21726       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21727         ;
21728       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21729         ;
21730       else
21731         break;
21732     }
21733   if (sw_if_index == ~0 || pfx.address_length == 0)
21734     {
21735       errmsg ("address and sw_if_index must be set");
21736       return -99;
21737     }
21738
21739   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21740
21741   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21742   mp->is_add = is_add;
21743   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21744
21745   S (mp);
21746   W (ret);
21747   return ret;
21748 }
21749
21750 static int
21751 api_qos_record_enable_disable (vat_main_t * vam)
21752 {
21753   unformat_input_t *i = vam->input;
21754   vl_api_qos_record_enable_disable_t *mp;
21755   u32 sw_if_index, qs = 0xff;
21756   u8 sw_if_index_set = 0;
21757   u8 enable = 1;
21758   int ret;
21759
21760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21761     {
21762       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21763         sw_if_index_set = 1;
21764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21765         sw_if_index_set = 1;
21766       else if (unformat (i, "%U", unformat_qos_source, &qs))
21767         ;
21768       else if (unformat (i, "disable"))
21769         enable = 0;
21770       else
21771         {
21772           clib_warning ("parse error '%U'", format_unformat_error, i);
21773           return -99;
21774         }
21775     }
21776
21777   if (sw_if_index_set == 0)
21778     {
21779       errmsg ("missing interface name or sw_if_index");
21780       return -99;
21781     }
21782   if (qs == 0xff)
21783     {
21784       errmsg ("input location must be specified");
21785       return -99;
21786     }
21787
21788   M (QOS_RECORD_ENABLE_DISABLE, mp);
21789
21790   mp->sw_if_index = ntohl (sw_if_index);
21791   mp->input_source = qs;
21792   mp->enable = enable;
21793
21794   S (mp);
21795   W (ret);
21796   return ret;
21797 }
21798
21799
21800 static int
21801 q_or_quit (vat_main_t * vam)
21802 {
21803 #if VPP_API_TEST_BUILTIN == 0
21804   longjmp (vam->jump_buf, 1);
21805 #endif
21806   return 0;                     /* not so much */
21807 }
21808
21809 static int
21810 q (vat_main_t * vam)
21811 {
21812   return q_or_quit (vam);
21813 }
21814
21815 static int
21816 quit (vat_main_t * vam)
21817 {
21818   return q_or_quit (vam);
21819 }
21820
21821 static int
21822 comment (vat_main_t * vam)
21823 {
21824   return 0;
21825 }
21826
21827 static int
21828 statseg (vat_main_t * vam)
21829 {
21830   ssvm_private_t *ssvmp = &vam->stat_segment;
21831   ssvm_shared_header_t *shared_header = ssvmp->sh;
21832   vlib_counter_t **counters;
21833   u64 thread0_index1_packets;
21834   u64 thread0_index1_bytes;
21835   f64 vector_rate, input_rate;
21836   uword *p;
21837
21838   uword *counter_vector_by_name;
21839   if (vam->stat_segment_lockp == 0)
21840     {
21841       errmsg ("Stat segment not mapped...");
21842       return -99;
21843     }
21844
21845   /* look up "/if/rx for sw_if_index 1 as a test */
21846
21847   clib_spinlock_lock (vam->stat_segment_lockp);
21848
21849   counter_vector_by_name = (uword *) shared_header->opaque[1];
21850
21851   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21852   if (p == 0)
21853     {
21854       clib_spinlock_unlock (vam->stat_segment_lockp);
21855       errmsg ("/if/tx not found?");
21856       return -99;
21857     }
21858
21859   /* Fish per-thread vector of combined counters from shared memory */
21860   counters = (vlib_counter_t **) p[0];
21861
21862   if (vec_len (counters[0]) < 2)
21863     {
21864       clib_spinlock_unlock (vam->stat_segment_lockp);
21865       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21866       return -99;
21867     }
21868
21869   /* Read thread 0 sw_if_index 1 counter */
21870   thread0_index1_packets = counters[0][1].packets;
21871   thread0_index1_bytes = counters[0][1].bytes;
21872
21873   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21874   if (p == 0)
21875     {
21876       clib_spinlock_unlock (vam->stat_segment_lockp);
21877       errmsg ("vector_rate not found?");
21878       return -99;
21879     }
21880
21881   vector_rate = *(f64 *) (p[0]);
21882   p = hash_get_mem (counter_vector_by_name, "input_rate");
21883   if (p == 0)
21884     {
21885       clib_spinlock_unlock (vam->stat_segment_lockp);
21886       errmsg ("input_rate not found?");
21887       return -99;
21888     }
21889   input_rate = *(f64 *) (p[0]);
21890
21891   clib_spinlock_unlock (vam->stat_segment_lockp);
21892
21893   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21894          vector_rate, input_rate);
21895   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21896          thread0_index1_packets, thread0_index1_bytes);
21897
21898   return 0;
21899 }
21900
21901 static int
21902 cmd_cmp (void *a1, void *a2)
21903 {
21904   u8 **c1 = a1;
21905   u8 **c2 = a2;
21906
21907   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21908 }
21909
21910 static int
21911 help (vat_main_t * vam)
21912 {
21913   u8 **cmds = 0;
21914   u8 *name = 0;
21915   hash_pair_t *p;
21916   unformat_input_t *i = vam->input;
21917   int j;
21918
21919   if (unformat (i, "%s", &name))
21920     {
21921       uword *hs;
21922
21923       vec_add1 (name, 0);
21924
21925       hs = hash_get_mem (vam->help_by_name, name);
21926       if (hs)
21927         print (vam->ofp, "usage: %s %s", name, hs[0]);
21928       else
21929         print (vam->ofp, "No such msg / command '%s'", name);
21930       vec_free (name);
21931       return 0;
21932     }
21933
21934   print (vam->ofp, "Help is available for the following:");
21935
21936     /* *INDENT-OFF* */
21937     hash_foreach_pair (p, vam->function_by_name,
21938     ({
21939       vec_add1 (cmds, (u8 *)(p->key));
21940     }));
21941     /* *INDENT-ON* */
21942
21943   vec_sort_with_function (cmds, cmd_cmp);
21944
21945   for (j = 0; j < vec_len (cmds); j++)
21946     print (vam->ofp, "%s", cmds[j]);
21947
21948   vec_free (cmds);
21949   return 0;
21950 }
21951
21952 static int
21953 set (vat_main_t * vam)
21954 {
21955   u8 *name = 0, *value = 0;
21956   unformat_input_t *i = vam->input;
21957
21958   if (unformat (i, "%s", &name))
21959     {
21960       /* The input buffer is a vector, not a string. */
21961       value = vec_dup (i->buffer);
21962       vec_delete (value, i->index, 0);
21963       /* Almost certainly has a trailing newline */
21964       if (value[vec_len (value) - 1] == '\n')
21965         value[vec_len (value) - 1] = 0;
21966       /* Make sure it's a proper string, one way or the other */
21967       vec_add1 (value, 0);
21968       (void) clib_macro_set_value (&vam->macro_main,
21969                                    (char *) name, (char *) value);
21970     }
21971   else
21972     errmsg ("usage: set <name> <value>");
21973
21974   vec_free (name);
21975   vec_free (value);
21976   return 0;
21977 }
21978
21979 static int
21980 unset (vat_main_t * vam)
21981 {
21982   u8 *name = 0;
21983
21984   if (unformat (vam->input, "%s", &name))
21985     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21986       errmsg ("unset: %s wasn't set", name);
21987   vec_free (name);
21988   return 0;
21989 }
21990
21991 typedef struct
21992 {
21993   u8 *name;
21994   u8 *value;
21995 } macro_sort_t;
21996
21997
21998 static int
21999 macro_sort_cmp (void *a1, void *a2)
22000 {
22001   macro_sort_t *s1 = a1;
22002   macro_sort_t *s2 = a2;
22003
22004   return strcmp ((char *) (s1->name), (char *) (s2->name));
22005 }
22006
22007 static int
22008 dump_macro_table (vat_main_t * vam)
22009 {
22010   macro_sort_t *sort_me = 0, *sm;
22011   int i;
22012   hash_pair_t *p;
22013
22014     /* *INDENT-OFF* */
22015     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22016     ({
22017       vec_add2 (sort_me, sm, 1);
22018       sm->name = (u8 *)(p->key);
22019       sm->value = (u8 *) (p->value[0]);
22020     }));
22021     /* *INDENT-ON* */
22022
22023   vec_sort_with_function (sort_me, macro_sort_cmp);
22024
22025   if (vec_len (sort_me))
22026     print (vam->ofp, "%-15s%s", "Name", "Value");
22027   else
22028     print (vam->ofp, "The macro table is empty...");
22029
22030   for (i = 0; i < vec_len (sort_me); i++)
22031     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22032   return 0;
22033 }
22034
22035 static int
22036 dump_node_table (vat_main_t * vam)
22037 {
22038   int i, j;
22039   vlib_node_t *node, *next_node;
22040
22041   if (vec_len (vam->graph_nodes) == 0)
22042     {
22043       print (vam->ofp, "Node table empty, issue get_node_graph...");
22044       return 0;
22045     }
22046
22047   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22048     {
22049       node = vam->graph_nodes[0][i];
22050       print (vam->ofp, "[%d] %s", i, node->name);
22051       for (j = 0; j < vec_len (node->next_nodes); j++)
22052         {
22053           if (node->next_nodes[j] != ~0)
22054             {
22055               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22056               print (vam->ofp, "  [%d] %s", j, next_node->name);
22057             }
22058         }
22059     }
22060   return 0;
22061 }
22062
22063 static int
22064 value_sort_cmp (void *a1, void *a2)
22065 {
22066   name_sort_t *n1 = a1;
22067   name_sort_t *n2 = a2;
22068
22069   if (n1->value < n2->value)
22070     return -1;
22071   if (n1->value > n2->value)
22072     return 1;
22073   return 0;
22074 }
22075
22076
22077 static int
22078 dump_msg_api_table (vat_main_t * vam)
22079 {
22080   api_main_t *am = &api_main;
22081   name_sort_t *nses = 0, *ns;
22082   hash_pair_t *hp;
22083   int i;
22084
22085   /* *INDENT-OFF* */
22086   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22087   ({
22088     vec_add2 (nses, ns, 1);
22089     ns->name = (u8 *)(hp->key);
22090     ns->value = (u32) hp->value[0];
22091   }));
22092   /* *INDENT-ON* */
22093
22094   vec_sort_with_function (nses, value_sort_cmp);
22095
22096   for (i = 0; i < vec_len (nses); i++)
22097     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22098   vec_free (nses);
22099   return 0;
22100 }
22101
22102 static int
22103 get_msg_id (vat_main_t * vam)
22104 {
22105   u8 *name_and_crc;
22106   u32 message_index;
22107
22108   if (unformat (vam->input, "%s", &name_and_crc))
22109     {
22110       message_index = vl_msg_api_get_msg_index (name_and_crc);
22111       if (message_index == ~0)
22112         {
22113           print (vam->ofp, " '%s' not found", name_and_crc);
22114           return 0;
22115         }
22116       print (vam->ofp, " '%s' has message index %d",
22117              name_and_crc, message_index);
22118       return 0;
22119     }
22120   errmsg ("name_and_crc required...");
22121   return 0;
22122 }
22123
22124 static int
22125 search_node_table (vat_main_t * vam)
22126 {
22127   unformat_input_t *line_input = vam->input;
22128   u8 *node_to_find;
22129   int j;
22130   vlib_node_t *node, *next_node;
22131   uword *p;
22132
22133   if (vam->graph_node_index_by_name == 0)
22134     {
22135       print (vam->ofp, "Node table empty, issue get_node_graph...");
22136       return 0;
22137     }
22138
22139   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22140     {
22141       if (unformat (line_input, "%s", &node_to_find))
22142         {
22143           vec_add1 (node_to_find, 0);
22144           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22145           if (p == 0)
22146             {
22147               print (vam->ofp, "%s not found...", node_to_find);
22148               goto out;
22149             }
22150           node = vam->graph_nodes[0][p[0]];
22151           print (vam->ofp, "[%d] %s", p[0], node->name);
22152           for (j = 0; j < vec_len (node->next_nodes); j++)
22153             {
22154               if (node->next_nodes[j] != ~0)
22155                 {
22156                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22157                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22158                 }
22159             }
22160         }
22161
22162       else
22163         {
22164           clib_warning ("parse error '%U'", format_unformat_error,
22165                         line_input);
22166           return -99;
22167         }
22168
22169     out:
22170       vec_free (node_to_find);
22171
22172     }
22173
22174   return 0;
22175 }
22176
22177
22178 static int
22179 script (vat_main_t * vam)
22180 {
22181 #if (VPP_API_TEST_BUILTIN==0)
22182   u8 *s = 0;
22183   char *save_current_file;
22184   unformat_input_t save_input;
22185   jmp_buf save_jump_buf;
22186   u32 save_line_number;
22187
22188   FILE *new_fp, *save_ifp;
22189
22190   if (unformat (vam->input, "%s", &s))
22191     {
22192       new_fp = fopen ((char *) s, "r");
22193       if (new_fp == 0)
22194         {
22195           errmsg ("Couldn't open script file %s", s);
22196           vec_free (s);
22197           return -99;
22198         }
22199     }
22200   else
22201     {
22202       errmsg ("Missing script name");
22203       return -99;
22204     }
22205
22206   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22207   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22208   save_ifp = vam->ifp;
22209   save_line_number = vam->input_line_number;
22210   save_current_file = (char *) vam->current_file;
22211
22212   vam->input_line_number = 0;
22213   vam->ifp = new_fp;
22214   vam->current_file = s;
22215   do_one_file (vam);
22216
22217   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22218   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22219   vam->ifp = save_ifp;
22220   vam->input_line_number = save_line_number;
22221   vam->current_file = (u8 *) save_current_file;
22222   vec_free (s);
22223
22224   return 0;
22225 #else
22226   clib_warning ("use the exec command...");
22227   return -99;
22228 #endif
22229 }
22230
22231 static int
22232 echo (vat_main_t * vam)
22233 {
22234   print (vam->ofp, "%v", vam->input->buffer);
22235   return 0;
22236 }
22237
22238 /* List of API message constructors, CLI names map to api_xxx */
22239 #define foreach_vpe_api_msg                                             \
22240 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22241 _(sw_interface_dump,"")                                                 \
22242 _(sw_interface_set_flags,                                               \
22243   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22244 _(sw_interface_add_del_address,                                         \
22245   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22246 _(sw_interface_set_rx_mode,                                             \
22247   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22248 _(sw_interface_set_rx_placement,                                        \
22249   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22250 _(sw_interface_rx_placement_dump,                                       \
22251   "[<intfc> | sw_if_index <id>]")                                         \
22252 _(sw_interface_set_table,                                               \
22253   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22254 _(sw_interface_set_mpls_enable,                                         \
22255   "<intfc> | sw_if_index [disable | dis]")                              \
22256 _(sw_interface_set_vpath,                                               \
22257   "<intfc> | sw_if_index <id> enable | disable")                        \
22258 _(sw_interface_set_vxlan_bypass,                                        \
22259   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22260 _(sw_interface_set_geneve_bypass,                                       \
22261   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22262 _(sw_interface_set_l2_xconnect,                                         \
22263   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22264   "enable | disable")                                                   \
22265 _(sw_interface_set_l2_bridge,                                           \
22266   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22267   "[shg <split-horizon-group>] [bvi]\n"                                 \
22268   "enable | disable")                                                   \
22269 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22270 _(bridge_domain_add_del,                                                \
22271   "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") \
22272 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22273 _(l2fib_add_del,                                                        \
22274   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22275 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22276 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22277 _(l2_flags,                                                             \
22278   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22279 _(bridge_flags,                                                         \
22280   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22281 _(tap_create_v2,                                                        \
22282   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22283 _(tap_delete_v2,                                                        \
22284   "<vpp-if-name> | sw_if_index <id>")                                   \
22285 _(sw_interface_tap_v2_dump, "")                                         \
22286 _(virtio_pci_create,                                                    \
22287   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22288 _(virtio_pci_delete,                                                    \
22289   "<vpp-if-name> | sw_if_index <id>")                                   \
22290 _(sw_interface_virtio_pci_dump, "")                                     \
22291 _(bond_create,                                                          \
22292   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22293   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22294   "[id <if-id>]")                                                       \
22295 _(bond_delete,                                                          \
22296   "<vpp-if-name> | sw_if_index <id>")                                   \
22297 _(bond_enslave,                                                         \
22298   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22299 _(bond_detach_slave,                                                    \
22300   "sw_if_index <n>")                                                    \
22301 _(sw_interface_bond_dump, "")                                           \
22302 _(sw_interface_slave_dump,                                              \
22303   "<vpp-if-name> | sw_if_index <id>")                                   \
22304 _(ip_table_add_del,                                                     \
22305   "table <n> [ipv6] [add | del]\n")                                     \
22306 _(ip_add_del_route,                                                     \
22307   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22308   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22309   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22310   "[multipath] [count <n>] [del]")                                      \
22311 _(ip_mroute_add_del,                                                    \
22312   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22313   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22314 _(mpls_table_add_del,                                                   \
22315   "table <n> [add | del]\n")                                            \
22316 _(mpls_route_add_del,                                                   \
22317   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22318   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22319   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22320   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22321   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22322   "[count <n>] [del]")                                                  \
22323 _(mpls_ip_bind_unbind,                                                  \
22324   "<label> <addr/len>")                                                 \
22325 _(mpls_tunnel_add_del,                                                  \
22326   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22327   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22328   "[l2-only]  [out-label <n>]")                                         \
22329 _(sr_mpls_policy_add,                                                   \
22330   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22331 _(sr_mpls_policy_del,                                                   \
22332   "bsid <id>")                                                          \
22333 _(bier_table_add_del,                                                   \
22334   "<label> <sub-domain> <set> <bsl> [del]")                             \
22335 _(bier_route_add_del,                                                   \
22336   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22337   "[<intfc> | sw_if_index <id>]"                                        \
22338   "[weight <n>] [del] [multipath]")                                     \
22339 _(proxy_arp_add_del,                                                    \
22340   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22341 _(proxy_arp_intfc_enable_disable,                                       \
22342   "<intfc> | sw_if_index <id> enable | disable")                        \
22343 _(sw_interface_set_unnumbered,                                          \
22344   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22345 _(ip_neighbor_add_del,                                                  \
22346   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22347   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22348 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22349 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22350   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22351   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22352   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22353 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22354 _(reset_fib, "vrf <n> [ipv6]")                                          \
22355 _(dhcp_proxy_config,                                                    \
22356   "svr <v46-address> src <v46-address>\n"                               \
22357    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22358 _(dhcp_proxy_set_vss,                                                   \
22359   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22360 _(dhcp_proxy_dump, "ip6")                                               \
22361 _(dhcp_client_config,                                                   \
22362   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22363 _(set_ip_flow_hash,                                                     \
22364   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22365 _(sw_interface_ip6_enable_disable,                                      \
22366   "<intfc> | sw_if_index <id> enable | disable")                        \
22367 _(ip6nd_proxy_add_del,                                                  \
22368   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22369 _(ip6nd_proxy_dump, "")                                                 \
22370 _(sw_interface_ip6nd_ra_prefix,                                         \
22371   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22372   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22373   "[nolink] [isno]")                                                    \
22374 _(sw_interface_ip6nd_ra_config,                                         \
22375   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22376   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22377   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22378 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22379 _(l2_patch_add_del,                                                     \
22380   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22381   "enable | disable")                                                   \
22382 _(sr_localsid_add_del,                                                  \
22383   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22384   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22385 _(classify_add_del_table,                                               \
22386   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22387   " [del] [del-chain] mask <mask-value>\n"                              \
22388   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22389   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22390 _(classify_add_del_session,                                             \
22391   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22392   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22393   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22394   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22395 _(classify_set_interface_ip_table,                                      \
22396   "<intfc> | sw_if_index <nn> table <nn>")                              \
22397 _(classify_set_interface_l2_tables,                                     \
22398   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22399   "  [other-table <nn>]")                                               \
22400 _(get_node_index, "node <node-name")                                    \
22401 _(add_node_next, "node <node-name> next <next-node-name>")              \
22402 _(l2tpv3_create_tunnel,                                                 \
22403   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22404   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22405   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22406 _(l2tpv3_set_tunnel_cookies,                                            \
22407   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22408   "[new_remote_cookie <nn>]\n")                                         \
22409 _(l2tpv3_interface_enable_disable,                                      \
22410   "<intfc> | sw_if_index <nn> enable | disable")                        \
22411 _(l2tpv3_set_lookup_key,                                                \
22412   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22413 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22414 _(vxlan_offload_rx,                                                     \
22415   "hw { <interface name> | hw_if_index <nn>} "                          \
22416   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22417 _(vxlan_add_del_tunnel,                                                 \
22418   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22419   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22420   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22421 _(geneve_add_del_tunnel,                                                \
22422   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22423   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22424   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22425 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22426 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22427 _(gre_add_del_tunnel,                                                   \
22428   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22429   "[teb | erspan <session-id>] [del]")                                  \
22430 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22431 _(l2_fib_clear_table, "")                                               \
22432 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22433 _(l2_interface_vlan_tag_rewrite,                                        \
22434   "<intfc> | sw_if_index <nn> \n"                                       \
22435   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22436   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22437 _(create_vhost_user_if,                                                 \
22438         "socket <filename> [server] [renumber <dev_instance>] "         \
22439         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22440         "[mac <mac_address>]")                                          \
22441 _(modify_vhost_user_if,                                                 \
22442         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22443         "[server] [renumber <dev_instance>]")                           \
22444 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22445 _(sw_interface_vhost_user_dump, "")                                     \
22446 _(show_version, "")                                                     \
22447 _(show_threads, "")                                                     \
22448 _(vxlan_gpe_add_del_tunnel,                                             \
22449   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22450   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22451   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22452   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22453 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22454 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22455 _(interface_name_renumber,                                              \
22456   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22457 _(input_acl_set_interface,                                              \
22458   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22459   "  [l2-table <nn>] [del]")                                            \
22460 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22461 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22462   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22463 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22464 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22465 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22466 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22467 _(ip_dump, "ipv4 | ipv6")                                               \
22468 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22469 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22470   "  spid_id <n> ")                                                     \
22471 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22472   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22473   "  integ_alg <alg> integ_key <hex>")                                  \
22474 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22475   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22476   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22477   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22478 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22479 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22480   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22481   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22482   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22483   "  [instance <n>]")     \
22484 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22485 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22486   "  <alg> <hex>\n")                                                    \
22487 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22488 _(delete_loopback,"sw_if_index <nn>")                                   \
22489 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22490 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22491 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22492 _(want_interface_events,  "enable|disable")                             \
22493 _(get_first_msg_id, "client <name>")                                    \
22494 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22495 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22496   "fib-id <nn> [ip4][ip6][default]")                                    \
22497 _(get_node_graph, " ")                                                  \
22498 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22499 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22500 _(ioam_disable, "")                                                     \
22501 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22502                             " sw_if_index <sw_if_index> p <priority> "  \
22503                             "w <weight>] [del]")                        \
22504 _(one_add_del_locator, "locator-set <locator_name> "                    \
22505                         "iface <intf> | sw_if_index <sw_if_index> "     \
22506                         "p <priority> w <weight> [del]")                \
22507 _(one_add_del_local_eid,"vni <vni> eid "                                \
22508                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22509                          "locator-set <locator_name> [del]"             \
22510                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22511 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22512 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22513 _(one_enable_disable, "enable|disable")                                 \
22514 _(one_map_register_enable_disable, "enable|disable")                    \
22515 _(one_map_register_fallback_threshold, "<value>")                       \
22516 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22517 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22518                                "[seid <seid>] "                         \
22519                                "rloc <locator> p <prio> "               \
22520                                "w <weight> [rloc <loc> ... ] "          \
22521                                "action <action> [del-all]")             \
22522 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22523                           "<local-eid>")                                \
22524 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22525 _(one_use_petr, "ip-address> | disable")                                \
22526 _(one_map_request_mode, "src-dst|dst-only")                             \
22527 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22528 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22529 _(one_locator_set_dump, "[local | remote]")                             \
22530 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22531 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22532                        "[local] | [remote]")                            \
22533 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22534 _(one_ndp_bd_get, "")                                                   \
22535 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22536 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22537 _(one_l2_arp_bd_get, "")                                                \
22538 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22539 _(one_stats_enable_disable, "enable|disable")                           \
22540 _(show_one_stats_enable_disable, "")                                    \
22541 _(one_eid_table_vni_dump, "")                                           \
22542 _(one_eid_table_map_dump, "l2|l3")                                      \
22543 _(one_map_resolver_dump, "")                                            \
22544 _(one_map_server_dump, "")                                              \
22545 _(one_adjacencies_get, "vni <vni>")                                     \
22546 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22547 _(show_one_rloc_probe_state, "")                                        \
22548 _(show_one_map_register_state, "")                                      \
22549 _(show_one_status, "")                                                  \
22550 _(one_stats_dump, "")                                                   \
22551 _(one_stats_flush, "")                                                  \
22552 _(one_get_map_request_itr_rlocs, "")                                    \
22553 _(one_map_register_set_ttl, "<ttl>")                                    \
22554 _(one_set_transport_protocol, "udp|api")                                \
22555 _(one_get_transport_protocol, "")                                       \
22556 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22557 _(one_show_xtr_mode, "")                                                \
22558 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22559 _(one_show_pitr_mode, "")                                               \
22560 _(one_enable_disable_petr_mode, "enable|disable")                       \
22561 _(one_show_petr_mode, "")                                               \
22562 _(show_one_nsh_mapping, "")                                             \
22563 _(show_one_pitr, "")                                                    \
22564 _(show_one_use_petr, "")                                                \
22565 _(show_one_map_request_mode, "")                                        \
22566 _(show_one_map_register_ttl, "")                                        \
22567 _(show_one_map_register_fallback_threshold, "")                         \
22568 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22569                             " sw_if_index <sw_if_index> p <priority> "  \
22570                             "w <weight>] [del]")                        \
22571 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22572                         "iface <intf> | sw_if_index <sw_if_index> "     \
22573                         "p <priority> w <weight> [del]")                \
22574 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22575                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22576                          "locator-set <locator_name> [del]"             \
22577                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22578 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22579 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22580 _(lisp_enable_disable, "enable|disable")                                \
22581 _(lisp_map_register_enable_disable, "enable|disable")                   \
22582 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22583 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22584                                "[seid <seid>] "                         \
22585                                "rloc <locator> p <prio> "               \
22586                                "w <weight> [rloc <loc> ... ] "          \
22587                                "action <action> [del-all]")             \
22588 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22589                           "<local-eid>")                                \
22590 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22591 _(lisp_use_petr, "<ip-address> | disable")                              \
22592 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22593 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22594 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22595 _(lisp_locator_set_dump, "[local | remote]")                            \
22596 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22597 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22598                        "[local] | [remote]")                            \
22599 _(lisp_eid_table_vni_dump, "")                                          \
22600 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22601 _(lisp_map_resolver_dump, "")                                           \
22602 _(lisp_map_server_dump, "")                                             \
22603 _(lisp_adjacencies_get, "vni <vni>")                                    \
22604 _(gpe_fwd_entry_vnis_get, "")                                           \
22605 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22606 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22607                                 "[table <table-id>]")                   \
22608 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22609 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22610 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22611 _(gpe_get_encap_mode, "")                                               \
22612 _(lisp_gpe_add_del_iface, "up|down")                                    \
22613 _(lisp_gpe_enable_disable, "enable|disable")                            \
22614 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22615   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22616 _(show_lisp_rloc_probe_state, "")                                       \
22617 _(show_lisp_map_register_state, "")                                     \
22618 _(show_lisp_status, "")                                                 \
22619 _(lisp_get_map_request_itr_rlocs, "")                                   \
22620 _(show_lisp_pitr, "")                                                   \
22621 _(show_lisp_use_petr, "")                                               \
22622 _(show_lisp_map_request_mode, "")                                       \
22623 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22624 _(af_packet_delete, "name <host interface name>")                       \
22625 _(af_packet_dump, "")                                                   \
22626 _(policer_add_del, "name <policer name> <params> [del]")                \
22627 _(policer_dump, "[name <policer name>]")                                \
22628 _(policer_classify_set_interface,                                       \
22629   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22630   "  [l2-table <nn>] [del]")                                            \
22631 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22632 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22633     "[master|slave]")                                                   \
22634 _(netmap_delete, "name <interface name>")                               \
22635 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22636 _(mpls_fib_dump, "")                                                    \
22637 _(classify_table_ids, "")                                               \
22638 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22639 _(classify_table_info, "table_id <nn>")                                 \
22640 _(classify_session_dump, "table_id <nn>")                               \
22641 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22642     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22643     "[template_interval <nn>] [udp_checksum]")                          \
22644 _(ipfix_exporter_dump, "")                                              \
22645 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22646 _(ipfix_classify_stream_dump, "")                                       \
22647 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22648 _(ipfix_classify_table_dump, "")                                        \
22649 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22650 _(sw_interface_span_dump, "[l2]")                                           \
22651 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22652 _(pg_create_interface, "if_id <nn>")                                    \
22653 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22654 _(pg_enable_disable, "[stream <id>] disable")                           \
22655 _(ip_source_and_port_range_check_add_del,                               \
22656   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22657 _(ip_source_and_port_range_check_interface_add_del,                     \
22658   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22659   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22660 _(ipsec_gre_add_del_tunnel,                                             \
22661   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22662 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22663 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22664 _(l2_interface_pbb_tag_rewrite,                                         \
22665   "<intfc> | sw_if_index <nn> \n"                                       \
22666   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22667   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22668 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22669 _(flow_classify_set_interface,                                          \
22670   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22671 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22672 _(ip_fib_dump, "")                                                      \
22673 _(ip_mfib_dump, "")                                                     \
22674 _(ip6_fib_dump, "")                                                     \
22675 _(ip6_mfib_dump, "")                                                    \
22676 _(feature_enable_disable, "arc_name <arc_name> "                        \
22677   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22678 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22679 "[disable]")                                                            \
22680 _(l2_xconnect_dump, "")                                                 \
22681 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22682 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22683 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22684 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22685 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22686 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22687 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22688   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22689 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22690 _(sock_init_shm, "size <nnn>")                                          \
22691 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22692 _(dns_enable_disable, "[enable][disable]")                              \
22693 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22694 _(dns_resolve_name, "<hostname>")                                       \
22695 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22696 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22697 _(dns_resolve_name, "<hostname>")                                       \
22698 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22699   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22700 _(session_rules_dump, "")                                               \
22701 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22702 _(output_acl_set_interface,                                             \
22703   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22704   "  [l2-table <nn>] [del]")                                            \
22705 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22706
22707 /* List of command functions, CLI names map directly to functions */
22708 #define foreach_cli_function                                    \
22709 _(comment, "usage: comment <ignore-rest-of-line>")              \
22710 _(dump_interface_table, "usage: dump_interface_table")          \
22711 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22712 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22713 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22714 _(dump_macro_table, "usage: dump_macro_table ")                 \
22715 _(dump_node_table, "usage: dump_node_table")                    \
22716 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22717 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22718 _(echo, "usage: echo <message>")                                \
22719 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22720 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22721 _(help, "usage: help")                                          \
22722 _(q, "usage: quit")                                             \
22723 _(quit, "usage: quit")                                          \
22724 _(search_node_table, "usage: search_node_table <name>...")      \
22725 _(set, "usage: set <variable-name> <value>")                    \
22726 _(script, "usage: script <file-name>")                          \
22727 _(statseg, "usage: statseg");                                   \
22728 _(unset, "usage: unset <variable-name>")
22729
22730 #define _(N,n)                                  \
22731     static void vl_api_##n##_t_handler_uni      \
22732     (vl_api_##n##_t * mp)                       \
22733     {                                           \
22734         vat_main_t * vam = &vat_main;           \
22735         if (vam->json_output) {                 \
22736             vl_api_##n##_t_handler_json(mp);    \
22737         } else {                                \
22738             vl_api_##n##_t_handler(mp);         \
22739         }                                       \
22740     }
22741 foreach_vpe_api_reply_msg;
22742 #if VPP_API_TEST_BUILTIN == 0
22743 foreach_standalone_reply_msg;
22744 #endif
22745 #undef _
22746
22747 void
22748 vat_api_hookup (vat_main_t * vam)
22749 {
22750 #define _(N,n)                                                  \
22751     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22752                            vl_api_##n##_t_handler_uni,          \
22753                            vl_noop_handler,                     \
22754                            vl_api_##n##_t_endian,               \
22755                            vl_api_##n##_t_print,                \
22756                            sizeof(vl_api_##n##_t), 1);
22757   foreach_vpe_api_reply_msg;
22758 #if VPP_API_TEST_BUILTIN == 0
22759   foreach_standalone_reply_msg;
22760 #endif
22761 #undef _
22762
22763 #if (VPP_API_TEST_BUILTIN==0)
22764   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22765
22766   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22767
22768   vam->function_by_name = hash_create_string (0, sizeof (uword));
22769
22770   vam->help_by_name = hash_create_string (0, sizeof (uword));
22771 #endif
22772
22773   /* API messages we can send */
22774 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22775   foreach_vpe_api_msg;
22776 #undef _
22777
22778   /* Help strings */
22779 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22780   foreach_vpe_api_msg;
22781 #undef _
22782
22783   /* CLI functions */
22784 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22785   foreach_cli_function;
22786 #undef _
22787
22788   /* Help strings */
22789 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22790   foreach_cli_function;
22791 #undef _
22792 }
22793
22794 #if VPP_API_TEST_BUILTIN
22795 static clib_error_t *
22796 vat_api_hookup_shim (vlib_main_t * vm)
22797 {
22798   vat_api_hookup (&vat_main);
22799   return 0;
22800 }
22801
22802 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22803 #endif
22804
22805 /*
22806  * fd.io coding-style-patch-verification: ON
22807  *
22808  * Local Variables:
22809  * eval: (c-set-style "gnu")
22810  * End:
22811  */