build: add -Wall and -fno-common, fix reported issues
[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 __clib_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 __clib_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 #if (VPP_API_TEST_BUILTIN==0)
566
567 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
568 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
569 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
570 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
571
572 uword
573 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
574 {
575   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
576   mfib_itf_attribute_t attr;
577
578   old = *iflags;
579   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
580   {
581     if (unformat (input, mfib_itf_flag_long_names[attr]))
582       *iflags |= (1 << attr);
583   }
584   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
585   {
586     if (unformat (input, mfib_itf_flag_names[attr]))
587       *iflags |= (1 << attr);
588   }
589
590   return (old == *iflags ? 0 : 1);
591 }
592
593 uword
594 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
595 {
596   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
597   mfib_entry_attribute_t attr;
598
599   old = *eflags;
600   FOR_EACH_MFIB_ATTRIBUTE (attr)
601   {
602     if (unformat (input, mfib_flag_long_names[attr]))
603       *eflags |= (1 << attr);
604   }
605   FOR_EACH_MFIB_ATTRIBUTE (attr)
606   {
607     if (unformat (input, mfib_flag_names[attr]))
608       *eflags |= (1 << attr);
609   }
610
611   return (old == *eflags ? 0 : 1);
612 }
613
614 u8 *
615 format_ip4_address (u8 * s, va_list * args)
616 {
617   u8 *a = va_arg (*args, u8 *);
618   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
619 }
620
621 u8 *
622 format_ip6_address (u8 * s, va_list * args)
623 {
624   ip6_address_t *a = va_arg (*args, ip6_address_t *);
625   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
626
627   i_max_n_zero = ARRAY_LEN (a->as_u16);
628   max_n_zeros = 0;
629   i_first_zero = i_max_n_zero;
630   n_zeros = 0;
631   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
632     {
633       u32 is_zero = a->as_u16[i] == 0;
634       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
635         {
636           i_first_zero = i;
637           n_zeros = 0;
638         }
639       n_zeros += is_zero;
640       if ((!is_zero && n_zeros > max_n_zeros)
641           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
642         {
643           i_max_n_zero = i_first_zero;
644           max_n_zeros = n_zeros;
645           i_first_zero = ARRAY_LEN (a->as_u16);
646           n_zeros = 0;
647         }
648     }
649
650   last_double_colon = 0;
651   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
652     {
653       if (i == i_max_n_zero && max_n_zeros > 1)
654         {
655           s = format (s, "::");
656           i += max_n_zeros - 1;
657           last_double_colon = 1;
658         }
659       else
660         {
661           s = format (s, "%s%x",
662                       (last_double_colon || i == 0) ? "" : ":",
663                       clib_net_to_host_u16 (a->as_u16[i]));
664           last_double_colon = 0;
665         }
666     }
667
668   return s;
669 }
670
671 /* Format an IP46 address. */
672 u8 *
673 format_ip46_address (u8 * s, va_list * args)
674 {
675   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
676   ip46_type_t type = va_arg (*args, ip46_type_t);
677   int is_ip4 = 1;
678
679   switch (type)
680     {
681     case IP46_TYPE_ANY:
682       is_ip4 = ip46_address_is_ip4 (ip46);
683       break;
684     case IP46_TYPE_IP4:
685       is_ip4 = 1;
686       break;
687     case IP46_TYPE_IP6:
688       is_ip4 = 0;
689       break;
690     }
691
692   return is_ip4 ?
693     format (s, "%U", format_ip4_address, &ip46->ip4) :
694     format (s, "%U", format_ip6_address, &ip46->ip6);
695 }
696
697 u8 *
698 format_ethernet_address (u8 * s, va_list * args)
699 {
700   u8 *a = va_arg (*args, u8 *);
701
702   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
703                  a[0], a[1], a[2], a[3], a[4], a[5]);
704 }
705 #endif
706
707 static void
708 increment_v4_address (ip4_address_t * a)
709 {
710   u32 v;
711
712   v = ntohl (a->as_u32) + 1;
713   a->as_u32 = ntohl (v);
714 }
715
716 static void
717 increment_vl_v4_address (vl_api_ip4_address_t * a)
718 {
719   u32 v;
720
721   v = *(u32 *) a;
722   v = ntohl (v);
723   v++;
724   v = ntohl (v);
725   clib_memcpy (a, &v, sizeof (v));
726 }
727
728 static void
729 increment_vl_address (vl_api_address_t * a)
730 {
731   if (ADDRESS_IP4 == a->af)
732     increment_vl_v4_address (&a->un.ip4);
733 }
734
735 static void
736 increment_v6_address (ip6_address_t * a)
737 {
738   u64 v0, v1;
739
740   v0 = clib_net_to_host_u64 (a->as_u64[0]);
741   v1 = clib_net_to_host_u64 (a->as_u64[1]);
742
743   v1 += 1;
744   if (v1 == 0)
745     v0 += 1;
746   a->as_u64[0] = clib_net_to_host_u64 (v0);
747   a->as_u64[1] = clib_net_to_host_u64 (v1);
748 }
749
750 static void
751 increment_mac_address (u8 * mac)
752 {
753   u64 tmp = *((u64 *) mac);
754   tmp = clib_net_to_host_u64 (tmp);
755   tmp += 1 << 16;               /* skip unused (least significant) octets */
756   tmp = clib_host_to_net_u64 (tmp);
757
758   clib_memcpy (mac, &tmp, 6);
759 }
760
761 static void vl_api_create_loopback_reply_t_handler
762   (vl_api_create_loopback_reply_t * mp)
763 {
764   vat_main_t *vam = &vat_main;
765   i32 retval = ntohl (mp->retval);
766
767   vam->retval = retval;
768   vam->regenerate_interface_table = 1;
769   vam->sw_if_index = ntohl (mp->sw_if_index);
770   vam->result_ready = 1;
771 }
772
773 static void vl_api_create_loopback_reply_t_handler_json
774   (vl_api_create_loopback_reply_t * mp)
775 {
776   vat_main_t *vam = &vat_main;
777   vat_json_node_t node;
778
779   vat_json_init_object (&node);
780   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
781   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
782
783   vat_json_print (vam->ofp, &node);
784   vat_json_free (&node);
785   vam->retval = ntohl (mp->retval);
786   vam->result_ready = 1;
787 }
788
789 static void vl_api_create_loopback_instance_reply_t_handler
790   (vl_api_create_loopback_instance_reply_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   i32 retval = ntohl (mp->retval);
794
795   vam->retval = retval;
796   vam->regenerate_interface_table = 1;
797   vam->sw_if_index = ntohl (mp->sw_if_index);
798   vam->result_ready = 1;
799 }
800
801 static void vl_api_create_loopback_instance_reply_t_handler_json
802   (vl_api_create_loopback_instance_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   vat_json_node_t node;
806
807   vat_json_init_object (&node);
808   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
809   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
810
811   vat_json_print (vam->ofp, &node);
812   vat_json_free (&node);
813   vam->retval = ntohl (mp->retval);
814   vam->result_ready = 1;
815 }
816
817 static void vl_api_af_packet_create_reply_t_handler
818   (vl_api_af_packet_create_reply_t * mp)
819 {
820   vat_main_t *vam = &vat_main;
821   i32 retval = ntohl (mp->retval);
822
823   vam->retval = retval;
824   vam->regenerate_interface_table = 1;
825   vam->sw_if_index = ntohl (mp->sw_if_index);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_af_packet_create_reply_t_handler_json
830   (vl_api_af_packet_create_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   vat_json_node_t node;
834
835   vat_json_init_object (&node);
836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
838
839   vat_json_print (vam->ofp, &node);
840   vat_json_free (&node);
841
842   vam->retval = ntohl (mp->retval);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_vlan_subif_reply_t_handler
847   (vl_api_create_vlan_subif_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   i32 retval = ntohl (mp->retval);
851
852   vam->retval = retval;
853   vam->regenerate_interface_table = 1;
854   vam->sw_if_index = ntohl (mp->sw_if_index);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_vlan_subif_reply_t_handler_json
859   (vl_api_create_vlan_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   vat_json_node_t node;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
867
868   vat_json_print (vam->ofp, &node);
869   vat_json_free (&node);
870
871   vam->retval = ntohl (mp->retval);
872   vam->result_ready = 1;
873 }
874
875 static void vl_api_create_subif_reply_t_handler
876   (vl_api_create_subif_reply_t * mp)
877 {
878   vat_main_t *vam = &vat_main;
879   i32 retval = ntohl (mp->retval);
880
881   vam->retval = retval;
882   vam->regenerate_interface_table = 1;
883   vam->sw_if_index = ntohl (mp->sw_if_index);
884   vam->result_ready = 1;
885 }
886
887 static void vl_api_create_subif_reply_t_handler_json
888   (vl_api_create_subif_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   vat_json_node_t node;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
896
897   vat_json_print (vam->ofp, &node);
898   vat_json_free (&node);
899
900   vam->retval = ntohl (mp->retval);
901   vam->result_ready = 1;
902 }
903
904 static void vl_api_interface_name_renumber_reply_t_handler
905   (vl_api_interface_name_renumber_reply_t * mp)
906 {
907   vat_main_t *vam = &vat_main;
908   i32 retval = ntohl (mp->retval);
909
910   vam->retval = retval;
911   vam->regenerate_interface_table = 1;
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_interface_name_renumber_reply_t_handler_json
916   (vl_api_interface_name_renumber_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   vat_json_node_t node;
920
921   vat_json_init_object (&node);
922   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
923
924   vat_json_print (vam->ofp, &node);
925   vat_json_free (&node);
926
927   vam->retval = ntohl (mp->retval);
928   vam->result_ready = 1;
929 }
930
931 /*
932  * Special-case: build the interface table, maintain
933  * the next loopback sw_if_index vbl.
934  */
935 static void vl_api_sw_interface_details_t_handler
936   (vl_api_sw_interface_details_t * mp)
937 {
938   vat_main_t *vam = &vat_main;
939   u8 *s = format (0, "%s%c", mp->interface_name, 0);
940
941   hash_set_mem (vam->sw_if_index_by_interface_name, s,
942                 ntohl (mp->sw_if_index));
943
944   /* In sub interface case, fill the sub interface table entry */
945   if (mp->sw_if_index != mp->sup_sw_if_index)
946     {
947       sw_interface_subif_t *sub = NULL;
948
949       vec_add2 (vam->sw_if_subif_table, sub, 1);
950
951       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
952       strncpy ((char *) sub->interface_name, (char *) s,
953                vec_len (sub->interface_name));
954       sub->sw_if_index = ntohl (mp->sw_if_index);
955       sub->sub_id = ntohl (mp->sub_id);
956
957       sub->sub_dot1ad = mp->sub_dot1ad;
958       sub->sub_number_of_tags = mp->sub_number_of_tags;
959       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
960       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
961       sub->sub_exact_match = mp->sub_exact_match;
962       sub->sub_default = mp->sub_default;
963       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
964       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
965
966       /* vlan tag rewrite */
967       sub->vtr_op = ntohl (mp->vtr_op);
968       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
969       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
970       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
971     }
972 }
973
974 static void vl_api_sw_interface_details_t_handler_json
975   (vl_api_sw_interface_details_t * mp)
976 {
977   vat_main_t *vam = &vat_main;
978   vat_json_node_t *node = NULL;
979
980   if (VAT_JSON_ARRAY != vam->json_tree.type)
981     {
982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
983       vat_json_init_array (&vam->json_tree);
984     }
985   node = vat_json_array_add (&vam->json_tree);
986
987   vat_json_init_object (node);
988   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
989   vat_json_object_add_uint (node, "sup_sw_if_index",
990                             ntohl (mp->sup_sw_if_index));
991   vat_json_object_add_uint (node, "l2_address_length",
992                             ntohl (mp->l2_address_length));
993   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
994                              sizeof (mp->l2_address));
995   vat_json_object_add_string_copy (node, "interface_name",
996                                    mp->interface_name);
997   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
998   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
999   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1000   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1001   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1002   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1003   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1004   vat_json_object_add_uint (node, "sub_number_of_tags",
1005                             mp->sub_number_of_tags);
1006   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1007                             ntohs (mp->sub_outer_vlan_id));
1008   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1009                             ntohs (mp->sub_inner_vlan_id));
1010   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1011   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1012   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1013                             mp->sub_outer_vlan_id_any);
1014   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1015                             mp->sub_inner_vlan_id_any);
1016   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1017   vat_json_object_add_uint (node, "vtr_push_dot1q",
1018                             ntohl (mp->vtr_push_dot1q));
1019   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1020   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1021   if (mp->sub_dot1ah)
1022     {
1023       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1024                                        format (0, "%U",
1025                                                format_ethernet_address,
1026                                                &mp->b_dmac));
1027       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1028                                        format (0, "%U",
1029                                                format_ethernet_address,
1030                                                &mp->b_smac));
1031       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1032       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1033     }
1034 }
1035
1036 #if VPP_API_TEST_BUILTIN == 0
1037 static void vl_api_sw_interface_event_t_handler
1038   (vl_api_sw_interface_event_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   if (vam->interface_event_display)
1042     errmsg ("interface flags: sw_if_index %d %s %s",
1043             ntohl (mp->sw_if_index),
1044             mp->admin_up_down ? "admin-up" : "admin-down",
1045             mp->link_up_down ? "link-up" : "link-down");
1046 }
1047 #endif
1048
1049 __clib_unused static void
1050 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1051 {
1052   /* JSON output not supported */
1053 }
1054
1055 static void
1056 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1057 {
1058   vat_main_t *vam = &vat_main;
1059   i32 retval = ntohl (mp->retval);
1060
1061   vam->retval = retval;
1062   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1063   vam->result_ready = 1;
1064 }
1065
1066 static void
1067 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1068 {
1069   vat_main_t *vam = &vat_main;
1070   vat_json_node_t node;
1071   api_main_t *am = &api_main;
1072   void *oldheap;
1073   u8 *reply;
1074
1075   vat_json_init_object (&node);
1076   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1077   vat_json_object_add_uint (&node, "reply_in_shmem",
1078                             ntohl (mp->reply_in_shmem));
1079   /* Toss the shared-memory original... */
1080   pthread_mutex_lock (&am->vlib_rp->mutex);
1081   oldheap = svm_push_data_heap (am->vlib_rp);
1082
1083   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1084   vec_free (reply);
1085
1086   svm_pop_heap (oldheap);
1087   pthread_mutex_unlock (&am->vlib_rp->mutex);
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void
1097 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101   u32 length = vl_api_string_len (&mp->reply);
1102
1103   vec_reset_length (vam->cmd_reply);
1104
1105   vam->retval = retval;
1106   if (retval == 0)
1107     {
1108       vec_validate (vam->cmd_reply, length);
1109       clib_memcpy ((char *) (vam->cmd_reply),
1110                    vl_api_from_api_string (&mp->reply), length);
1111       vam->cmd_reply[length] = 0;
1112     }
1113   vam->result_ready = 1;
1114 }
1115
1116 static void
1117 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1118 {
1119   vat_main_t *vam = &vat_main;
1120   vat_json_node_t node;
1121
1122   vec_reset_length (vam->cmd_reply);
1123
1124   vat_json_init_object (&node);
1125   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1126   vat_json_object_add_string_copy (&node, "reply",
1127                                    vl_api_from_api_string (&mp->reply));
1128
1129   vat_json_print (vam->ofp, &node);
1130   vat_json_free (&node);
1131
1132   vam->retval = ntohl (mp->retval);
1133   vam->result_ready = 1;
1134 }
1135
1136 static void vl_api_classify_add_del_table_reply_t_handler
1137   (vl_api_classify_add_del_table_reply_t * mp)
1138 {
1139   vat_main_t *vam = &vat_main;
1140   i32 retval = ntohl (mp->retval);
1141   if (vam->async_mode)
1142     {
1143       vam->async_errors += (retval < 0);
1144     }
1145   else
1146     {
1147       vam->retval = retval;
1148       if (retval == 0 &&
1149           ((mp->new_table_index != 0xFFFFFFFF) ||
1150            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1151            (mp->match_n_vectors != 0xFFFFFFFF)))
1152         /*
1153          * Note: this is just barely thread-safe, depends on
1154          * the main thread spinning waiting for an answer...
1155          */
1156         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1157                 ntohl (mp->new_table_index),
1158                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1159       vam->result_ready = 1;
1160     }
1161 }
1162
1163 static void vl_api_classify_add_del_table_reply_t_handler_json
1164   (vl_api_classify_add_del_table_reply_t * mp)
1165 {
1166   vat_main_t *vam = &vat_main;
1167   vat_json_node_t node;
1168
1169   vat_json_init_object (&node);
1170   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1171   vat_json_object_add_uint (&node, "new_table_index",
1172                             ntohl (mp->new_table_index));
1173   vat_json_object_add_uint (&node, "skip_n_vectors",
1174                             ntohl (mp->skip_n_vectors));
1175   vat_json_object_add_uint (&node, "match_n_vectors",
1176                             ntohl (mp->match_n_vectors));
1177
1178   vat_json_print (vam->ofp, &node);
1179   vat_json_free (&node);
1180
1181   vam->retval = ntohl (mp->retval);
1182   vam->result_ready = 1;
1183 }
1184
1185 static void vl_api_get_node_index_reply_t_handler
1186   (vl_api_get_node_index_reply_t * mp)
1187 {
1188   vat_main_t *vam = &vat_main;
1189   i32 retval = ntohl (mp->retval);
1190   if (vam->async_mode)
1191     {
1192       vam->async_errors += (retval < 0);
1193     }
1194   else
1195     {
1196       vam->retval = retval;
1197       if (retval == 0)
1198         errmsg ("node index %d", ntohl (mp->node_index));
1199       vam->result_ready = 1;
1200     }
1201 }
1202
1203 static void vl_api_get_node_index_reply_t_handler_json
1204   (vl_api_get_node_index_reply_t * mp)
1205 {
1206   vat_main_t *vam = &vat_main;
1207   vat_json_node_t node;
1208
1209   vat_json_init_object (&node);
1210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1211   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1212
1213   vat_json_print (vam->ofp, &node);
1214   vat_json_free (&node);
1215
1216   vam->retval = ntohl (mp->retval);
1217   vam->result_ready = 1;
1218 }
1219
1220 static void vl_api_get_next_index_reply_t_handler
1221   (vl_api_get_next_index_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   i32 retval = ntohl (mp->retval);
1225   if (vam->async_mode)
1226     {
1227       vam->async_errors += (retval < 0);
1228     }
1229   else
1230     {
1231       vam->retval = retval;
1232       if (retval == 0)
1233         errmsg ("next node index %d", ntohl (mp->next_index));
1234       vam->result_ready = 1;
1235     }
1236 }
1237
1238 static void vl_api_get_next_index_reply_t_handler_json
1239   (vl_api_get_next_index_reply_t * mp)
1240 {
1241   vat_main_t *vam = &vat_main;
1242   vat_json_node_t node;
1243
1244   vat_json_init_object (&node);
1245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1246   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1247
1248   vat_json_print (vam->ofp, &node);
1249   vat_json_free (&node);
1250
1251   vam->retval = ntohl (mp->retval);
1252   vam->result_ready = 1;
1253 }
1254
1255 static void vl_api_add_node_next_reply_t_handler
1256   (vl_api_add_node_next_reply_t * mp)
1257 {
1258   vat_main_t *vam = &vat_main;
1259   i32 retval = ntohl (mp->retval);
1260   if (vam->async_mode)
1261     {
1262       vam->async_errors += (retval < 0);
1263     }
1264   else
1265     {
1266       vam->retval = retval;
1267       if (retval == 0)
1268         errmsg ("next index %d", ntohl (mp->next_index));
1269       vam->result_ready = 1;
1270     }
1271 }
1272
1273 static void vl_api_add_node_next_reply_t_handler_json
1274   (vl_api_add_node_next_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1282
1283   vat_json_print (vam->ofp, &node);
1284   vat_json_free (&node);
1285
1286   vam->retval = ntohl (mp->retval);
1287   vam->result_ready = 1;
1288 }
1289
1290 static void vl_api_show_version_reply_t_handler
1291   (vl_api_show_version_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   i32 retval = ntohl (mp->retval);
1295
1296   if (retval >= 0)
1297     {
1298       char *s;
1299       char *p = (char *) &mp->program;
1300
1301       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1302       errmsg ("        program: %s\n", s);
1303       free (s);
1304
1305       p +=
1306         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1307       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1308       errmsg ("        version: %s\n", s);
1309       free (s);
1310
1311       p +=
1312         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1313       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1314       errmsg ("     build date: %s\n", s);
1315       free (s);
1316
1317       p +=
1318         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1319       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1320       errmsg ("build directory: %s\n", s);
1321       free (s);
1322     }
1323   vam->retval = retval;
1324   vam->result_ready = 1;
1325 }
1326
1327 static void vl_api_show_version_reply_t_handler_json
1328   (vl_api_show_version_reply_t * mp)
1329 {
1330   vat_main_t *vam = &vat_main;
1331   vat_json_node_t node;
1332
1333   vat_json_init_object (&node);
1334   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1335   char *p = (char *) &mp->program;
1336   vat_json_object_add_string_copy (&node, "program",
1337                                    vl_api_from_api_string ((vl_api_string_t *)
1338                                                            p));
1339   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1340   vat_json_object_add_string_copy (&node, "version",
1341                                    vl_api_from_api_string ((vl_api_string_t *)
1342                                                            p));
1343   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1344   vat_json_object_add_string_copy (&node, "build_date",
1345                                    vl_api_from_api_string ((vl_api_string_t *)
1346                                                            p));
1347   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1348   vat_json_object_add_string_copy (&node, "build_directory",
1349                                    vl_api_from_api_string ((vl_api_string_t *)
1350                                                            p));
1351
1352   vat_json_print (vam->ofp, &node);
1353   vat_json_free (&node);
1354
1355   vam->retval = ntohl (mp->retval);
1356   vam->result_ready = 1;
1357 }
1358
1359 static void vl_api_show_threads_reply_t_handler
1360   (vl_api_show_threads_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   i32 retval = ntohl (mp->retval);
1364   int i, count = 0;
1365
1366   if (retval >= 0)
1367     count = ntohl (mp->count);
1368
1369   for (i = 0; i < count; i++)
1370     print (vam->ofp,
1371            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1372            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1373            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1374            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1375            ntohl (mp->thread_data[i].cpu_socket));
1376
1377   vam->retval = retval;
1378   vam->result_ready = 1;
1379 }
1380
1381 static void vl_api_show_threads_reply_t_handler_json
1382   (vl_api_show_threads_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t node;
1386   vl_api_thread_data_t *td;
1387   i32 retval = ntohl (mp->retval);
1388   int i, count = 0;
1389
1390   if (retval >= 0)
1391     count = ntohl (mp->count);
1392
1393   vat_json_init_object (&node);
1394   vat_json_object_add_int (&node, "retval", retval);
1395   vat_json_object_add_uint (&node, "count", count);
1396
1397   for (i = 0; i < count; i++)
1398     {
1399       td = &mp->thread_data[i];
1400       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1401       vat_json_object_add_string_copy (&node, "name", td->name);
1402       vat_json_object_add_string_copy (&node, "type", td->type);
1403       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1404       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1405       vat_json_object_add_int (&node, "core", ntohl (td->id));
1406       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1407     }
1408
1409   vat_json_print (vam->ofp, &node);
1410   vat_json_free (&node);
1411
1412   vam->retval = retval;
1413   vam->result_ready = 1;
1414 }
1415
1416 static int
1417 api_show_threads (vat_main_t * vam)
1418 {
1419   vl_api_show_threads_t *mp;
1420   int ret;
1421
1422   print (vam->ofp,
1423          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1424          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1425
1426   M (SHOW_THREADS, mp);
1427
1428   S (mp);
1429   W (ret);
1430   return ret;
1431 }
1432
1433 static void
1434 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1435 {
1436   u32 sw_if_index = ntohl (mp->sw_if_index);
1437   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1438           mp->mac_ip ? "mac/ip binding" : "address resolution",
1439           ntohl (mp->pid), format_ip4_address, mp->ip,
1440           format_vl_api_mac_address, &mp->mac, sw_if_index);
1441 }
1442
1443 static void
1444 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1445 {
1446   /* JSON output not supported */
1447 }
1448
1449 static void
1450 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1451 {
1452   u32 sw_if_index = ntohl (mp->sw_if_index);
1453   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1454           mp->mac_ip ? "mac/ip binding" : "address resolution",
1455           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1456           format_vl_api_mac_address, mp->mac, sw_if_index);
1457 }
1458
1459 static void
1460 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1461 {
1462   /* JSON output not supported */
1463 }
1464
1465 static void
1466 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1467 {
1468   u32 n_macs = ntohl (mp->n_macs);
1469   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1470           ntohl (mp->pid), mp->client_index, n_macs);
1471   int i;
1472   for (i = 0; i < n_macs; i++)
1473     {
1474       vl_api_mac_entry_t *mac = &mp->mac[i];
1475       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1476               i + 1, ntohl (mac->sw_if_index),
1477               format_ethernet_address, mac->mac_addr, mac->action);
1478       if (i == 1000)
1479         break;
1480     }
1481 }
1482
1483 static void
1484 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1485 {
1486   /* JSON output not supported */
1487 }
1488
1489 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1490 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1491
1492 /*
1493  * Special-case: build the bridge domain table, maintain
1494  * the next bd id vbl.
1495  */
1496 static void vl_api_bridge_domain_details_t_handler
1497   (vl_api_bridge_domain_details_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1501   int i;
1502
1503   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1504          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1505
1506   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1507          ntohl (mp->bd_id), mp->learn, mp->forward,
1508          mp->flood, ntohl (mp->bvi_sw_if_index),
1509          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1510
1511   if (n_sw_ifs)
1512     {
1513       vl_api_bridge_domain_sw_if_t *sw_ifs;
1514       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1515              "Interface Name");
1516
1517       sw_ifs = mp->sw_if_details;
1518       for (i = 0; i < n_sw_ifs; i++)
1519         {
1520           u8 *sw_if_name = 0;
1521           u32 sw_if_index;
1522           hash_pair_t *p;
1523
1524           sw_if_index = ntohl (sw_ifs->sw_if_index);
1525
1526           /* *INDENT-OFF* */
1527           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1528                              ({
1529                                if ((u32) p->value[0] == sw_if_index)
1530                                  {
1531                                    sw_if_name = (u8 *)(p->key);
1532                                    break;
1533                                  }
1534                              }));
1535           /* *INDENT-ON* */
1536           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1537                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1538                  "sw_if_index not found!");
1539
1540           sw_ifs++;
1541         }
1542     }
1543 }
1544
1545 static void vl_api_bridge_domain_details_t_handler_json
1546   (vl_api_bridge_domain_details_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t *node, *array = NULL;
1550   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1551
1552   if (VAT_JSON_ARRAY != vam->json_tree.type)
1553     {
1554       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1555       vat_json_init_array (&vam->json_tree);
1556     }
1557   node = vat_json_array_add (&vam->json_tree);
1558
1559   vat_json_init_object (node);
1560   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1561   vat_json_object_add_uint (node, "flood", mp->flood);
1562   vat_json_object_add_uint (node, "forward", mp->forward);
1563   vat_json_object_add_uint (node, "learn", mp->learn);
1564   vat_json_object_add_uint (node, "bvi_sw_if_index",
1565                             ntohl (mp->bvi_sw_if_index));
1566   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1567   array = vat_json_object_add (node, "sw_if");
1568   vat_json_init_array (array);
1569
1570
1571
1572   if (n_sw_ifs)
1573     {
1574       vl_api_bridge_domain_sw_if_t *sw_ifs;
1575       int i;
1576
1577       sw_ifs = mp->sw_if_details;
1578       for (i = 0; i < n_sw_ifs; i++)
1579         {
1580           node = vat_json_array_add (array);
1581           vat_json_init_object (node);
1582           vat_json_object_add_uint (node, "sw_if_index",
1583                                     ntohl (sw_ifs->sw_if_index));
1584           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1585           sw_ifs++;
1586         }
1587     }
1588 }
1589
1590 static void vl_api_control_ping_reply_t_handler
1591   (vl_api_control_ping_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->result_ready = 1;
1603     }
1604   if (vam->socket_client_main)
1605     vam->socket_client_main->control_pings_outstanding--;
1606 }
1607
1608 static void vl_api_control_ping_reply_t_handler_json
1609   (vl_api_control_ping_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613
1614   if (VAT_JSON_NONE != vam->json_tree.type)
1615     {
1616       vat_json_print (vam->ofp, &vam->json_tree);
1617       vat_json_free (&vam->json_tree);
1618       vam->json_tree.type = VAT_JSON_NONE;
1619     }
1620   else
1621     {
1622       /* just print [] */
1623       vat_json_init_array (&vam->json_tree);
1624       vat_json_print (vam->ofp, &vam->json_tree);
1625       vam->json_tree.type = VAT_JSON_NONE;
1626     }
1627
1628   vam->retval = retval;
1629   vam->result_ready = 1;
1630 }
1631
1632 static void
1633   vl_api_bridge_domain_set_mac_age_reply_t_handler
1634   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1635 {
1636   vat_main_t *vam = &vat_main;
1637   i32 retval = ntohl (mp->retval);
1638   if (vam->async_mode)
1639     {
1640       vam->async_errors += (retval < 0);
1641     }
1642   else
1643     {
1644       vam->retval = retval;
1645       vam->result_ready = 1;
1646     }
1647 }
1648
1649 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1650   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1651 {
1652   vat_main_t *vam = &vat_main;
1653   vat_json_node_t node;
1654
1655   vat_json_init_object (&node);
1656   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void
1666 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_l2_flags_reply_t_handler_json
1682   (vl_api_l2_flags_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1690                             ntohl (mp->resulting_feature_bitmap));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699 static void vl_api_bridge_flags_reply_t_handler
1700   (vl_api_bridge_flags_reply_t * mp)
1701 {
1702   vat_main_t *vam = &vat_main;
1703   i32 retval = ntohl (mp->retval);
1704   if (vam->async_mode)
1705     {
1706       vam->async_errors += (retval < 0);
1707     }
1708   else
1709     {
1710       vam->retval = retval;
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_bridge_flags_reply_t_handler_json
1716   (vl_api_bridge_flags_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1724                             ntohl (mp->resulting_feature_bitmap));
1725
1726   vat_json_print (vam->ofp, &node);
1727   vat_json_free (&node);
1728
1729   vam->retval = ntohl (mp->retval);
1730   vam->result_ready = 1;
1731 }
1732
1733 static void
1734 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->sw_if_index = ntohl (mp->sw_if_index);
1746       vam->result_ready = 1;
1747     }
1748
1749 }
1750
1751 static void vl_api_tap_create_v2_reply_t_handler_json
1752   (vl_api_tap_create_v2_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1760
1761   vat_json_print (vam->ofp, &node);
1762   vat_json_free (&node);
1763
1764   vam->retval = ntohl (mp->retval);
1765   vam->result_ready = 1;
1766
1767 }
1768
1769 static void
1770 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773   i32 retval = ntohl (mp->retval);
1774   if (vam->async_mode)
1775     {
1776       vam->async_errors += (retval < 0);
1777     }
1778   else
1779     {
1780       vam->retval = retval;
1781       vam->result_ready = 1;
1782     }
1783 }
1784
1785 static void vl_api_tap_delete_v2_reply_t_handler_json
1786   (vl_api_tap_delete_v2_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793
1794   vat_json_print (vam->ofp, &node);
1795   vat_json_free (&node);
1796
1797   vam->retval = ntohl (mp->retval);
1798   vam->result_ready = 1;
1799 }
1800
1801 static void
1802 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1803                                           mp)
1804 {
1805   vat_main_t *vam = &vat_main;
1806   i32 retval = ntohl (mp->retval);
1807   if (vam->async_mode)
1808     {
1809       vam->async_errors += (retval < 0);
1810     }
1811   else
1812     {
1813       vam->retval = retval;
1814       vam->sw_if_index = ntohl (mp->sw_if_index);
1815       vam->result_ready = 1;
1816     }
1817 }
1818
1819 static void vl_api_virtio_pci_create_reply_t_handler_json
1820   (vl_api_virtio_pci_create_reply_t * mp)
1821 {
1822   vat_main_t *vam = &vat_main;
1823   vat_json_node_t node;
1824
1825   vat_json_init_object (&node);
1826   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1827   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1828
1829   vat_json_print (vam->ofp, &node);
1830   vat_json_free (&node);
1831
1832   vam->retval = ntohl (mp->retval);
1833   vam->result_ready = 1;
1834
1835 }
1836
1837 static void
1838 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1839                                           mp)
1840 {
1841   vat_main_t *vam = &vat_main;
1842   i32 retval = ntohl (mp->retval);
1843   if (vam->async_mode)
1844     {
1845       vam->async_errors += (retval < 0);
1846     }
1847   else
1848     {
1849       vam->retval = retval;
1850       vam->result_ready = 1;
1851     }
1852 }
1853
1854 static void vl_api_virtio_pci_delete_reply_t_handler_json
1855   (vl_api_virtio_pci_delete_reply_t * mp)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   vat_json_node_t node;
1859
1860   vat_json_init_object (&node);
1861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1862
1863   vat_json_print (vam->ofp, &node);
1864   vat_json_free (&node);
1865
1866   vam->retval = ntohl (mp->retval);
1867   vam->result_ready = 1;
1868 }
1869
1870 static void
1871 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1872 {
1873   vat_main_t *vam = &vat_main;
1874   i32 retval = ntohl (mp->retval);
1875
1876   if (vam->async_mode)
1877     {
1878       vam->async_errors += (retval < 0);
1879     }
1880   else
1881     {
1882       vam->retval = retval;
1883       vam->sw_if_index = ntohl (mp->sw_if_index);
1884       vam->result_ready = 1;
1885     }
1886 }
1887
1888 static void vl_api_bond_create_reply_t_handler_json
1889   (vl_api_bond_create_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   vat_json_node_t node;
1893
1894   vat_json_init_object (&node);
1895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1896   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1897
1898   vat_json_print (vam->ofp, &node);
1899   vat_json_free (&node);
1900
1901   vam->retval = ntohl (mp->retval);
1902   vam->result_ready = 1;
1903 }
1904
1905 static void
1906 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1907 {
1908   vat_main_t *vam = &vat_main;
1909   i32 retval = ntohl (mp->retval);
1910
1911   if (vam->async_mode)
1912     {
1913       vam->async_errors += (retval < 0);
1914     }
1915   else
1916     {
1917       vam->retval = retval;
1918       vam->result_ready = 1;
1919     }
1920 }
1921
1922 static void vl_api_bond_delete_reply_t_handler_json
1923   (vl_api_bond_delete_reply_t * mp)
1924 {
1925   vat_main_t *vam = &vat_main;
1926   vat_json_node_t node;
1927
1928   vat_json_init_object (&node);
1929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1930
1931   vat_json_print (vam->ofp, &node);
1932   vat_json_free (&node);
1933
1934   vam->retval = ntohl (mp->retval);
1935   vam->result_ready = 1;
1936 }
1937
1938 static void
1939 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_bond_enslave_reply_t_handler_json
1956   (vl_api_bond_enslave_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static void
1972 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1973                                           mp)
1974 {
1975   vat_main_t *vam = &vat_main;
1976   i32 retval = ntohl (mp->retval);
1977
1978   if (vam->async_mode)
1979     {
1980       vam->async_errors += (retval < 0);
1981     }
1982   else
1983     {
1984       vam->retval = retval;
1985       vam->result_ready = 1;
1986     }
1987 }
1988
1989 static void vl_api_bond_detach_slave_reply_t_handler_json
1990   (vl_api_bond_detach_slave_reply_t * mp)
1991 {
1992   vat_main_t *vam = &vat_main;
1993   vat_json_node_t node;
1994
1995   vat_json_init_object (&node);
1996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1997
1998   vat_json_print (vam->ofp, &node);
1999   vat_json_free (&node);
2000
2001   vam->retval = ntohl (mp->retval);
2002   vam->result_ready = 1;
2003 }
2004
2005 static void vl_api_sw_interface_bond_details_t_handler
2006   (vl_api_sw_interface_bond_details_t * mp)
2007 {
2008   vat_main_t *vam = &vat_main;
2009
2010   print (vam->ofp,
2011          "%-16s %-12d %-12U %-13U %-14u %-14u",
2012          mp->interface_name, ntohl (mp->sw_if_index),
2013          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2014          ntohl (mp->active_slaves), ntohl (mp->slaves));
2015 }
2016
2017 static void vl_api_sw_interface_bond_details_t_handler_json
2018   (vl_api_sw_interface_bond_details_t * mp)
2019 {
2020   vat_main_t *vam = &vat_main;
2021   vat_json_node_t *node = NULL;
2022
2023   if (VAT_JSON_ARRAY != vam->json_tree.type)
2024     {
2025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2026       vat_json_init_array (&vam->json_tree);
2027     }
2028   node = vat_json_array_add (&vam->json_tree);
2029
2030   vat_json_init_object (node);
2031   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2032   vat_json_object_add_string_copy (node, "interface_name",
2033                                    mp->interface_name);
2034   vat_json_object_add_uint (node, "mode", mp->mode);
2035   vat_json_object_add_uint (node, "load_balance", mp->lb);
2036   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2037   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2038 }
2039
2040 static int
2041 api_sw_interface_bond_dump (vat_main_t * vam)
2042 {
2043   vl_api_sw_interface_bond_dump_t *mp;
2044   vl_api_control_ping_t *mp_ping;
2045   int ret;
2046
2047   print (vam->ofp,
2048          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2049          "interface name", "sw_if_index", "mode", "load balance",
2050          "active slaves", "slaves");
2051
2052   /* Get list of bond interfaces */
2053   M (SW_INTERFACE_BOND_DUMP, mp);
2054   S (mp);
2055
2056   /* Use a control ping for synchronization */
2057   MPING (CONTROL_PING, mp_ping);
2058   S (mp_ping);
2059
2060   W (ret);
2061   return ret;
2062 }
2063
2064 static void vl_api_sw_interface_slave_details_t_handler
2065   (vl_api_sw_interface_slave_details_t * mp)
2066 {
2067   vat_main_t *vam = &vat_main;
2068
2069   print (vam->ofp,
2070          "%-25s %-12d %-12d %d", mp->interface_name,
2071          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2072 }
2073
2074 static void vl_api_sw_interface_slave_details_t_handler_json
2075   (vl_api_sw_interface_slave_details_t * mp)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   vat_json_node_t *node = NULL;
2079
2080   if (VAT_JSON_ARRAY != vam->json_tree.type)
2081     {
2082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2083       vat_json_init_array (&vam->json_tree);
2084     }
2085   node = vat_json_array_add (&vam->json_tree);
2086
2087   vat_json_init_object (node);
2088   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2089   vat_json_object_add_string_copy (node, "interface_name",
2090                                    mp->interface_name);
2091   vat_json_object_add_uint (node, "passive", mp->is_passive);
2092   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2093 }
2094
2095 static int
2096 api_sw_interface_slave_dump (vat_main_t * vam)
2097 {
2098   unformat_input_t *i = vam->input;
2099   vl_api_sw_interface_slave_dump_t *mp;
2100   vl_api_control_ping_t *mp_ping;
2101   u32 sw_if_index = ~0;
2102   u8 sw_if_index_set = 0;
2103   int ret;
2104
2105   /* Parse args required to build the message */
2106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2107     {
2108       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2109         sw_if_index_set = 1;
2110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2111         sw_if_index_set = 1;
2112       else
2113         break;
2114     }
2115
2116   if (sw_if_index_set == 0)
2117     {
2118       errmsg ("missing vpp interface name. ");
2119       return -99;
2120     }
2121
2122   print (vam->ofp,
2123          "\n%-25s %-12s %-12s %s",
2124          "slave interface name", "sw_if_index", "passive", "long_timeout");
2125
2126   /* Get list of bond interfaces */
2127   M (SW_INTERFACE_SLAVE_DUMP, mp);
2128   mp->sw_if_index = ntohl (sw_if_index);
2129   S (mp);
2130
2131   /* Use a control ping for synchronization */
2132   MPING (CONTROL_PING, mp_ping);
2133   S (mp_ping);
2134
2135   W (ret);
2136   return ret;
2137 }
2138
2139 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2140   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2141 {
2142   vat_main_t *vam = &vat_main;
2143   i32 retval = ntohl (mp->retval);
2144   if (vam->async_mode)
2145     {
2146       vam->async_errors += (retval < 0);
2147     }
2148   else
2149     {
2150       vam->retval = retval;
2151       vam->sw_if_index = ntohl (mp->sw_if_index);
2152       vam->result_ready = 1;
2153     }
2154   vam->regenerate_interface_table = 1;
2155 }
2156
2157 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2158   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2159 {
2160   vat_main_t *vam = &vat_main;
2161   vat_json_node_t node;
2162
2163   vat_json_init_object (&node);
2164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2165   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2166                             ntohl (mp->sw_if_index));
2167
2168   vat_json_print (vam->ofp, &node);
2169   vat_json_free (&node);
2170
2171   vam->retval = ntohl (mp->retval);
2172   vam->result_ready = 1;
2173 }
2174
2175 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2176   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2177 {
2178   vat_main_t *vam = &vat_main;
2179   i32 retval = ntohl (mp->retval);
2180   if (vam->async_mode)
2181     {
2182       vam->async_errors += (retval < 0);
2183     }
2184   else
2185     {
2186       vam->retval = retval;
2187       vam->sw_if_index = ntohl (mp->sw_if_index);
2188       vam->result_ready = 1;
2189     }
2190 }
2191
2192 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2193   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2194 {
2195   vat_main_t *vam = &vat_main;
2196   vat_json_node_t node;
2197
2198   vat_json_init_object (&node);
2199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2200   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2201
2202   vat_json_print (vam->ofp, &node);
2203   vat_json_free (&node);
2204
2205   vam->retval = ntohl (mp->retval);
2206   vam->result_ready = 1;
2207 }
2208
2209 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2210   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   i32 retval = ntohl (mp->retval);
2214   if (vam->async_mode)
2215     {
2216       vam->async_errors += (retval < 0);
2217     }
2218   else
2219     {
2220       vam->retval = retval;
2221       vam->result_ready = 1;
2222     }
2223 }
2224
2225 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2226   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2227 {
2228   vat_main_t *vam = &vat_main;
2229   vat_json_node_t node;
2230
2231   vat_json_init_object (&node);
2232   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2233   vat_json_object_add_uint (&node, "fwd_entry_index",
2234                             clib_net_to_host_u32 (mp->fwd_entry_index));
2235
2236   vat_json_print (vam->ofp, &node);
2237   vat_json_free (&node);
2238
2239   vam->retval = ntohl (mp->retval);
2240   vam->result_ready = 1;
2241 }
2242
2243 u8 *
2244 format_lisp_transport_protocol (u8 * s, va_list * args)
2245 {
2246   u32 proto = va_arg (*args, u32);
2247
2248   switch (proto)
2249     {
2250     case 1:
2251       return format (s, "udp");
2252     case 2:
2253       return format (s, "api");
2254     default:
2255       return 0;
2256     }
2257   return 0;
2258 }
2259
2260 static void vl_api_one_get_transport_protocol_reply_t_handler
2261   (vl_api_one_get_transport_protocol_reply_t * mp)
2262 {
2263   vat_main_t *vam = &vat_main;
2264   i32 retval = ntohl (mp->retval);
2265   if (vam->async_mode)
2266     {
2267       vam->async_errors += (retval < 0);
2268     }
2269   else
2270     {
2271       u32 proto = mp->protocol;
2272       print (vam->ofp, "Transport protocol: %U",
2273              format_lisp_transport_protocol, proto);
2274       vam->retval = retval;
2275       vam->result_ready = 1;
2276     }
2277 }
2278
2279 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2280   (vl_api_one_get_transport_protocol_reply_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t node;
2284   u8 *s;
2285
2286   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2287   vec_add1 (s, 0);
2288
2289   vat_json_init_object (&node);
2290   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2291   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2292
2293   vec_free (s);
2294   vat_json_print (vam->ofp, &node);
2295   vat_json_free (&node);
2296
2297   vam->retval = ntohl (mp->retval);
2298   vam->result_ready = 1;
2299 }
2300
2301 static void vl_api_one_add_del_locator_set_reply_t_handler
2302   (vl_api_one_add_del_locator_set_reply_t * mp)
2303 {
2304   vat_main_t *vam = &vat_main;
2305   i32 retval = ntohl (mp->retval);
2306   if (vam->async_mode)
2307     {
2308       vam->async_errors += (retval < 0);
2309     }
2310   else
2311     {
2312       vam->retval = retval;
2313       vam->result_ready = 1;
2314     }
2315 }
2316
2317 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2318   (vl_api_one_add_del_locator_set_reply_t * mp)
2319 {
2320   vat_main_t *vam = &vat_main;
2321   vat_json_node_t node;
2322
2323   vat_json_init_object (&node);
2324   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2325   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2326
2327   vat_json_print (vam->ofp, &node);
2328   vat_json_free (&node);
2329
2330   vam->retval = ntohl (mp->retval);
2331   vam->result_ready = 1;
2332 }
2333
2334 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2335   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2336 {
2337   vat_main_t *vam = &vat_main;
2338   i32 retval = ntohl (mp->retval);
2339   if (vam->async_mode)
2340     {
2341       vam->async_errors += (retval < 0);
2342     }
2343   else
2344     {
2345       vam->retval = retval;
2346       vam->sw_if_index = ntohl (mp->sw_if_index);
2347       vam->result_ready = 1;
2348     }
2349   vam->regenerate_interface_table = 1;
2350 }
2351
2352 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2353   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   vat_json_node_t node;
2357
2358   vat_json_init_object (&node);
2359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2360   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2361
2362   vat_json_print (vam->ofp, &node);
2363   vat_json_free (&node);
2364
2365   vam->retval = ntohl (mp->retval);
2366   vam->result_ready = 1;
2367 }
2368
2369 static void vl_api_vxlan_offload_rx_reply_t_handler
2370   (vl_api_vxlan_offload_rx_reply_t * mp)
2371 {
2372   vat_main_t *vam = &vat_main;
2373   i32 retval = ntohl (mp->retval);
2374   if (vam->async_mode)
2375     {
2376       vam->async_errors += (retval < 0);
2377     }
2378   else
2379     {
2380       vam->retval = retval;
2381       vam->result_ready = 1;
2382     }
2383 }
2384
2385 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2386   (vl_api_vxlan_offload_rx_reply_t * mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   vat_json_node_t node;
2390
2391   vat_json_init_object (&node);
2392   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2393
2394   vat_json_print (vam->ofp, &node);
2395   vat_json_free (&node);
2396
2397   vam->retval = ntohl (mp->retval);
2398   vam->result_ready = 1;
2399 }
2400
2401 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2402   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2403 {
2404   vat_main_t *vam = &vat_main;
2405   i32 retval = ntohl (mp->retval);
2406   if (vam->async_mode)
2407     {
2408       vam->async_errors += (retval < 0);
2409     }
2410   else
2411     {
2412       vam->retval = retval;
2413       vam->sw_if_index = ntohl (mp->sw_if_index);
2414       vam->result_ready = 1;
2415     }
2416 }
2417
2418 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2419   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422   vat_json_node_t node;
2423
2424   vat_json_init_object (&node);
2425   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2426   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2427
2428   vat_json_print (vam->ofp, &node);
2429   vat_json_free (&node);
2430
2431   vam->retval = ntohl (mp->retval);
2432   vam->result_ready = 1;
2433 }
2434
2435 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2436   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   i32 retval = ntohl (mp->retval);
2440   if (vam->async_mode)
2441     {
2442       vam->async_errors += (retval < 0);
2443     }
2444   else
2445     {
2446       vam->retval = retval;
2447       vam->sw_if_index = ntohl (mp->sw_if_index);
2448       vam->result_ready = 1;
2449     }
2450   vam->regenerate_interface_table = 1;
2451 }
2452
2453 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2454   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2455 {
2456   vat_main_t *vam = &vat_main;
2457   vat_json_node_t node;
2458
2459   vat_json_init_object (&node);
2460   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2461   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2462
2463   vat_json_print (vam->ofp, &node);
2464   vat_json_free (&node);
2465
2466   vam->retval = ntohl (mp->retval);
2467   vam->result_ready = 1;
2468 }
2469
2470 static void vl_api_gre_tunnel_add_del_reply_t_handler
2471   (vl_api_gre_tunnel_add_del_reply_t * mp)
2472 {
2473   vat_main_t *vam = &vat_main;
2474   i32 retval = ntohl (mp->retval);
2475   if (vam->async_mode)
2476     {
2477       vam->async_errors += (retval < 0);
2478     }
2479   else
2480     {
2481       vam->retval = retval;
2482       vam->sw_if_index = ntohl (mp->sw_if_index);
2483       vam->result_ready = 1;
2484     }
2485 }
2486
2487 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2488   (vl_api_gre_tunnel_add_del_reply_t * mp)
2489 {
2490   vat_main_t *vam = &vat_main;
2491   vat_json_node_t node;
2492
2493   vat_json_init_object (&node);
2494   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2495   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2496
2497   vat_json_print (vam->ofp, &node);
2498   vat_json_free (&node);
2499
2500   vam->retval = ntohl (mp->retval);
2501   vam->result_ready = 1;
2502 }
2503
2504 static void vl_api_create_vhost_user_if_reply_t_handler
2505   (vl_api_create_vhost_user_if_reply_t * mp)
2506 {
2507   vat_main_t *vam = &vat_main;
2508   i32 retval = ntohl (mp->retval);
2509   if (vam->async_mode)
2510     {
2511       vam->async_errors += (retval < 0);
2512     }
2513   else
2514     {
2515       vam->retval = retval;
2516       vam->sw_if_index = ntohl (mp->sw_if_index);
2517       vam->result_ready = 1;
2518     }
2519   vam->regenerate_interface_table = 1;
2520 }
2521
2522 static void vl_api_create_vhost_user_if_reply_t_handler_json
2523   (vl_api_create_vhost_user_if_reply_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   vat_json_node_t node;
2527
2528   vat_json_init_object (&node);
2529   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2530   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2531
2532   vat_json_print (vam->ofp, &node);
2533   vat_json_free (&node);
2534
2535   vam->retval = ntohl (mp->retval);
2536   vam->result_ready = 1;
2537 }
2538
2539 static void vl_api_dns_resolve_name_reply_t_handler
2540   (vl_api_dns_resolve_name_reply_t * mp)
2541 {
2542   vat_main_t *vam = &vat_main;
2543   i32 retval = ntohl (mp->retval);
2544   if (vam->async_mode)
2545     {
2546       vam->async_errors += (retval < 0);
2547     }
2548   else
2549     {
2550       vam->retval = retval;
2551       vam->result_ready = 1;
2552
2553       if (retval == 0)
2554         {
2555           if (mp->ip4_set)
2556             clib_warning ("ip4 address %U", format_ip4_address,
2557                           (ip4_address_t *) mp->ip4_address);
2558           if (mp->ip6_set)
2559             clib_warning ("ip6 address %U", format_ip6_address,
2560                           (ip6_address_t *) mp->ip6_address);
2561         }
2562       else
2563         clib_warning ("retval %d", retval);
2564     }
2565 }
2566
2567 static void vl_api_dns_resolve_name_reply_t_handler_json
2568   (vl_api_dns_resolve_name_reply_t * mp)
2569 {
2570   clib_warning ("not implemented");
2571 }
2572
2573 static void vl_api_dns_resolve_ip_reply_t_handler
2574   (vl_api_dns_resolve_ip_reply_t * mp)
2575 {
2576   vat_main_t *vam = &vat_main;
2577   i32 retval = ntohl (mp->retval);
2578   if (vam->async_mode)
2579     {
2580       vam->async_errors += (retval < 0);
2581     }
2582   else
2583     {
2584       vam->retval = retval;
2585       vam->result_ready = 1;
2586
2587       if (retval == 0)
2588         {
2589           clib_warning ("canonical name %s", mp->name);
2590         }
2591       else
2592         clib_warning ("retval %d", retval);
2593     }
2594 }
2595
2596 static void vl_api_dns_resolve_ip_reply_t_handler_json
2597   (vl_api_dns_resolve_ip_reply_t * mp)
2598 {
2599   clib_warning ("not implemented");
2600 }
2601
2602
2603 static void vl_api_ip_address_details_t_handler
2604   (vl_api_ip_address_details_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607   static ip_address_details_t empty_ip_address_details = { {0} };
2608   ip_address_details_t *address = NULL;
2609   ip_details_t *current_ip_details = NULL;
2610   ip_details_t *details = NULL;
2611
2612   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2613
2614   if (!details || vam->current_sw_if_index >= vec_len (details)
2615       || !details[vam->current_sw_if_index].present)
2616     {
2617       errmsg ("ip address details arrived but not stored");
2618       errmsg ("ip_dump should be called first");
2619       return;
2620     }
2621
2622   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2623
2624 #define addresses (current_ip_details->addr)
2625
2626   vec_validate_init_empty (addresses, vec_len (addresses),
2627                            empty_ip_address_details);
2628
2629   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2630
2631   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2632   address->prefix_length = mp->prefix_length;
2633 #undef addresses
2634 }
2635
2636 static void vl_api_ip_address_details_t_handler_json
2637   (vl_api_ip_address_details_t * mp)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   vat_json_node_t *node = NULL;
2641   struct in6_addr ip6;
2642   struct in_addr ip4;
2643
2644   if (VAT_JSON_ARRAY != vam->json_tree.type)
2645     {
2646       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2647       vat_json_init_array (&vam->json_tree);
2648     }
2649   node = vat_json_array_add (&vam->json_tree);
2650
2651   vat_json_init_object (node);
2652   if (vam->is_ipv6)
2653     {
2654       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2655       vat_json_object_add_ip6 (node, "ip", ip6);
2656     }
2657   else
2658     {
2659       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2660       vat_json_object_add_ip4 (node, "ip", ip4);
2661     }
2662   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2663 }
2664
2665 static void
2666 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2667 {
2668   vat_main_t *vam = &vat_main;
2669   static ip_details_t empty_ip_details = { 0 };
2670   ip_details_t *ip = NULL;
2671   u32 sw_if_index = ~0;
2672
2673   sw_if_index = ntohl (mp->sw_if_index);
2674
2675   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2676                            sw_if_index, empty_ip_details);
2677
2678   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2679                          sw_if_index);
2680
2681   ip->present = 1;
2682 }
2683
2684 static void
2685 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688
2689   if (VAT_JSON_ARRAY != vam->json_tree.type)
2690     {
2691       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2692       vat_json_init_array (&vam->json_tree);
2693     }
2694   vat_json_array_add_uint (&vam->json_tree,
2695                            clib_net_to_host_u32 (mp->sw_if_index));
2696 }
2697
2698 static void
2699 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2700 {
2701   u8 *s, i;
2702
2703   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2704               "host_mac %U router_addr %U",
2705               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2706               mp->lease.hostname,
2707               format_ip4_address, mp->lease.host_address,
2708               format_ethernet_address, mp->lease.host_mac,
2709               format_ip4_address, mp->lease.router_address);
2710
2711   for (i = 0; i < mp->lease.count; i++)
2712     s =
2713       format (s, " domain_server_addr %U", format_ip4_address,
2714               mp->lease.domain_server[i].address);
2715
2716   errmsg ((char *) s);
2717   vec_free (s);
2718 }
2719
2720 static void vl_api_dhcp_compl_event_t_handler_json
2721   (vl_api_dhcp_compl_event_t * mp)
2722 {
2723   /* JSON output not supported */
2724 }
2725
2726 static void vl_api_get_first_msg_id_reply_t_handler
2727   (vl_api_get_first_msg_id_reply_t * mp)
2728 {
2729   vat_main_t *vam = &vat_main;
2730   i32 retval = ntohl (mp->retval);
2731
2732   if (vam->async_mode)
2733     {
2734       vam->async_errors += (retval < 0);
2735     }
2736   else
2737     {
2738       vam->retval = retval;
2739       vam->result_ready = 1;
2740     }
2741   if (retval >= 0)
2742     {
2743       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2744     }
2745 }
2746
2747 static void vl_api_get_first_msg_id_reply_t_handler_json
2748   (vl_api_get_first_msg_id_reply_t * mp)
2749 {
2750   vat_main_t *vam = &vat_main;
2751   vat_json_node_t node;
2752
2753   vat_json_init_object (&node);
2754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2755   vat_json_object_add_uint (&node, "first_msg_id",
2756                             (uint) ntohs (mp->first_msg_id));
2757
2758   vat_json_print (vam->ofp, &node);
2759   vat_json_free (&node);
2760
2761   vam->retval = ntohl (mp->retval);
2762   vam->result_ready = 1;
2763 }
2764
2765 static void vl_api_get_node_graph_reply_t_handler
2766   (vl_api_get_node_graph_reply_t * mp)
2767 {
2768   vat_main_t *vam = &vat_main;
2769   api_main_t *am = &api_main;
2770   i32 retval = ntohl (mp->retval);
2771   u8 *pvt_copy, *reply;
2772   void *oldheap;
2773   vlib_node_t *node;
2774   int i;
2775
2776   if (vam->async_mode)
2777     {
2778       vam->async_errors += (retval < 0);
2779     }
2780   else
2781     {
2782       vam->retval = retval;
2783       vam->result_ready = 1;
2784     }
2785
2786   /* "Should never happen..." */
2787   if (retval != 0)
2788     return;
2789
2790   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2791   pvt_copy = vec_dup (reply);
2792
2793   /* Toss the shared-memory original... */
2794   pthread_mutex_lock (&am->vlib_rp->mutex);
2795   oldheap = svm_push_data_heap (am->vlib_rp);
2796
2797   vec_free (reply);
2798
2799   svm_pop_heap (oldheap);
2800   pthread_mutex_unlock (&am->vlib_rp->mutex);
2801
2802   if (vam->graph_nodes)
2803     {
2804       hash_free (vam->graph_node_index_by_name);
2805
2806       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2807         {
2808           node = vam->graph_nodes[0][i];
2809           vec_free (node->name);
2810           vec_free (node->next_nodes);
2811           vec_free (node);
2812         }
2813       vec_free (vam->graph_nodes[0]);
2814       vec_free (vam->graph_nodes);
2815     }
2816
2817   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2818   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2819   vec_free (pvt_copy);
2820
2821   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2822     {
2823       node = vam->graph_nodes[0][i];
2824       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2825     }
2826 }
2827
2828 static void vl_api_get_node_graph_reply_t_handler_json
2829   (vl_api_get_node_graph_reply_t * mp)
2830 {
2831   vat_main_t *vam = &vat_main;
2832   api_main_t *am = &api_main;
2833   void *oldheap;
2834   vat_json_node_t node;
2835   u8 *reply;
2836
2837   /* $$$$ make this real? */
2838   vat_json_init_object (&node);
2839   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2840   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2841
2842   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2843
2844   /* Toss the shared-memory original... */
2845   pthread_mutex_lock (&am->vlib_rp->mutex);
2846   oldheap = svm_push_data_heap (am->vlib_rp);
2847
2848   vec_free (reply);
2849
2850   svm_pop_heap (oldheap);
2851   pthread_mutex_unlock (&am->vlib_rp->mutex);
2852
2853   vat_json_print (vam->ofp, &node);
2854   vat_json_free (&node);
2855
2856   vam->retval = ntohl (mp->retval);
2857   vam->result_ready = 1;
2858 }
2859
2860 static void
2861 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2862 {
2863   vat_main_t *vam = &vat_main;
2864   u8 *s = 0;
2865
2866   if (mp->local)
2867     {
2868       s = format (s, "%=16d%=16d%=16d",
2869                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2870     }
2871   else
2872     {
2873       s = format (s, "%=16U%=16d%=16d",
2874                   mp->is_ipv6 ? format_ip6_address :
2875                   format_ip4_address,
2876                   mp->ip_address, mp->priority, mp->weight);
2877     }
2878
2879   print (vam->ofp, "%v", s);
2880   vec_free (s);
2881 }
2882
2883 static void
2884 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2885 {
2886   vat_main_t *vam = &vat_main;
2887   vat_json_node_t *node = NULL;
2888   struct in6_addr ip6;
2889   struct in_addr ip4;
2890
2891   if (VAT_JSON_ARRAY != vam->json_tree.type)
2892     {
2893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2894       vat_json_init_array (&vam->json_tree);
2895     }
2896   node = vat_json_array_add (&vam->json_tree);
2897   vat_json_init_object (node);
2898
2899   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2900   vat_json_object_add_uint (node, "priority", mp->priority);
2901   vat_json_object_add_uint (node, "weight", mp->weight);
2902
2903   if (mp->local)
2904     vat_json_object_add_uint (node, "sw_if_index",
2905                               clib_net_to_host_u32 (mp->sw_if_index));
2906   else
2907     {
2908       if (mp->is_ipv6)
2909         {
2910           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2911           vat_json_object_add_ip6 (node, "address", ip6);
2912         }
2913       else
2914         {
2915           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2916           vat_json_object_add_ip4 (node, "address", ip4);
2917         }
2918     }
2919 }
2920
2921 static void
2922 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2923                                           mp)
2924 {
2925   vat_main_t *vam = &vat_main;
2926   u8 *ls_name = 0;
2927
2928   ls_name = format (0, "%s", mp->ls_name);
2929
2930   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2931          ls_name);
2932   vec_free (ls_name);
2933 }
2934
2935 static void
2936   vl_api_one_locator_set_details_t_handler_json
2937   (vl_api_one_locator_set_details_t * mp)
2938 {
2939   vat_main_t *vam = &vat_main;
2940   vat_json_node_t *node = 0;
2941   u8 *ls_name = 0;
2942
2943   ls_name = format (0, "%s", mp->ls_name);
2944   vec_add1 (ls_name, 0);
2945
2946   if (VAT_JSON_ARRAY != vam->json_tree.type)
2947     {
2948       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2949       vat_json_init_array (&vam->json_tree);
2950     }
2951   node = vat_json_array_add (&vam->json_tree);
2952
2953   vat_json_init_object (node);
2954   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2955   vat_json_object_add_uint (node, "ls_index",
2956                             clib_net_to_host_u32 (mp->ls_index));
2957   vec_free (ls_name);
2958 }
2959
2960 typedef struct
2961 {
2962   u32 spi;
2963   u8 si;
2964 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2965
2966 uword
2967 unformat_nsh_address (unformat_input_t * input, va_list * args)
2968 {
2969   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2970   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2971 }
2972
2973 u8 *
2974 format_nsh_address_vat (u8 * s, va_list * args)
2975 {
2976   nsh_t *a = va_arg (*args, nsh_t *);
2977   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2978 }
2979
2980 static u8 *
2981 format_lisp_flat_eid (u8 * s, va_list * args)
2982 {
2983   u32 type = va_arg (*args, u32);
2984   u8 *eid = va_arg (*args, u8 *);
2985   u32 eid_len = va_arg (*args, u32);
2986
2987   switch (type)
2988     {
2989     case 0:
2990       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2991     case 1:
2992       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2993     case 2:
2994       return format (s, "%U", format_ethernet_address, eid);
2995     case 3:
2996       return format (s, "%U", format_nsh_address_vat, eid);
2997     }
2998   return 0;
2999 }
3000
3001 static u8 *
3002 format_lisp_eid_vat (u8 * s, va_list * args)
3003 {
3004   u32 type = va_arg (*args, u32);
3005   u8 *eid = va_arg (*args, u8 *);
3006   u32 eid_len = va_arg (*args, u32);
3007   u8 *seid = va_arg (*args, u8 *);
3008   u32 seid_len = va_arg (*args, u32);
3009   u32 is_src_dst = va_arg (*args, u32);
3010
3011   if (is_src_dst)
3012     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3013
3014   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3015
3016   return s;
3017 }
3018
3019 static void
3020 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   u8 *s = 0, *eid = 0;
3024
3025   if (~0 == mp->locator_set_index)
3026     s = format (0, "action: %d", mp->action);
3027   else
3028     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3029
3030   eid = format (0, "%U", format_lisp_eid_vat,
3031                 mp->eid_type,
3032                 mp->eid,
3033                 mp->eid_prefix_len,
3034                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3035   vec_add1 (eid, 0);
3036
3037   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3038          clib_net_to_host_u32 (mp->vni),
3039          eid,
3040          mp->is_local ? "local" : "remote",
3041          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3042          clib_net_to_host_u16 (mp->key_id), mp->key);
3043
3044   vec_free (s);
3045   vec_free (eid);
3046 }
3047
3048 static void
3049 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3050                                              * mp)
3051 {
3052   vat_main_t *vam = &vat_main;
3053   vat_json_node_t *node = 0;
3054   u8 *eid = 0;
3055
3056   if (VAT_JSON_ARRAY != vam->json_tree.type)
3057     {
3058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3059       vat_json_init_array (&vam->json_tree);
3060     }
3061   node = vat_json_array_add (&vam->json_tree);
3062
3063   vat_json_init_object (node);
3064   if (~0 == mp->locator_set_index)
3065     vat_json_object_add_uint (node, "action", mp->action);
3066   else
3067     vat_json_object_add_uint (node, "locator_set_index",
3068                               clib_net_to_host_u32 (mp->locator_set_index));
3069
3070   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3071   if (mp->eid_type == 3)
3072     {
3073       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3074       vat_json_init_object (nsh_json);
3075       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3076       vat_json_object_add_uint (nsh_json, "spi",
3077                                 clib_net_to_host_u32 (nsh->spi));
3078       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3079     }
3080   else
3081     {
3082       eid = format (0, "%U", format_lisp_eid_vat,
3083                     mp->eid_type,
3084                     mp->eid,
3085                     mp->eid_prefix_len,
3086                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3087       vec_add1 (eid, 0);
3088       vat_json_object_add_string_copy (node, "eid", eid);
3089       vec_free (eid);
3090     }
3091   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3092   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3093   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3094
3095   if (mp->key_id)
3096     {
3097       vat_json_object_add_uint (node, "key_id",
3098                                 clib_net_to_host_u16 (mp->key_id));
3099       vat_json_object_add_string_copy (node, "key", mp->key);
3100     }
3101 }
3102
3103 static void
3104 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3105 {
3106   vat_main_t *vam = &vat_main;
3107   u8 *seid = 0, *deid = 0;
3108   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3109
3110   deid = format (0, "%U", format_lisp_eid_vat,
3111                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3112
3113   seid = format (0, "%U", format_lisp_eid_vat,
3114                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3115
3116   vec_add1 (deid, 0);
3117   vec_add1 (seid, 0);
3118
3119   if (mp->is_ip4)
3120     format_ip_address_fcn = format_ip4_address;
3121   else
3122     format_ip_address_fcn = format_ip6_address;
3123
3124
3125   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3126          clib_net_to_host_u32 (mp->vni),
3127          seid, deid,
3128          format_ip_address_fcn, mp->lloc,
3129          format_ip_address_fcn, mp->rloc,
3130          clib_net_to_host_u32 (mp->pkt_count),
3131          clib_net_to_host_u32 (mp->bytes));
3132
3133   vec_free (deid);
3134   vec_free (seid);
3135 }
3136
3137 static void
3138 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3139 {
3140   struct in6_addr ip6;
3141   struct in_addr ip4;
3142   vat_main_t *vam = &vat_main;
3143   vat_json_node_t *node = 0;
3144   u8 *deid = 0, *seid = 0;
3145
3146   if (VAT_JSON_ARRAY != vam->json_tree.type)
3147     {
3148       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3149       vat_json_init_array (&vam->json_tree);
3150     }
3151   node = vat_json_array_add (&vam->json_tree);
3152
3153   vat_json_init_object (node);
3154   deid = format (0, "%U", format_lisp_eid_vat,
3155                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3156
3157   seid = format (0, "%U", format_lisp_eid_vat,
3158                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3159
3160   vec_add1 (deid, 0);
3161   vec_add1 (seid, 0);
3162
3163   vat_json_object_add_string_copy (node, "seid", seid);
3164   vat_json_object_add_string_copy (node, "deid", deid);
3165   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3166
3167   if (mp->is_ip4)
3168     {
3169       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3170       vat_json_object_add_ip4 (node, "lloc", ip4);
3171       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3172       vat_json_object_add_ip4 (node, "rloc", ip4);
3173     }
3174   else
3175     {
3176       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3177       vat_json_object_add_ip6 (node, "lloc", ip6);
3178       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3179       vat_json_object_add_ip6 (node, "rloc", ip6);
3180     }
3181   vat_json_object_add_uint (node, "pkt_count",
3182                             clib_net_to_host_u32 (mp->pkt_count));
3183   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3184
3185   vec_free (deid);
3186   vec_free (seid);
3187 }
3188
3189 static void
3190   vl_api_one_eid_table_map_details_t_handler
3191   (vl_api_one_eid_table_map_details_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194
3195   u8 *line = format (0, "%=10d%=10d",
3196                      clib_net_to_host_u32 (mp->vni),
3197                      clib_net_to_host_u32 (mp->dp_table));
3198   print (vam->ofp, "%v", line);
3199   vec_free (line);
3200 }
3201
3202 static void
3203   vl_api_one_eid_table_map_details_t_handler_json
3204   (vl_api_one_eid_table_map_details_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t *node = NULL;
3208
3209   if (VAT_JSON_ARRAY != vam->json_tree.type)
3210     {
3211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3212       vat_json_init_array (&vam->json_tree);
3213     }
3214   node = vat_json_array_add (&vam->json_tree);
3215   vat_json_init_object (node);
3216   vat_json_object_add_uint (node, "dp_table",
3217                             clib_net_to_host_u32 (mp->dp_table));
3218   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3219 }
3220
3221 static void
3222   vl_api_one_eid_table_vni_details_t_handler
3223   (vl_api_one_eid_table_vni_details_t * mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226
3227   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3228   print (vam->ofp, "%v", line);
3229   vec_free (line);
3230 }
3231
3232 static void
3233   vl_api_one_eid_table_vni_details_t_handler_json
3234   (vl_api_one_eid_table_vni_details_t * mp)
3235 {
3236   vat_main_t *vam = &vat_main;
3237   vat_json_node_t *node = NULL;
3238
3239   if (VAT_JSON_ARRAY != vam->json_tree.type)
3240     {
3241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3242       vat_json_init_array (&vam->json_tree);
3243     }
3244   node = vat_json_array_add (&vam->json_tree);
3245   vat_json_init_object (node);
3246   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3247 }
3248
3249 static void
3250   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3251   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254   int retval = clib_net_to_host_u32 (mp->retval);
3255
3256   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3257   print (vam->ofp, "fallback threshold value: %d", mp->value);
3258
3259   vam->retval = retval;
3260   vam->result_ready = 1;
3261 }
3262
3263 static void
3264   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3265   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268   vat_json_node_t _node, *node = &_node;
3269   int retval = clib_net_to_host_u32 (mp->retval);
3270
3271   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3272   vat_json_init_object (node);
3273   vat_json_object_add_uint (node, "value", mp->value);
3274
3275   vat_json_print (vam->ofp, node);
3276   vat_json_free (node);
3277
3278   vam->retval = retval;
3279   vam->result_ready = 1;
3280 }
3281
3282 static void
3283   vl_api_show_one_map_register_state_reply_t_handler
3284   (vl_api_show_one_map_register_state_reply_t * mp)
3285 {
3286   vat_main_t *vam = &vat_main;
3287   int retval = clib_net_to_host_u32 (mp->retval);
3288
3289   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3290
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293 }
3294
3295 static void
3296   vl_api_show_one_map_register_state_reply_t_handler_json
3297   (vl_api_show_one_map_register_state_reply_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300   vat_json_node_t _node, *node = &_node;
3301   int retval = clib_net_to_host_u32 (mp->retval);
3302
3303   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3304
3305   vat_json_init_object (node);
3306   vat_json_object_add_string_copy (node, "state", s);
3307
3308   vat_json_print (vam->ofp, node);
3309   vat_json_free (node);
3310
3311   vam->retval = retval;
3312   vam->result_ready = 1;
3313   vec_free (s);
3314 }
3315
3316 static void
3317   vl_api_show_one_rloc_probe_state_reply_t_handler
3318   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3319 {
3320   vat_main_t *vam = &vat_main;
3321   int retval = clib_net_to_host_u32 (mp->retval);
3322
3323   if (retval)
3324     goto end;
3325
3326   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3327 end:
3328   vam->retval = retval;
3329   vam->result_ready = 1;
3330 }
3331
3332 static void
3333   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3334   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3335 {
3336   vat_main_t *vam = &vat_main;
3337   vat_json_node_t _node, *node = &_node;
3338   int retval = clib_net_to_host_u32 (mp->retval);
3339
3340   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3341   vat_json_init_object (node);
3342   vat_json_object_add_string_copy (node, "state", s);
3343
3344   vat_json_print (vam->ofp, node);
3345   vat_json_free (node);
3346
3347   vam->retval = retval;
3348   vam->result_ready = 1;
3349   vec_free (s);
3350 }
3351
3352 static void
3353   vl_api_show_one_stats_enable_disable_reply_t_handler
3354   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   int retval = clib_net_to_host_u32 (mp->retval);
3358
3359   if (retval)
3360     goto end;
3361
3362   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3363 end:
3364   vam->retval = retval;
3365   vam->result_ready = 1;
3366 }
3367
3368 static void
3369   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3370   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373   vat_json_node_t _node, *node = &_node;
3374   int retval = clib_net_to_host_u32 (mp->retval);
3375
3376   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3377   vat_json_init_object (node);
3378   vat_json_object_add_string_copy (node, "state", s);
3379
3380   vat_json_print (vam->ofp, node);
3381   vat_json_free (node);
3382
3383   vam->retval = retval;
3384   vam->result_ready = 1;
3385   vec_free (s);
3386 }
3387
3388 static void
3389 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3390 {
3391   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3392   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3393   e->vni = clib_net_to_host_u32 (e->vni);
3394 }
3395
3396 static void
3397   gpe_fwd_entries_get_reply_t_net_to_host
3398   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3399 {
3400   u32 i;
3401
3402   mp->count = clib_net_to_host_u32 (mp->count);
3403   for (i = 0; i < mp->count; i++)
3404     {
3405       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3406     }
3407 }
3408
3409 static u8 *
3410 format_gpe_encap_mode (u8 * s, va_list * args)
3411 {
3412   u32 mode = va_arg (*args, u32);
3413
3414   switch (mode)
3415     {
3416     case 0:
3417       return format (s, "lisp");
3418     case 1:
3419       return format (s, "vxlan");
3420     }
3421   return 0;
3422 }
3423
3424 static void
3425   vl_api_gpe_get_encap_mode_reply_t_handler
3426   (vl_api_gpe_get_encap_mode_reply_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429
3430   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3431   vam->retval = ntohl (mp->retval);
3432   vam->result_ready = 1;
3433 }
3434
3435 static void
3436   vl_api_gpe_get_encap_mode_reply_t_handler_json
3437   (vl_api_gpe_get_encap_mode_reply_t * mp)
3438 {
3439   vat_main_t *vam = &vat_main;
3440   vat_json_node_t node;
3441
3442   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3443   vec_add1 (encap_mode, 0);
3444
3445   vat_json_init_object (&node);
3446   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3447
3448   vec_free (encap_mode);
3449   vat_json_print (vam->ofp, &node);
3450   vat_json_free (&node);
3451
3452   vam->retval = ntohl (mp->retval);
3453   vam->result_ready = 1;
3454 }
3455
3456 static void
3457   vl_api_gpe_fwd_entry_path_details_t_handler
3458   (vl_api_gpe_fwd_entry_path_details_t * mp)
3459 {
3460   vat_main_t *vam = &vat_main;
3461   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3462
3463   if (mp->lcl_loc.is_ip4)
3464     format_ip_address_fcn = format_ip4_address;
3465   else
3466     format_ip_address_fcn = format_ip6_address;
3467
3468   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3469          format_ip_address_fcn, &mp->lcl_loc,
3470          format_ip_address_fcn, &mp->rmt_loc);
3471 }
3472
3473 static void
3474 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3475 {
3476   struct in6_addr ip6;
3477   struct in_addr ip4;
3478
3479   if (loc->is_ip4)
3480     {
3481       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3482       vat_json_object_add_ip4 (n, "address", ip4);
3483     }
3484   else
3485     {
3486       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3487       vat_json_object_add_ip6 (n, "address", ip6);
3488     }
3489   vat_json_object_add_uint (n, "weight", loc->weight);
3490 }
3491
3492 static void
3493   vl_api_gpe_fwd_entry_path_details_t_handler_json
3494   (vl_api_gpe_fwd_entry_path_details_t * mp)
3495 {
3496   vat_main_t *vam = &vat_main;
3497   vat_json_node_t *node = NULL;
3498   vat_json_node_t *loc_node;
3499
3500   if (VAT_JSON_ARRAY != vam->json_tree.type)
3501     {
3502       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3503       vat_json_init_array (&vam->json_tree);
3504     }
3505   node = vat_json_array_add (&vam->json_tree);
3506   vat_json_init_object (node);
3507
3508   loc_node = vat_json_object_add (node, "local_locator");
3509   vat_json_init_object (loc_node);
3510   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3511
3512   loc_node = vat_json_object_add (node, "remote_locator");
3513   vat_json_init_object (loc_node);
3514   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3515 }
3516
3517 static void
3518   vl_api_gpe_fwd_entries_get_reply_t_handler
3519   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   u32 i;
3523   int retval = clib_net_to_host_u32 (mp->retval);
3524   vl_api_gpe_fwd_entry_t *e;
3525
3526   if (retval)
3527     goto end;
3528
3529   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3530
3531   for (i = 0; i < mp->count; i++)
3532     {
3533       e = &mp->entries[i];
3534       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3535              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3536              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3537     }
3538
3539 end:
3540   vam->retval = retval;
3541   vam->result_ready = 1;
3542 }
3543
3544 static void
3545   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3546   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3547 {
3548   u8 *s = 0;
3549   vat_main_t *vam = &vat_main;
3550   vat_json_node_t *e = 0, root;
3551   u32 i;
3552   int retval = clib_net_to_host_u32 (mp->retval);
3553   vl_api_gpe_fwd_entry_t *fwd;
3554
3555   if (retval)
3556     goto end;
3557
3558   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3559   vat_json_init_array (&root);
3560
3561   for (i = 0; i < mp->count; i++)
3562     {
3563       e = vat_json_array_add (&root);
3564       fwd = &mp->entries[i];
3565
3566       vat_json_init_object (e);
3567       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3568       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3569       vat_json_object_add_int (e, "vni", fwd->vni);
3570       vat_json_object_add_int (e, "action", fwd->action);
3571
3572       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3573                   fwd->leid_prefix_len);
3574       vec_add1 (s, 0);
3575       vat_json_object_add_string_copy (e, "leid", s);
3576       vec_free (s);
3577
3578       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3579                   fwd->reid_prefix_len);
3580       vec_add1 (s, 0);
3581       vat_json_object_add_string_copy (e, "reid", s);
3582       vec_free (s);
3583     }
3584
3585   vat_json_print (vam->ofp, &root);
3586   vat_json_free (&root);
3587
3588 end:
3589   vam->retval = retval;
3590   vam->result_ready = 1;
3591 }
3592
3593 static void
3594   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3595   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3596 {
3597   vat_main_t *vam = &vat_main;
3598   u32 i, n;
3599   int retval = clib_net_to_host_u32 (mp->retval);
3600   vl_api_gpe_native_fwd_rpath_t *r;
3601
3602   if (retval)
3603     goto end;
3604
3605   n = clib_net_to_host_u32 (mp->count);
3606
3607   for (i = 0; i < n; i++)
3608     {
3609       r = &mp->entries[i];
3610       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3611              clib_net_to_host_u32 (r->fib_index),
3612              clib_net_to_host_u32 (r->nh_sw_if_index),
3613              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3614     }
3615
3616 end:
3617   vam->retval = retval;
3618   vam->result_ready = 1;
3619 }
3620
3621 static void
3622   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3623   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3624 {
3625   vat_main_t *vam = &vat_main;
3626   vat_json_node_t root, *e;
3627   u32 i, n;
3628   int retval = clib_net_to_host_u32 (mp->retval);
3629   vl_api_gpe_native_fwd_rpath_t *r;
3630   u8 *s;
3631
3632   if (retval)
3633     goto end;
3634
3635   n = clib_net_to_host_u32 (mp->count);
3636   vat_json_init_array (&root);
3637
3638   for (i = 0; i < n; i++)
3639     {
3640       e = vat_json_array_add (&root);
3641       vat_json_init_object (e);
3642       r = &mp->entries[i];
3643       s =
3644         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3645                 r->nh_addr);
3646       vec_add1 (s, 0);
3647       vat_json_object_add_string_copy (e, "ip4", s);
3648       vec_free (s);
3649
3650       vat_json_object_add_uint (e, "fib_index",
3651                                 clib_net_to_host_u32 (r->fib_index));
3652       vat_json_object_add_uint (e, "nh_sw_if_index",
3653                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3654     }
3655
3656   vat_json_print (vam->ofp, &root);
3657   vat_json_free (&root);
3658
3659 end:
3660   vam->retval = retval;
3661   vam->result_ready = 1;
3662 }
3663
3664 static void
3665   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3666   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3667 {
3668   vat_main_t *vam = &vat_main;
3669   u32 i, n;
3670   int retval = clib_net_to_host_u32 (mp->retval);
3671
3672   if (retval)
3673     goto end;
3674
3675   n = clib_net_to_host_u32 (mp->count);
3676
3677   for (i = 0; i < n; i++)
3678     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3679
3680 end:
3681   vam->retval = retval;
3682   vam->result_ready = 1;
3683 }
3684
3685 static void
3686   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3687   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3688 {
3689   vat_main_t *vam = &vat_main;
3690   vat_json_node_t root;
3691   u32 i, n;
3692   int retval = clib_net_to_host_u32 (mp->retval);
3693
3694   if (retval)
3695     goto end;
3696
3697   n = clib_net_to_host_u32 (mp->count);
3698   vat_json_init_array (&root);
3699
3700   for (i = 0; i < n; i++)
3701     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3702
3703   vat_json_print (vam->ofp, &root);
3704   vat_json_free (&root);
3705
3706 end:
3707   vam->retval = retval;
3708   vam->result_ready = 1;
3709 }
3710
3711 static void
3712   vl_api_one_ndp_entries_get_reply_t_handler
3713   (vl_api_one_ndp_entries_get_reply_t * mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716   u32 i, n;
3717   int retval = clib_net_to_host_u32 (mp->retval);
3718
3719   if (retval)
3720     goto end;
3721
3722   n = clib_net_to_host_u32 (mp->count);
3723
3724   for (i = 0; i < n; i++)
3725     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3726            format_ethernet_address, mp->entries[i].mac);
3727
3728 end:
3729   vam->retval = retval;
3730   vam->result_ready = 1;
3731 }
3732
3733 static void
3734   vl_api_one_ndp_entries_get_reply_t_handler_json
3735   (vl_api_one_ndp_entries_get_reply_t * mp)
3736 {
3737   u8 *s = 0;
3738   vat_main_t *vam = &vat_main;
3739   vat_json_node_t *e = 0, root;
3740   u32 i, n;
3741   int retval = clib_net_to_host_u32 (mp->retval);
3742   vl_api_one_ndp_entry_t *arp_entry;
3743
3744   if (retval)
3745     goto end;
3746
3747   n = clib_net_to_host_u32 (mp->count);
3748   vat_json_init_array (&root);
3749
3750   for (i = 0; i < n; i++)
3751     {
3752       e = vat_json_array_add (&root);
3753       arp_entry = &mp->entries[i];
3754
3755       vat_json_init_object (e);
3756       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3757       vec_add1 (s, 0);
3758
3759       vat_json_object_add_string_copy (e, "mac", s);
3760       vec_free (s);
3761
3762       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3763       vec_add1 (s, 0);
3764       vat_json_object_add_string_copy (e, "ip6", s);
3765       vec_free (s);
3766     }
3767
3768   vat_json_print (vam->ofp, &root);
3769   vat_json_free (&root);
3770
3771 end:
3772   vam->retval = retval;
3773   vam->result_ready = 1;
3774 }
3775
3776 static void
3777   vl_api_one_l2_arp_entries_get_reply_t_handler
3778   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3779 {
3780   vat_main_t *vam = &vat_main;
3781   u32 i, n;
3782   int retval = clib_net_to_host_u32 (mp->retval);
3783
3784   if (retval)
3785     goto end;
3786
3787   n = clib_net_to_host_u32 (mp->count);
3788
3789   for (i = 0; i < n; i++)
3790     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3791            format_ethernet_address, mp->entries[i].mac);
3792
3793 end:
3794   vam->retval = retval;
3795   vam->result_ready = 1;
3796 }
3797
3798 static void
3799   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3800   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3801 {
3802   u8 *s = 0;
3803   vat_main_t *vam = &vat_main;
3804   vat_json_node_t *e = 0, root;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807   vl_api_one_l2_arp_entry_t *arp_entry;
3808
3809   if (retval)
3810     goto end;
3811
3812   n = clib_net_to_host_u32 (mp->count);
3813   vat_json_init_array (&root);
3814
3815   for (i = 0; i < n; i++)
3816     {
3817       e = vat_json_array_add (&root);
3818       arp_entry = &mp->entries[i];
3819
3820       vat_json_init_object (e);
3821       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3822       vec_add1 (s, 0);
3823
3824       vat_json_object_add_string_copy (e, "mac", s);
3825       vec_free (s);
3826
3827       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3828       vec_add1 (s, 0);
3829       vat_json_object_add_string_copy (e, "ip4", s);
3830       vec_free (s);
3831     }
3832
3833   vat_json_print (vam->ofp, &root);
3834   vat_json_free (&root);
3835
3836 end:
3837   vam->retval = retval;
3838   vam->result_ready = 1;
3839 }
3840
3841 static void
3842 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3843 {
3844   vat_main_t *vam = &vat_main;
3845   u32 i, n;
3846   int retval = clib_net_to_host_u32 (mp->retval);
3847
3848   if (retval)
3849     goto end;
3850
3851   n = clib_net_to_host_u32 (mp->count);
3852
3853   for (i = 0; i < n; i++)
3854     {
3855       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3856     }
3857
3858 end:
3859   vam->retval = retval;
3860   vam->result_ready = 1;
3861 }
3862
3863 static void
3864   vl_api_one_ndp_bd_get_reply_t_handler_json
3865   (vl_api_one_ndp_bd_get_reply_t * mp)
3866 {
3867   vat_main_t *vam = &vat_main;
3868   vat_json_node_t root;
3869   u32 i, n;
3870   int retval = clib_net_to_host_u32 (mp->retval);
3871
3872   if (retval)
3873     goto end;
3874
3875   n = clib_net_to_host_u32 (mp->count);
3876   vat_json_init_array (&root);
3877
3878   for (i = 0; i < n; i++)
3879     {
3880       vat_json_array_add_uint (&root,
3881                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3882     }
3883
3884   vat_json_print (vam->ofp, &root);
3885   vat_json_free (&root);
3886
3887 end:
3888   vam->retval = retval;
3889   vam->result_ready = 1;
3890 }
3891
3892 static void
3893   vl_api_one_l2_arp_bd_get_reply_t_handler
3894   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3895 {
3896   vat_main_t *vam = &vat_main;
3897   u32 i, n;
3898   int retval = clib_net_to_host_u32 (mp->retval);
3899
3900   if (retval)
3901     goto end;
3902
3903   n = clib_net_to_host_u32 (mp->count);
3904
3905   for (i = 0; i < n; i++)
3906     {
3907       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3908     }
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3917   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3918 {
3919   vat_main_t *vam = &vat_main;
3920   vat_json_node_t root;
3921   u32 i, n;
3922   int retval = clib_net_to_host_u32 (mp->retval);
3923
3924   if (retval)
3925     goto end;
3926
3927   n = clib_net_to_host_u32 (mp->count);
3928   vat_json_init_array (&root);
3929
3930   for (i = 0; i < n; i++)
3931     {
3932       vat_json_array_add_uint (&root,
3933                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3934     }
3935
3936   vat_json_print (vam->ofp, &root);
3937   vat_json_free (&root);
3938
3939 end:
3940   vam->retval = retval;
3941   vam->result_ready = 1;
3942 }
3943
3944 static void
3945   vl_api_one_adjacencies_get_reply_t_handler
3946   (vl_api_one_adjacencies_get_reply_t * mp)
3947 {
3948   vat_main_t *vam = &vat_main;
3949   u32 i, n;
3950   int retval = clib_net_to_host_u32 (mp->retval);
3951   vl_api_one_adjacency_t *a;
3952
3953   if (retval)
3954     goto end;
3955
3956   n = clib_net_to_host_u32 (mp->count);
3957
3958   for (i = 0; i < n; i++)
3959     {
3960       a = &mp->adjacencies[i];
3961       print (vam->ofp, "%U %40U",
3962              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3963              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3964     }
3965
3966 end:
3967   vam->retval = retval;
3968   vam->result_ready = 1;
3969 }
3970
3971 static void
3972   vl_api_one_adjacencies_get_reply_t_handler_json
3973   (vl_api_one_adjacencies_get_reply_t * mp)
3974 {
3975   u8 *s = 0;
3976   vat_main_t *vam = &vat_main;
3977   vat_json_node_t *e = 0, root;
3978   u32 i, n;
3979   int retval = clib_net_to_host_u32 (mp->retval);
3980   vl_api_one_adjacency_t *a;
3981
3982   if (retval)
3983     goto end;
3984
3985   n = clib_net_to_host_u32 (mp->count);
3986   vat_json_init_array (&root);
3987
3988   for (i = 0; i < n; i++)
3989     {
3990       e = vat_json_array_add (&root);
3991       a = &mp->adjacencies[i];
3992
3993       vat_json_init_object (e);
3994       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3995                   a->leid_prefix_len);
3996       vec_add1 (s, 0);
3997       vat_json_object_add_string_copy (e, "leid", s);
3998       vec_free (s);
3999
4000       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4001                   a->reid_prefix_len);
4002       vec_add1 (s, 0);
4003       vat_json_object_add_string_copy (e, "reid", s);
4004       vec_free (s);
4005     }
4006
4007   vat_json_print (vam->ofp, &root);
4008   vat_json_free (&root);
4009
4010 end:
4011   vam->retval = retval;
4012   vam->result_ready = 1;
4013 }
4014
4015 static void
4016 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * 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_server_details_t_handler_json
4027   (vl_api_one_map_server_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-server", ip6);
4046     }
4047   else
4048     {
4049       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4050       vat_json_object_add_ip4 (node, "map-server", ip4);
4051     }
4052 }
4053
4054 static void
4055 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4056                                            * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059
4060   print (vam->ofp, "%=20U",
4061          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4062          mp->ip_address);
4063 }
4064
4065 static void
4066   vl_api_one_map_resolver_details_t_handler_json
4067   (vl_api_one_map_resolver_details_t * mp)
4068 {
4069   vat_main_t *vam = &vat_main;
4070   vat_json_node_t *node = NULL;
4071   struct in6_addr ip6;
4072   struct in_addr ip4;
4073
4074   if (VAT_JSON_ARRAY != vam->json_tree.type)
4075     {
4076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4077       vat_json_init_array (&vam->json_tree);
4078     }
4079   node = vat_json_array_add (&vam->json_tree);
4080
4081   vat_json_init_object (node);
4082   if (mp->is_ipv6)
4083     {
4084       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4085       vat_json_object_add_ip6 (node, "map resolver", ip6);
4086     }
4087   else
4088     {
4089       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4090       vat_json_object_add_ip4 (node, "map resolver", ip4);
4091     }
4092 }
4093
4094 static void
4095 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4096 {
4097   vat_main_t *vam = &vat_main;
4098   i32 retval = ntohl (mp->retval);
4099
4100   if (0 <= retval)
4101     {
4102       print (vam->ofp, "feature: %s\ngpe: %s",
4103              mp->feature_status ? "enabled" : "disabled",
4104              mp->gpe_status ? "enabled" : "disabled");
4105     }
4106
4107   vam->retval = retval;
4108   vam->result_ready = 1;
4109 }
4110
4111 static void
4112   vl_api_show_one_status_reply_t_handler_json
4113   (vl_api_show_one_status_reply_t * mp)
4114 {
4115   vat_main_t *vam = &vat_main;
4116   vat_json_node_t node;
4117   u8 *gpe_status = NULL;
4118   u8 *feature_status = NULL;
4119
4120   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4121   feature_status = format (0, "%s",
4122                            mp->feature_status ? "enabled" : "disabled");
4123   vec_add1 (gpe_status, 0);
4124   vec_add1 (feature_status, 0);
4125
4126   vat_json_init_object (&node);
4127   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4128   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4129
4130   vec_free (gpe_status);
4131   vec_free (feature_status);
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 void
4141   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4142   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4143 {
4144   vat_main_t *vam = &vat_main;
4145   i32 retval = ntohl (mp->retval);
4146
4147   if (retval >= 0)
4148     {
4149       print (vam->ofp, "%=20s", mp->locator_set_name);
4150     }
4151
4152   vam->retval = retval;
4153   vam->result_ready = 1;
4154 }
4155
4156 static void
4157   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4158   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4159 {
4160   vat_main_t *vam = &vat_main;
4161   vat_json_node_t *node = NULL;
4162
4163   if (VAT_JSON_ARRAY != vam->json_tree.type)
4164     {
4165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4166       vat_json_init_array (&vam->json_tree);
4167     }
4168   node = vat_json_array_add (&vam->json_tree);
4169
4170   vat_json_init_object (node);
4171   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4172
4173   vat_json_print (vam->ofp, node);
4174   vat_json_free (node);
4175
4176   vam->retval = ntohl (mp->retval);
4177   vam->result_ready = 1;
4178 }
4179
4180 static u8 *
4181 format_lisp_map_request_mode (u8 * s, va_list * args)
4182 {
4183   u32 mode = va_arg (*args, u32);
4184
4185   switch (mode)
4186     {
4187     case 0:
4188       return format (0, "dst-only");
4189     case 1:
4190       return format (0, "src-dst");
4191     }
4192   return 0;
4193 }
4194
4195 static void
4196   vl_api_show_one_map_request_mode_reply_t_handler
4197   (vl_api_show_one_map_request_mode_reply_t * mp)
4198 {
4199   vat_main_t *vam = &vat_main;
4200   i32 retval = ntohl (mp->retval);
4201
4202   if (0 <= retval)
4203     {
4204       u32 mode = mp->mode;
4205       print (vam->ofp, "map_request_mode: %U",
4206              format_lisp_map_request_mode, mode);
4207     }
4208
4209   vam->retval = retval;
4210   vam->result_ready = 1;
4211 }
4212
4213 static void
4214   vl_api_show_one_map_request_mode_reply_t_handler_json
4215   (vl_api_show_one_map_request_mode_reply_t * mp)
4216 {
4217   vat_main_t *vam = &vat_main;
4218   vat_json_node_t node;
4219   u8 *s = 0;
4220   u32 mode;
4221
4222   mode = mp->mode;
4223   s = format (0, "%U", format_lisp_map_request_mode, mode);
4224   vec_add1 (s, 0);
4225
4226   vat_json_init_object (&node);
4227   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4228   vat_json_print (vam->ofp, &node);
4229   vat_json_free (&node);
4230
4231   vec_free (s);
4232   vam->retval = ntohl (mp->retval);
4233   vam->result_ready = 1;
4234 }
4235
4236 static void
4237   vl_api_one_show_xtr_mode_reply_t_handler
4238   (vl_api_one_show_xtr_mode_reply_t * mp)
4239 {
4240   vat_main_t *vam = &vat_main;
4241   i32 retval = ntohl (mp->retval);
4242
4243   if (0 <= retval)
4244     {
4245       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4246     }
4247
4248   vam->retval = retval;
4249   vam->result_ready = 1;
4250 }
4251
4252 static void
4253   vl_api_one_show_xtr_mode_reply_t_handler_json
4254   (vl_api_one_show_xtr_mode_reply_t * mp)
4255 {
4256   vat_main_t *vam = &vat_main;
4257   vat_json_node_t node;
4258   u8 *status = 0;
4259
4260   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4261   vec_add1 (status, 0);
4262
4263   vat_json_init_object (&node);
4264   vat_json_object_add_string_copy (&node, "status", status);
4265
4266   vec_free (status);
4267
4268   vat_json_print (vam->ofp, &node);
4269   vat_json_free (&node);
4270
4271   vam->retval = ntohl (mp->retval);
4272   vam->result_ready = 1;
4273 }
4274
4275 static void
4276   vl_api_one_show_pitr_mode_reply_t_handler
4277   (vl_api_one_show_pitr_mode_reply_t * mp)
4278 {
4279   vat_main_t *vam = &vat_main;
4280   i32 retval = ntohl (mp->retval);
4281
4282   if (0 <= retval)
4283     {
4284       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4285     }
4286
4287   vam->retval = retval;
4288   vam->result_ready = 1;
4289 }
4290
4291 static void
4292   vl_api_one_show_pitr_mode_reply_t_handler_json
4293   (vl_api_one_show_pitr_mode_reply_t * mp)
4294 {
4295   vat_main_t *vam = &vat_main;
4296   vat_json_node_t node;
4297   u8 *status = 0;
4298
4299   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4300   vec_add1 (status, 0);
4301
4302   vat_json_init_object (&node);
4303   vat_json_object_add_string_copy (&node, "status", status);
4304
4305   vec_free (status);
4306
4307   vat_json_print (vam->ofp, &node);
4308   vat_json_free (&node);
4309
4310   vam->retval = ntohl (mp->retval);
4311   vam->result_ready = 1;
4312 }
4313
4314 static void
4315   vl_api_one_show_petr_mode_reply_t_handler
4316   (vl_api_one_show_petr_mode_reply_t * mp)
4317 {
4318   vat_main_t *vam = &vat_main;
4319   i32 retval = ntohl (mp->retval);
4320
4321   if (0 <= retval)
4322     {
4323       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4324     }
4325
4326   vam->retval = retval;
4327   vam->result_ready = 1;
4328 }
4329
4330 static void
4331   vl_api_one_show_petr_mode_reply_t_handler_json
4332   (vl_api_one_show_petr_mode_reply_t * mp)
4333 {
4334   vat_main_t *vam = &vat_main;
4335   vat_json_node_t node;
4336   u8 *status = 0;
4337
4338   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4339   vec_add1 (status, 0);
4340
4341   vat_json_init_object (&node);
4342   vat_json_object_add_string_copy (&node, "status", status);
4343
4344   vec_free (status);
4345
4346   vat_json_print (vam->ofp, &node);
4347   vat_json_free (&node);
4348
4349   vam->retval = ntohl (mp->retval);
4350   vam->result_ready = 1;
4351 }
4352
4353 static void
4354   vl_api_show_one_use_petr_reply_t_handler
4355   (vl_api_show_one_use_petr_reply_t * mp)
4356 {
4357   vat_main_t *vam = &vat_main;
4358   i32 retval = ntohl (mp->retval);
4359
4360   if (0 <= retval)
4361     {
4362       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4363       if (mp->status)
4364         {
4365           print (vam->ofp, "Proxy-ETR address; %U",
4366                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4367                  mp->address);
4368         }
4369     }
4370
4371   vam->retval = retval;
4372   vam->result_ready = 1;
4373 }
4374
4375 static void
4376   vl_api_show_one_use_petr_reply_t_handler_json
4377   (vl_api_show_one_use_petr_reply_t * mp)
4378 {
4379   vat_main_t *vam = &vat_main;
4380   vat_json_node_t node;
4381   u8 *status = 0;
4382   struct in_addr ip4;
4383   struct in6_addr ip6;
4384
4385   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4386   vec_add1 (status, 0);
4387
4388   vat_json_init_object (&node);
4389   vat_json_object_add_string_copy (&node, "status", status);
4390   if (mp->status)
4391     {
4392       if (mp->is_ip4)
4393         {
4394           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4395           vat_json_object_add_ip6 (&node, "address", ip6);
4396         }
4397       else
4398         {
4399           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4400           vat_json_object_add_ip4 (&node, "address", ip4);
4401         }
4402     }
4403
4404   vec_free (status);
4405
4406   vat_json_print (vam->ofp, &node);
4407   vat_json_free (&node);
4408
4409   vam->retval = ntohl (mp->retval);
4410   vam->result_ready = 1;
4411 }
4412
4413 static void
4414   vl_api_show_one_nsh_mapping_reply_t_handler
4415   (vl_api_show_one_nsh_mapping_reply_t * mp)
4416 {
4417   vat_main_t *vam = &vat_main;
4418   i32 retval = ntohl (mp->retval);
4419
4420   if (0 <= retval)
4421     {
4422       print (vam->ofp, "%-20s%-16s",
4423              mp->is_set ? "set" : "not-set",
4424              mp->is_set ? (char *) mp->locator_set_name : "");
4425     }
4426
4427   vam->retval = retval;
4428   vam->result_ready = 1;
4429 }
4430
4431 static void
4432   vl_api_show_one_nsh_mapping_reply_t_handler_json
4433   (vl_api_show_one_nsh_mapping_reply_t * mp)
4434 {
4435   vat_main_t *vam = &vat_main;
4436   vat_json_node_t node;
4437   u8 *status = 0;
4438
4439   status = format (0, "%s", mp->is_set ? "yes" : "no");
4440   vec_add1 (status, 0);
4441
4442   vat_json_init_object (&node);
4443   vat_json_object_add_string_copy (&node, "is_set", status);
4444   if (mp->is_set)
4445     {
4446       vat_json_object_add_string_copy (&node, "locator_set",
4447                                        mp->locator_set_name);
4448     }
4449
4450   vec_free (status);
4451
4452   vat_json_print (vam->ofp, &node);
4453   vat_json_free (&node);
4454
4455   vam->retval = ntohl (mp->retval);
4456   vam->result_ready = 1;
4457 }
4458
4459 static void
4460   vl_api_show_one_map_register_ttl_reply_t_handler
4461   (vl_api_show_one_map_register_ttl_reply_t * mp)
4462 {
4463   vat_main_t *vam = &vat_main;
4464   i32 retval = ntohl (mp->retval);
4465
4466   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4467
4468   if (0 <= retval)
4469     {
4470       print (vam->ofp, "ttl: %u", mp->ttl);
4471     }
4472
4473   vam->retval = retval;
4474   vam->result_ready = 1;
4475 }
4476
4477 static void
4478   vl_api_show_one_map_register_ttl_reply_t_handler_json
4479   (vl_api_show_one_map_register_ttl_reply_t * mp)
4480 {
4481   vat_main_t *vam = &vat_main;
4482   vat_json_node_t node;
4483
4484   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4485   vat_json_init_object (&node);
4486   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4487
4488   vat_json_print (vam->ofp, &node);
4489   vat_json_free (&node);
4490
4491   vam->retval = ntohl (mp->retval);
4492   vam->result_ready = 1;
4493 }
4494
4495 static void
4496 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4497 {
4498   vat_main_t *vam = &vat_main;
4499   i32 retval = ntohl (mp->retval);
4500
4501   if (0 <= retval)
4502     {
4503       print (vam->ofp, "%-20s%-16s",
4504              mp->status ? "enabled" : "disabled",
4505              mp->status ? (char *) mp->locator_set_name : "");
4506     }
4507
4508   vam->retval = retval;
4509   vam->result_ready = 1;
4510 }
4511
4512 static void
4513 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4514 {
4515   vat_main_t *vam = &vat_main;
4516   vat_json_node_t node;
4517   u8 *status = 0;
4518
4519   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4520   vec_add1 (status, 0);
4521
4522   vat_json_init_object (&node);
4523   vat_json_object_add_string_copy (&node, "status", status);
4524   if (mp->status)
4525     {
4526       vat_json_object_add_string_copy (&node, "locator_set",
4527                                        mp->locator_set_name);
4528     }
4529
4530   vec_free (status);
4531
4532   vat_json_print (vam->ofp, &node);
4533   vat_json_free (&node);
4534
4535   vam->retval = ntohl (mp->retval);
4536   vam->result_ready = 1;
4537 }
4538
4539 static u8 *
4540 format_policer_type (u8 * s, va_list * va)
4541 {
4542   u32 i = va_arg (*va, u32);
4543
4544   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4545     s = format (s, "1r2c");
4546   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4547     s = format (s, "1r3c");
4548   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4549     s = format (s, "2r3c-2698");
4550   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4551     s = format (s, "2r3c-4115");
4552   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4553     s = format (s, "2r3c-mef5cf1");
4554   else
4555     s = format (s, "ILLEGAL");
4556   return s;
4557 }
4558
4559 static u8 *
4560 format_policer_rate_type (u8 * s, va_list * va)
4561 {
4562   u32 i = va_arg (*va, u32);
4563
4564   if (i == SSE2_QOS_RATE_KBPS)
4565     s = format (s, "kbps");
4566   else if (i == SSE2_QOS_RATE_PPS)
4567     s = format (s, "pps");
4568   else
4569     s = format (s, "ILLEGAL");
4570   return s;
4571 }
4572
4573 static u8 *
4574 format_policer_round_type (u8 * s, va_list * va)
4575 {
4576   u32 i = va_arg (*va, u32);
4577
4578   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4579     s = format (s, "closest");
4580   else if (i == SSE2_QOS_ROUND_TO_UP)
4581     s = format (s, "up");
4582   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4583     s = format (s, "down");
4584   else
4585     s = format (s, "ILLEGAL");
4586   return s;
4587 }
4588
4589 static u8 *
4590 format_policer_action_type (u8 * s, va_list * va)
4591 {
4592   u32 i = va_arg (*va, u32);
4593
4594   if (i == SSE2_QOS_ACTION_DROP)
4595     s = format (s, "drop");
4596   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4597     s = format (s, "transmit");
4598   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4599     s = format (s, "mark-and-transmit");
4600   else
4601     s = format (s, "ILLEGAL");
4602   return s;
4603 }
4604
4605 static u8 *
4606 format_dscp (u8 * s, va_list * va)
4607 {
4608   u32 i = va_arg (*va, u32);
4609   char *t = 0;
4610
4611   switch (i)
4612     {
4613 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4614       foreach_vnet_dscp
4615 #undef _
4616     default:
4617       return format (s, "ILLEGAL");
4618     }
4619   s = format (s, "%s", t);
4620   return s;
4621 }
4622
4623 static void
4624 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4628
4629   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4630     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4631   else
4632     conform_dscp_str = format (0, "");
4633
4634   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4635     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4636   else
4637     exceed_dscp_str = format (0, "");
4638
4639   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4640     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4641   else
4642     violate_dscp_str = format (0, "");
4643
4644   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4645          "rate type %U, round type %U, %s rate, %s color-aware, "
4646          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4647          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4648          "conform action %U%s, exceed action %U%s, violate action %U%s",
4649          mp->name,
4650          format_policer_type, mp->type,
4651          ntohl (mp->cir),
4652          ntohl (mp->eir),
4653          clib_net_to_host_u64 (mp->cb),
4654          clib_net_to_host_u64 (mp->eb),
4655          format_policer_rate_type, mp->rate_type,
4656          format_policer_round_type, mp->round_type,
4657          mp->single_rate ? "single" : "dual",
4658          mp->color_aware ? "is" : "not",
4659          ntohl (mp->cir_tokens_per_period),
4660          ntohl (mp->pir_tokens_per_period),
4661          ntohl (mp->scale),
4662          ntohl (mp->current_limit),
4663          ntohl (mp->current_bucket),
4664          ntohl (mp->extended_limit),
4665          ntohl (mp->extended_bucket),
4666          clib_net_to_host_u64 (mp->last_update_time),
4667          format_policer_action_type, mp->conform_action_type,
4668          conform_dscp_str,
4669          format_policer_action_type, mp->exceed_action_type,
4670          exceed_dscp_str,
4671          format_policer_action_type, mp->violate_action_type,
4672          violate_dscp_str);
4673
4674   vec_free (conform_dscp_str);
4675   vec_free (exceed_dscp_str);
4676   vec_free (violate_dscp_str);
4677 }
4678
4679 static void vl_api_policer_details_t_handler_json
4680   (vl_api_policer_details_t * mp)
4681 {
4682   vat_main_t *vam = &vat_main;
4683   vat_json_node_t *node;
4684   u8 *rate_type_str, *round_type_str, *type_str;
4685   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4686
4687   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4688   round_type_str =
4689     format (0, "%U", format_policer_round_type, mp->round_type);
4690   type_str = format (0, "%U", format_policer_type, mp->type);
4691   conform_action_str = format (0, "%U", format_policer_action_type,
4692                                mp->conform_action_type);
4693   exceed_action_str = format (0, "%U", format_policer_action_type,
4694                               mp->exceed_action_type);
4695   violate_action_str = format (0, "%U", format_policer_action_type,
4696                                mp->violate_action_type);
4697
4698   if (VAT_JSON_ARRAY != vam->json_tree.type)
4699     {
4700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4701       vat_json_init_array (&vam->json_tree);
4702     }
4703   node = vat_json_array_add (&vam->json_tree);
4704
4705   vat_json_init_object (node);
4706   vat_json_object_add_string_copy (node, "name", mp->name);
4707   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4708   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4709   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4710   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4711   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4712   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4713   vat_json_object_add_string_copy (node, "type", type_str);
4714   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4715   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4716   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4717   vat_json_object_add_uint (node, "cir_tokens_per_period",
4718                             ntohl (mp->cir_tokens_per_period));
4719   vat_json_object_add_uint (node, "eir_tokens_per_period",
4720                             ntohl (mp->pir_tokens_per_period));
4721   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4722   vat_json_object_add_uint (node, "current_bucket",
4723                             ntohl (mp->current_bucket));
4724   vat_json_object_add_uint (node, "extended_limit",
4725                             ntohl (mp->extended_limit));
4726   vat_json_object_add_uint (node, "extended_bucket",
4727                             ntohl (mp->extended_bucket));
4728   vat_json_object_add_uint (node, "last_update_time",
4729                             ntohl (mp->last_update_time));
4730   vat_json_object_add_string_copy (node, "conform_action",
4731                                    conform_action_str);
4732   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4733     {
4734       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4735       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4736       vec_free (dscp_str);
4737     }
4738   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4739   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4740     {
4741       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4742       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4743       vec_free (dscp_str);
4744     }
4745   vat_json_object_add_string_copy (node, "violate_action",
4746                                    violate_action_str);
4747   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4748     {
4749       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4750       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4751       vec_free (dscp_str);
4752     }
4753
4754   vec_free (rate_type_str);
4755   vec_free (round_type_str);
4756   vec_free (type_str);
4757   vec_free (conform_action_str);
4758   vec_free (exceed_action_str);
4759   vec_free (violate_action_str);
4760 }
4761
4762 static void
4763 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4764                                            mp)
4765 {
4766   vat_main_t *vam = &vat_main;
4767   int i, count = ntohl (mp->count);
4768
4769   if (count > 0)
4770     print (vam->ofp, "classify table ids (%d) : ", count);
4771   for (i = 0; i < count; i++)
4772     {
4773       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4774       print (vam->ofp, (i < count - 1) ? "," : "");
4775     }
4776   vam->retval = ntohl (mp->retval);
4777   vam->result_ready = 1;
4778 }
4779
4780 static void
4781   vl_api_classify_table_ids_reply_t_handler_json
4782   (vl_api_classify_table_ids_reply_t * mp)
4783 {
4784   vat_main_t *vam = &vat_main;
4785   int i, count = ntohl (mp->count);
4786
4787   if (count > 0)
4788     {
4789       vat_json_node_t node;
4790
4791       vat_json_init_object (&node);
4792       for (i = 0; i < count; i++)
4793         {
4794           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4795         }
4796       vat_json_print (vam->ofp, &node);
4797       vat_json_free (&node);
4798     }
4799   vam->retval = ntohl (mp->retval);
4800   vam->result_ready = 1;
4801 }
4802
4803 static void
4804   vl_api_classify_table_by_interface_reply_t_handler
4805   (vl_api_classify_table_by_interface_reply_t * mp)
4806 {
4807   vat_main_t *vam = &vat_main;
4808   u32 table_id;
4809
4810   table_id = ntohl (mp->l2_table_id);
4811   if (table_id != ~0)
4812     print (vam->ofp, "l2 table id : %d", table_id);
4813   else
4814     print (vam->ofp, "l2 table id : No input ACL tables configured");
4815   table_id = ntohl (mp->ip4_table_id);
4816   if (table_id != ~0)
4817     print (vam->ofp, "ip4 table id : %d", table_id);
4818   else
4819     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4820   table_id = ntohl (mp->ip6_table_id);
4821   if (table_id != ~0)
4822     print (vam->ofp, "ip6 table id : %d", table_id);
4823   else
4824     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4825   vam->retval = ntohl (mp->retval);
4826   vam->result_ready = 1;
4827 }
4828
4829 static void
4830   vl_api_classify_table_by_interface_reply_t_handler_json
4831   (vl_api_classify_table_by_interface_reply_t * mp)
4832 {
4833   vat_main_t *vam = &vat_main;
4834   vat_json_node_t node;
4835
4836   vat_json_init_object (&node);
4837
4838   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4839   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4840   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
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 static void vl_api_policer_add_del_reply_t_handler
4850   (vl_api_policer_add_del_reply_t * mp)
4851 {
4852   vat_main_t *vam = &vat_main;
4853   i32 retval = ntohl (mp->retval);
4854   if (vam->async_mode)
4855     {
4856       vam->async_errors += (retval < 0);
4857     }
4858   else
4859     {
4860       vam->retval = retval;
4861       vam->result_ready = 1;
4862       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4863         /*
4864          * Note: this is just barely thread-safe, depends on
4865          * the main thread spinning waiting for an answer...
4866          */
4867         errmsg ("policer index %d", ntohl (mp->policer_index));
4868     }
4869 }
4870
4871 static void vl_api_policer_add_del_reply_t_handler_json
4872   (vl_api_policer_add_del_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t node;
4876
4877   vat_json_init_object (&node);
4878   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4879   vat_json_object_add_uint (&node, "policer_index",
4880                             ntohl (mp->policer_index));
4881
4882   vat_json_print (vam->ofp, &node);
4883   vat_json_free (&node);
4884
4885   vam->retval = ntohl (mp->retval);
4886   vam->result_ready = 1;
4887 }
4888
4889 /* Format hex dump. */
4890 u8 *
4891 format_hex_bytes (u8 * s, va_list * va)
4892 {
4893   u8 *bytes = va_arg (*va, u8 *);
4894   int n_bytes = va_arg (*va, int);
4895   uword i;
4896
4897   /* Print short or long form depending on byte count. */
4898   uword short_form = n_bytes <= 32;
4899   u32 indent = format_get_indent (s);
4900
4901   if (n_bytes == 0)
4902     return s;
4903
4904   for (i = 0; i < n_bytes; i++)
4905     {
4906       if (!short_form && (i % 32) == 0)
4907         s = format (s, "%08x: ", i);
4908       s = format (s, "%02x", bytes[i]);
4909       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4910         s = format (s, "\n%U", format_white_space, indent);
4911     }
4912
4913   return s;
4914 }
4915
4916 static void
4917 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4918                                             * mp)
4919 {
4920   vat_main_t *vam = &vat_main;
4921   i32 retval = ntohl (mp->retval);
4922   if (retval == 0)
4923     {
4924       print (vam->ofp, "classify table info :");
4925       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4926              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4927              ntohl (mp->miss_next_index));
4928       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4929              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4930              ntohl (mp->match_n_vectors));
4931       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4932              ntohl (mp->mask_length));
4933     }
4934   vam->retval = retval;
4935   vam->result_ready = 1;
4936 }
4937
4938 static void
4939   vl_api_classify_table_info_reply_t_handler_json
4940   (vl_api_classify_table_info_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   vat_json_node_t node;
4944
4945   i32 retval = ntohl (mp->retval);
4946   if (retval == 0)
4947     {
4948       vat_json_init_object (&node);
4949
4950       vat_json_object_add_int (&node, "sessions",
4951                                ntohl (mp->active_sessions));
4952       vat_json_object_add_int (&node, "nexttbl",
4953                                ntohl (mp->next_table_index));
4954       vat_json_object_add_int (&node, "nextnode",
4955                                ntohl (mp->miss_next_index));
4956       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4957       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4958       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4959       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4960                       ntohl (mp->mask_length), 0);
4961       vat_json_object_add_string_copy (&node, "mask", s);
4962
4963       vat_json_print (vam->ofp, &node);
4964       vat_json_free (&node);
4965     }
4966   vam->retval = ntohl (mp->retval);
4967   vam->result_ready = 1;
4968 }
4969
4970 static void
4971 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4972                                            mp)
4973 {
4974   vat_main_t *vam = &vat_main;
4975
4976   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4977          ntohl (mp->hit_next_index), ntohl (mp->advance),
4978          ntohl (mp->opaque_index));
4979   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4980          ntohl (mp->match_length));
4981 }
4982
4983 static void
4984   vl_api_classify_session_details_t_handler_json
4985   (vl_api_classify_session_details_t * mp)
4986 {
4987   vat_main_t *vam = &vat_main;
4988   vat_json_node_t *node = NULL;
4989
4990   if (VAT_JSON_ARRAY != vam->json_tree.type)
4991     {
4992       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4993       vat_json_init_array (&vam->json_tree);
4994     }
4995   node = vat_json_array_add (&vam->json_tree);
4996
4997   vat_json_init_object (node);
4998   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4999   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5000   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5001   u8 *s =
5002     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5003             0);
5004   vat_json_object_add_string_copy (node, "match", s);
5005 }
5006
5007 static void vl_api_pg_create_interface_reply_t_handler
5008   (vl_api_pg_create_interface_reply_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011
5012   vam->retval = ntohl (mp->retval);
5013   vam->result_ready = 1;
5014 }
5015
5016 static void vl_api_pg_create_interface_reply_t_handler_json
5017   (vl_api_pg_create_interface_reply_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020   vat_json_node_t node;
5021
5022   i32 retval = ntohl (mp->retval);
5023   if (retval == 0)
5024     {
5025       vat_json_init_object (&node);
5026
5027       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5028
5029       vat_json_print (vam->ofp, &node);
5030       vat_json_free (&node);
5031     }
5032   vam->retval = ntohl (mp->retval);
5033   vam->result_ready = 1;
5034 }
5035
5036 static void vl_api_policer_classify_details_t_handler
5037   (vl_api_policer_classify_details_t * mp)
5038 {
5039   vat_main_t *vam = &vat_main;
5040
5041   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5042          ntohl (mp->table_index));
5043 }
5044
5045 static void vl_api_policer_classify_details_t_handler_json
5046   (vl_api_policer_classify_details_t * mp)
5047 {
5048   vat_main_t *vam = &vat_main;
5049   vat_json_node_t *node;
5050
5051   if (VAT_JSON_ARRAY != vam->json_tree.type)
5052     {
5053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5054       vat_json_init_array (&vam->json_tree);
5055     }
5056   node = vat_json_array_add (&vam->json_tree);
5057
5058   vat_json_init_object (node);
5059   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5060   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5061 }
5062
5063 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5064   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5065 {
5066   vat_main_t *vam = &vat_main;
5067   i32 retval = ntohl (mp->retval);
5068   if (vam->async_mode)
5069     {
5070       vam->async_errors += (retval < 0);
5071     }
5072   else
5073     {
5074       vam->retval = retval;
5075       vam->sw_if_index = ntohl (mp->sw_if_index);
5076       vam->result_ready = 1;
5077     }
5078   vam->regenerate_interface_table = 1;
5079 }
5080
5081 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5082   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085   vat_json_node_t node;
5086
5087   vat_json_init_object (&node);
5088   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5089   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5090
5091   vat_json_print (vam->ofp, &node);
5092   vat_json_free (&node);
5093
5094   vam->retval = ntohl (mp->retval);
5095   vam->result_ready = 1;
5096 }
5097
5098 static void vl_api_flow_classify_details_t_handler
5099   (vl_api_flow_classify_details_t * mp)
5100 {
5101   vat_main_t *vam = &vat_main;
5102
5103   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5104          ntohl (mp->table_index));
5105 }
5106
5107 static void vl_api_flow_classify_details_t_handler_json
5108   (vl_api_flow_classify_details_t * mp)
5109 {
5110   vat_main_t *vam = &vat_main;
5111   vat_json_node_t *node;
5112
5113   if (VAT_JSON_ARRAY != vam->json_tree.type)
5114     {
5115       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5116       vat_json_init_array (&vam->json_tree);
5117     }
5118   node = vat_json_array_add (&vam->json_tree);
5119
5120   vat_json_init_object (node);
5121   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5122   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5123 }
5124
5125 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5126 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5127 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5128 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5129 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5130 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5131 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5132 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5133 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5134 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5135
5136 /*
5137  * Generate boilerplate reply handlers, which
5138  * dig the return value out of the xxx_reply_t API message,
5139  * stick it into vam->retval, and set vam->result_ready
5140  *
5141  * Could also do this by pointing N message decode slots at
5142  * a single function, but that could break in subtle ways.
5143  */
5144
5145 #define foreach_standard_reply_retval_handler           \
5146 _(sw_interface_set_flags_reply)                         \
5147 _(sw_interface_add_del_address_reply)                   \
5148 _(sw_interface_set_rx_mode_reply)                       \
5149 _(sw_interface_set_rx_placement_reply)                  \
5150 _(sw_interface_set_table_reply)                         \
5151 _(sw_interface_set_mpls_enable_reply)                   \
5152 _(sw_interface_set_vpath_reply)                         \
5153 _(sw_interface_set_vxlan_bypass_reply)                  \
5154 _(sw_interface_set_geneve_bypass_reply)                 \
5155 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5156 _(sw_interface_set_l2_bridge_reply)                     \
5157 _(bridge_domain_add_del_reply)                          \
5158 _(sw_interface_set_l2_xconnect_reply)                   \
5159 _(l2fib_add_del_reply)                                  \
5160 _(l2fib_flush_int_reply)                                \
5161 _(l2fib_flush_bd_reply)                                 \
5162 _(ip_add_del_route_reply)                               \
5163 _(ip_table_add_del_reply)                               \
5164 _(ip_mroute_add_del_reply)                              \
5165 _(mpls_route_add_del_reply)                             \
5166 _(mpls_table_add_del_reply)                             \
5167 _(mpls_ip_bind_unbind_reply)                            \
5168 _(bier_route_add_del_reply)                             \
5169 _(bier_table_add_del_reply)                             \
5170 _(proxy_arp_add_del_reply)                              \
5171 _(proxy_arp_intfc_enable_disable_reply)                 \
5172 _(sw_interface_set_unnumbered_reply)                    \
5173 _(ip_neighbor_add_del_reply)                            \
5174 _(reset_fib_reply)                                      \
5175 _(dhcp_proxy_config_reply)                              \
5176 _(dhcp_proxy_set_vss_reply)                             \
5177 _(dhcp_client_config_reply)                             \
5178 _(set_ip_flow_hash_reply)                               \
5179 _(sw_interface_ip6_enable_disable_reply)                \
5180 _(ip6nd_proxy_add_del_reply)                            \
5181 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5182 _(sw_interface_ip6nd_ra_config_reply)                   \
5183 _(set_arp_neighbor_limit_reply)                         \
5184 _(l2_patch_add_del_reply)                               \
5185 _(sr_mpls_policy_add_reply)                             \
5186 _(sr_mpls_policy_mod_reply)                             \
5187 _(sr_mpls_policy_del_reply)                             \
5188 _(sr_policy_add_reply)                                  \
5189 _(sr_policy_mod_reply)                                  \
5190 _(sr_policy_del_reply)                                  \
5191 _(sr_localsid_add_del_reply)                            \
5192 _(sr_steering_add_del_reply)                            \
5193 _(classify_add_del_session_reply)                       \
5194 _(classify_set_interface_ip_table_reply)                \
5195 _(classify_set_interface_l2_tables_reply)               \
5196 _(l2tpv3_set_tunnel_cookies_reply)                      \
5197 _(l2tpv3_interface_enable_disable_reply)                \
5198 _(l2tpv3_set_lookup_key_reply)                          \
5199 _(l2_fib_clear_table_reply)                             \
5200 _(l2_interface_efp_filter_reply)                        \
5201 _(l2_interface_vlan_tag_rewrite_reply)                  \
5202 _(modify_vhost_user_if_reply)                           \
5203 _(delete_vhost_user_if_reply)                           \
5204 _(ip_probe_neighbor_reply)                              \
5205 _(ip_scan_neighbor_enable_disable_reply)                \
5206 _(want_ip4_arp_events_reply)                            \
5207 _(want_ip6_nd_events_reply)                             \
5208 _(want_l2_macs_events_reply)                            \
5209 _(input_acl_set_interface_reply)                        \
5210 _(ipsec_spd_add_del_reply)                              \
5211 _(ipsec_interface_add_del_spd_reply)                    \
5212 _(ipsec_spd_entry_add_del_reply)                        \
5213 _(ipsec_sad_entry_add_del_reply)                        \
5214 _(ipsec_tunnel_if_add_del_reply)                        \
5215 _(ipsec_tunnel_if_set_sa_reply)                         \
5216 _(delete_loopback_reply)                                \
5217 _(bd_ip_mac_add_del_reply)                              \
5218 _(bd_ip_mac_flush_reply)                                \
5219 _(want_interface_events_reply)                          \
5220 _(cop_interface_enable_disable_reply)                   \
5221 _(cop_whitelist_enable_disable_reply)                   \
5222 _(sw_interface_clear_stats_reply)                       \
5223 _(ioam_enable_reply)                                    \
5224 _(ioam_disable_reply)                                   \
5225 _(one_add_del_locator_reply)                            \
5226 _(one_add_del_local_eid_reply)                          \
5227 _(one_add_del_remote_mapping_reply)                     \
5228 _(one_add_del_adjacency_reply)                          \
5229 _(one_add_del_map_resolver_reply)                       \
5230 _(one_add_del_map_server_reply)                         \
5231 _(one_enable_disable_reply)                             \
5232 _(one_rloc_probe_enable_disable_reply)                  \
5233 _(one_map_register_enable_disable_reply)                \
5234 _(one_map_register_set_ttl_reply)                       \
5235 _(one_set_transport_protocol_reply)                     \
5236 _(one_map_register_fallback_threshold_reply)            \
5237 _(one_pitr_set_locator_set_reply)                       \
5238 _(one_map_request_mode_reply)                           \
5239 _(one_add_del_map_request_itr_rlocs_reply)              \
5240 _(one_eid_table_add_del_map_reply)                      \
5241 _(one_use_petr_reply)                                   \
5242 _(one_stats_enable_disable_reply)                       \
5243 _(one_add_del_l2_arp_entry_reply)                       \
5244 _(one_add_del_ndp_entry_reply)                          \
5245 _(one_stats_flush_reply)                                \
5246 _(one_enable_disable_xtr_mode_reply)                    \
5247 _(one_enable_disable_pitr_mode_reply)                   \
5248 _(one_enable_disable_petr_mode_reply)                   \
5249 _(gpe_enable_disable_reply)                             \
5250 _(gpe_set_encap_mode_reply)                             \
5251 _(gpe_add_del_iface_reply)                              \
5252 _(gpe_add_del_native_fwd_rpath_reply)                   \
5253 _(af_packet_delete_reply)                               \
5254 _(policer_classify_set_interface_reply)                 \
5255 _(netmap_create_reply)                                  \
5256 _(netmap_delete_reply)                                  \
5257 _(set_ipfix_exporter_reply)                             \
5258 _(set_ipfix_classify_stream_reply)                      \
5259 _(ipfix_classify_table_add_del_reply)                   \
5260 _(flow_classify_set_interface_reply)                    \
5261 _(sw_interface_span_enable_disable_reply)               \
5262 _(pg_capture_reply)                                     \
5263 _(pg_enable_disable_reply)                              \
5264 _(ip_source_and_port_range_check_add_del_reply)         \
5265 _(ip_source_and_port_range_check_interface_add_del_reply)\
5266 _(delete_subif_reply)                                   \
5267 _(l2_interface_pbb_tag_rewrite_reply)                   \
5268 _(set_punt_reply)                                       \
5269 _(feature_enable_disable_reply)                         \
5270 _(sw_interface_tag_add_del_reply)                       \
5271 _(hw_interface_set_mtu_reply)                           \
5272 _(p2p_ethernet_add_reply)                               \
5273 _(p2p_ethernet_del_reply)                               \
5274 _(lldp_config_reply)                                    \
5275 _(sw_interface_set_lldp_reply)                          \
5276 _(tcp_configure_src_addresses_reply)                    \
5277 _(dns_enable_disable_reply)                             \
5278 _(dns_name_server_add_del_reply)                        \
5279 _(session_rule_add_del_reply)                           \
5280 _(ip_container_proxy_add_del_reply)                     \
5281 _(output_acl_set_interface_reply)                       \
5282 _(qos_record_enable_disable_reply)
5283
5284 #define _(n)                                    \
5285     static void vl_api_##n##_t_handler          \
5286     (vl_api_##n##_t * mp)                       \
5287     {                                           \
5288         vat_main_t * vam = &vat_main;           \
5289         i32 retval = ntohl(mp->retval);         \
5290         if (vam->async_mode) {                  \
5291             vam->async_errors += (retval < 0);  \
5292         } else {                                \
5293             vam->retval = retval;               \
5294             vam->result_ready = 1;              \
5295         }                                       \
5296     }
5297 foreach_standard_reply_retval_handler;
5298 #undef _
5299
5300 #define _(n)                                    \
5301     static void vl_api_##n##_t_handler_json     \
5302     (vl_api_##n##_t * mp)                       \
5303     {                                           \
5304         vat_main_t * vam = &vat_main;           \
5305         vat_json_node_t node;                   \
5306         vat_json_init_object(&node);            \
5307         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5308         vat_json_print(vam->ofp, &node);        \
5309         vam->retval = ntohl(mp->retval);        \
5310         vam->result_ready = 1;                  \
5311     }
5312 foreach_standard_reply_retval_handler;
5313 #undef _
5314
5315 /*
5316  * Table of message reply handlers, must include boilerplate handlers
5317  * we just generated
5318  */
5319
5320 #define foreach_vpe_api_reply_msg                                       \
5321 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5322 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5323 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5324 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5325 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5326 _(CLI_REPLY, cli_reply)                                                 \
5327 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5328 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5329   sw_interface_add_del_address_reply)                                   \
5330 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5331 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5332 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5333 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5334 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5335 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5336 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5337 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5338 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5339 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5340   sw_interface_set_l2_xconnect_reply)                                   \
5341 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5342   sw_interface_set_l2_bridge_reply)                                     \
5343 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5344 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5345 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5346 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5347 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5348 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5349 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5350 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5351 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5352 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5353 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5354 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5355 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5356 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5357 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5358 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5359 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5360 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5361 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5362 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5363 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5364 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5365 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5366 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5367 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5368 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5369 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5370 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5371 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5372 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5373   proxy_arp_intfc_enable_disable_reply)                                 \
5374 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5375 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5376   sw_interface_set_unnumbered_reply)                                    \
5377 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5378 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5379 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5380 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5381 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5382 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5383 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5384 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5385 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5386 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5387   sw_interface_ip6_enable_disable_reply)                                \
5388 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5389 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5390 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5391   sw_interface_ip6nd_ra_prefix_reply)                                   \
5392 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5393   sw_interface_ip6nd_ra_config_reply)                                   \
5394 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5395 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5396 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5397 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5398 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5399 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5400 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5401 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5402 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5403 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5404 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5405 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5406 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5407 classify_set_interface_ip_table_reply)                                  \
5408 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5409   classify_set_interface_l2_tables_reply)                               \
5410 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5411 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5412 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5413 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5414 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5415   l2tpv3_interface_enable_disable_reply)                                \
5416 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5417 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5418 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5419 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5420 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5421 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5422 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5423 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5424 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5425 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5426 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5427 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5428 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5429 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5430 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5431 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5432 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5433 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5434 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5435 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5436 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5437 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5438 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5439 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5440 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5441 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5442 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5443 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5444 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5445 _(L2_MACS_EVENT, l2_macs_event)                                         \
5446 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5447 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5448 _(IP_DETAILS, ip_details)                                               \
5449 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5450 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5451 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5452 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5453 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5454 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5455 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5456 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5457 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5458 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5459 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5460 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5461 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5462 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5463 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5464 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5465 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5466 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5467 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5468 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5469 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5470 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5471 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5472 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5473 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5474 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5475 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5476 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5477 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5478   one_map_register_enable_disable_reply)                                \
5479 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5480 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5481 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5482 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5483   one_map_register_fallback_threshold_reply)                            \
5484 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5485   one_rloc_probe_enable_disable_reply)                                  \
5486 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5487 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5488 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5489 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5490 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5491 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5492 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5493 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5494 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5495 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5496 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5497 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5498 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5499 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5500 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5501 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5502   show_one_stats_enable_disable_reply)                                  \
5503 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5504 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5505 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5506 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5507 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5508 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5509 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5510 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5511   one_enable_disable_pitr_mode_reply)                                   \
5512 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5513   one_enable_disable_petr_mode_reply)                                   \
5514 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5515 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5516 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5517 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5518 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5519 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5520 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5521 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5522 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5523 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5524 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5525 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5526   gpe_add_del_native_fwd_rpath_reply)                                   \
5527 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5528   gpe_fwd_entry_path_details)                                           \
5529 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5530 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5531   one_add_del_map_request_itr_rlocs_reply)                              \
5532 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5533   one_get_map_request_itr_rlocs_reply)                                  \
5534 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5535 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5536 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5537 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5538 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5539 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5540   show_one_map_register_state_reply)                                    \
5541 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5542 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5543   show_one_map_register_fallback_threshold_reply)                       \
5544 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5545 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5546 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5547 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5548 _(POLICER_DETAILS, policer_details)                                     \
5549 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5550 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5551 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5552 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5553 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5554 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5555 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5556 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5557 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5558 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5559 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5560 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5561 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5562 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5563 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5564 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5565 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5566 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5567 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5568 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5569 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5570 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5571 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5572 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5573 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5574  ip_source_and_port_range_check_add_del_reply)                          \
5575 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5576  ip_source_and_port_range_check_interface_add_del_reply)                \
5577 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5578 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5579 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5580 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5581 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5582 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5583 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5584 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5585 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5586 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5587 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5588 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5589 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5590 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5591 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5592 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5593 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5594 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5595 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5596 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5597 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5598 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5599 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5600 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5601 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5602 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5603 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5604 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5605
5606 #define foreach_standalone_reply_msg                                    \
5607 _(SW_INTERFACE_EVENT, sw_interface_event)
5608
5609 typedef struct
5610 {
5611   u8 *name;
5612   u32 value;
5613 } name_sort_t;
5614
5615 #define STR_VTR_OP_CASE(op)     \
5616     case L2_VTR_ ## op:         \
5617         return "" # op;
5618
5619 static const char *
5620 str_vtr_op (u32 vtr_op)
5621 {
5622   switch (vtr_op)
5623     {
5624       STR_VTR_OP_CASE (DISABLED);
5625       STR_VTR_OP_CASE (PUSH_1);
5626       STR_VTR_OP_CASE (PUSH_2);
5627       STR_VTR_OP_CASE (POP_1);
5628       STR_VTR_OP_CASE (POP_2);
5629       STR_VTR_OP_CASE (TRANSLATE_1_1);
5630       STR_VTR_OP_CASE (TRANSLATE_1_2);
5631       STR_VTR_OP_CASE (TRANSLATE_2_1);
5632       STR_VTR_OP_CASE (TRANSLATE_2_2);
5633     }
5634
5635   return "UNKNOWN";
5636 }
5637
5638 static int
5639 dump_sub_interface_table (vat_main_t * vam)
5640 {
5641   const sw_interface_subif_t *sub = NULL;
5642
5643   if (vam->json_output)
5644     {
5645       clib_warning
5646         ("JSON output supported only for VPE API calls and dump_stats_table");
5647       return -99;
5648     }
5649
5650   print (vam->ofp,
5651          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5652          "Interface", "sw_if_index",
5653          "sub id", "dot1ad", "tags", "outer id",
5654          "inner id", "exact", "default", "outer any", "inner any");
5655
5656   vec_foreach (sub, vam->sw_if_subif_table)
5657   {
5658     print (vam->ofp,
5659            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5660            sub->interface_name,
5661            sub->sw_if_index,
5662            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5663            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5664            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5665            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5666     if (sub->vtr_op != L2_VTR_DISABLED)
5667       {
5668         print (vam->ofp,
5669                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5670                "tag1: %d tag2: %d ]",
5671                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5672                sub->vtr_tag1, sub->vtr_tag2);
5673       }
5674   }
5675
5676   return 0;
5677 }
5678
5679 static int
5680 name_sort_cmp (void *a1, void *a2)
5681 {
5682   name_sort_t *n1 = a1;
5683   name_sort_t *n2 = a2;
5684
5685   return strcmp ((char *) n1->name, (char *) n2->name);
5686 }
5687
5688 static int
5689 dump_interface_table (vat_main_t * vam)
5690 {
5691   hash_pair_t *p;
5692   name_sort_t *nses = 0, *ns;
5693
5694   if (vam->json_output)
5695     {
5696       clib_warning
5697         ("JSON output supported only for VPE API calls and dump_stats_table");
5698       return -99;
5699     }
5700
5701   /* *INDENT-OFF* */
5702   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5703   ({
5704     vec_add2 (nses, ns, 1);
5705     ns->name = (u8 *)(p->key);
5706     ns->value = (u32) p->value[0];
5707   }));
5708   /* *INDENT-ON* */
5709
5710   vec_sort_with_function (nses, name_sort_cmp);
5711
5712   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5713   vec_foreach (ns, nses)
5714   {
5715     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5716   }
5717   vec_free (nses);
5718   return 0;
5719 }
5720
5721 static int
5722 dump_ip_table (vat_main_t * vam, int is_ipv6)
5723 {
5724   const ip_details_t *det = NULL;
5725   const ip_address_details_t *address = NULL;
5726   u32 i = ~0;
5727
5728   print (vam->ofp, "%-12s", "sw_if_index");
5729
5730   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5731   {
5732     i++;
5733     if (!det->present)
5734       {
5735         continue;
5736       }
5737     print (vam->ofp, "%-12d", i);
5738     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5739     if (!det->addr)
5740       {
5741         continue;
5742       }
5743     vec_foreach (address, det->addr)
5744     {
5745       print (vam->ofp,
5746              "            %-30U%-13d",
5747              is_ipv6 ? format_ip6_address : format_ip4_address,
5748              address->ip, address->prefix_length);
5749     }
5750   }
5751
5752   return 0;
5753 }
5754
5755 static int
5756 dump_ipv4_table (vat_main_t * vam)
5757 {
5758   if (vam->json_output)
5759     {
5760       clib_warning
5761         ("JSON output supported only for VPE API calls and dump_stats_table");
5762       return -99;
5763     }
5764
5765   return dump_ip_table (vam, 0);
5766 }
5767
5768 static int
5769 dump_ipv6_table (vat_main_t * vam)
5770 {
5771   if (vam->json_output)
5772     {
5773       clib_warning
5774         ("JSON output supported only for VPE API calls and dump_stats_table");
5775       return -99;
5776     }
5777
5778   return dump_ip_table (vam, 1);
5779 }
5780
5781 /*
5782  * Pass CLI buffers directly in the CLI_INBAND API message,
5783  * instead of an additional shared memory area.
5784  */
5785 static int
5786 exec_inband (vat_main_t * vam)
5787 {
5788   vl_api_cli_inband_t *mp;
5789   unformat_input_t *i = vam->input;
5790   int ret;
5791
5792   if (vec_len (i->buffer) == 0)
5793     return -1;
5794
5795   if (vam->exec_mode == 0 && unformat (i, "mode"))
5796     {
5797       vam->exec_mode = 1;
5798       return 0;
5799     }
5800   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5801     {
5802       vam->exec_mode = 0;
5803       return 0;
5804     }
5805
5806   /*
5807    * In order for the CLI command to work, it
5808    * must be a vector ending in \n, not a C-string ending
5809    * in \n\0.
5810    */
5811   u32 len = vec_len (vam->input->buffer);
5812   M2 (CLI_INBAND, mp, len);
5813   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5814
5815   S (mp);
5816   W (ret);
5817   /* json responses may or may not include a useful reply... */
5818   if (vec_len (vam->cmd_reply))
5819     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5820   return ret;
5821 }
5822
5823 int
5824 exec (vat_main_t * vam)
5825 {
5826   return exec_inband (vam);
5827 }
5828
5829 static int
5830 api_create_loopback (vat_main_t * vam)
5831 {
5832   unformat_input_t *i = vam->input;
5833   vl_api_create_loopback_t *mp;
5834   vl_api_create_loopback_instance_t *mp_lbi;
5835   u8 mac_address[6];
5836   u8 mac_set = 0;
5837   u8 is_specified = 0;
5838   u32 user_instance = 0;
5839   int ret;
5840
5841   clib_memset (mac_address, 0, sizeof (mac_address));
5842
5843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5844     {
5845       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5846         mac_set = 1;
5847       if (unformat (i, "instance %d", &user_instance))
5848         is_specified = 1;
5849       else
5850         break;
5851     }
5852
5853   if (is_specified)
5854     {
5855       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5856       mp_lbi->is_specified = is_specified;
5857       if (is_specified)
5858         mp_lbi->user_instance = htonl (user_instance);
5859       if (mac_set)
5860         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5861       S (mp_lbi);
5862     }
5863   else
5864     {
5865       /* Construct the API message */
5866       M (CREATE_LOOPBACK, mp);
5867       if (mac_set)
5868         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5869       S (mp);
5870     }
5871
5872   W (ret);
5873   return ret;
5874 }
5875
5876 static int
5877 api_delete_loopback (vat_main_t * vam)
5878 {
5879   unformat_input_t *i = vam->input;
5880   vl_api_delete_loopback_t *mp;
5881   u32 sw_if_index = ~0;
5882   int ret;
5883
5884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5885     {
5886       if (unformat (i, "sw_if_index %d", &sw_if_index))
5887         ;
5888       else
5889         break;
5890     }
5891
5892   if (sw_if_index == ~0)
5893     {
5894       errmsg ("missing sw_if_index");
5895       return -99;
5896     }
5897
5898   /* Construct the API message */
5899   M (DELETE_LOOPBACK, mp);
5900   mp->sw_if_index = ntohl (sw_if_index);
5901
5902   S (mp);
5903   W (ret);
5904   return ret;
5905 }
5906
5907 static int
5908 api_want_interface_events (vat_main_t * vam)
5909 {
5910   unformat_input_t *i = vam->input;
5911   vl_api_want_interface_events_t *mp;
5912   int enable = -1;
5913   int ret;
5914
5915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5916     {
5917       if (unformat (i, "enable"))
5918         enable = 1;
5919       else if (unformat (i, "disable"))
5920         enable = 0;
5921       else
5922         break;
5923     }
5924
5925   if (enable == -1)
5926     {
5927       errmsg ("missing enable|disable");
5928       return -99;
5929     }
5930
5931   M (WANT_INTERFACE_EVENTS, mp);
5932   mp->enable_disable = enable;
5933
5934   vam->interface_event_display = enable;
5935
5936   S (mp);
5937   W (ret);
5938   return ret;
5939 }
5940
5941
5942 /* Note: non-static, called once to set up the initial intfc table */
5943 int
5944 api_sw_interface_dump (vat_main_t * vam)
5945 {
5946   vl_api_sw_interface_dump_t *mp;
5947   vl_api_control_ping_t *mp_ping;
5948   hash_pair_t *p;
5949   name_sort_t *nses = 0, *ns;
5950   sw_interface_subif_t *sub = NULL;
5951   int ret;
5952
5953   /* Toss the old name table */
5954   /* *INDENT-OFF* */
5955   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5956   ({
5957     vec_add2 (nses, ns, 1);
5958     ns->name = (u8 *)(p->key);
5959     ns->value = (u32) p->value[0];
5960   }));
5961   /* *INDENT-ON* */
5962
5963   hash_free (vam->sw_if_index_by_interface_name);
5964
5965   vec_foreach (ns, nses) vec_free (ns->name);
5966
5967   vec_free (nses);
5968
5969   vec_foreach (sub, vam->sw_if_subif_table)
5970   {
5971     vec_free (sub->interface_name);
5972   }
5973   vec_free (vam->sw_if_subif_table);
5974
5975   /* recreate the interface name hash table */
5976   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5977
5978   /*
5979    * Ask for all interface names. Otherwise, the epic catalog of
5980    * name filters becomes ridiculously long, and vat ends up needing
5981    * to be taught about new interface types.
5982    */
5983   M (SW_INTERFACE_DUMP, mp);
5984   S (mp);
5985
5986   /* Use a control ping for synchronization */
5987   MPING (CONTROL_PING, mp_ping);
5988   S (mp_ping);
5989
5990   W (ret);
5991   return ret;
5992 }
5993
5994 static int
5995 api_sw_interface_set_flags (vat_main_t * vam)
5996 {
5997   unformat_input_t *i = vam->input;
5998   vl_api_sw_interface_set_flags_t *mp;
5999   u32 sw_if_index;
6000   u8 sw_if_index_set = 0;
6001   u8 admin_up = 0;
6002   int ret;
6003
6004   /* Parse args required to build the message */
6005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6006     {
6007       if (unformat (i, "admin-up"))
6008         admin_up = 1;
6009       else if (unformat (i, "admin-down"))
6010         admin_up = 0;
6011       else
6012         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6013         sw_if_index_set = 1;
6014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6015         sw_if_index_set = 1;
6016       else
6017         break;
6018     }
6019
6020   if (sw_if_index_set == 0)
6021     {
6022       errmsg ("missing interface name or sw_if_index");
6023       return -99;
6024     }
6025
6026   /* Construct the API message */
6027   M (SW_INTERFACE_SET_FLAGS, mp);
6028   mp->sw_if_index = ntohl (sw_if_index);
6029   mp->admin_up_down = admin_up;
6030
6031   /* send it... */
6032   S (mp);
6033
6034   /* Wait for a reply, return the good/bad news... */
6035   W (ret);
6036   return ret;
6037 }
6038
6039 static int
6040 api_sw_interface_set_rx_mode (vat_main_t * vam)
6041 {
6042   unformat_input_t *i = vam->input;
6043   vl_api_sw_interface_set_rx_mode_t *mp;
6044   u32 sw_if_index;
6045   u8 sw_if_index_set = 0;
6046   int ret;
6047   u8 queue_id_valid = 0;
6048   u32 queue_id;
6049   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6050
6051   /* Parse args required to build the message */
6052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6053     {
6054       if (unformat (i, "queue %d", &queue_id))
6055         queue_id_valid = 1;
6056       else if (unformat (i, "polling"))
6057         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6058       else if (unformat (i, "interrupt"))
6059         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6060       else if (unformat (i, "adaptive"))
6061         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6062       else
6063         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6064         sw_if_index_set = 1;
6065       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6066         sw_if_index_set = 1;
6067       else
6068         break;
6069     }
6070
6071   if (sw_if_index_set == 0)
6072     {
6073       errmsg ("missing interface name or sw_if_index");
6074       return -99;
6075     }
6076   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6077     {
6078       errmsg ("missing rx-mode");
6079       return -99;
6080     }
6081
6082   /* Construct the API message */
6083   M (SW_INTERFACE_SET_RX_MODE, mp);
6084   mp->sw_if_index = ntohl (sw_if_index);
6085   mp->mode = mode;
6086   mp->queue_id_valid = queue_id_valid;
6087   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6088
6089   /* send it... */
6090   S (mp);
6091
6092   /* Wait for a reply, return the good/bad news... */
6093   W (ret);
6094   return ret;
6095 }
6096
6097 static int
6098 api_sw_interface_set_rx_placement (vat_main_t * vam)
6099 {
6100   unformat_input_t *i = vam->input;
6101   vl_api_sw_interface_set_rx_placement_t *mp;
6102   u32 sw_if_index;
6103   u8 sw_if_index_set = 0;
6104   int ret;
6105   u8 is_main = 0;
6106   u32 queue_id, thread_index;
6107
6108   /* Parse args required to build the message */
6109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6110     {
6111       if (unformat (i, "queue %d", &queue_id))
6112         ;
6113       else if (unformat (i, "main"))
6114         is_main = 1;
6115       else if (unformat (i, "worker %d", &thread_index))
6116         ;
6117       else
6118         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6119         sw_if_index_set = 1;
6120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6121         sw_if_index_set = 1;
6122       else
6123         break;
6124     }
6125
6126   if (sw_if_index_set == 0)
6127     {
6128       errmsg ("missing interface name or sw_if_index");
6129       return -99;
6130     }
6131
6132   if (is_main)
6133     thread_index = 0;
6134   /* Construct the API message */
6135   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6136   mp->sw_if_index = ntohl (sw_if_index);
6137   mp->worker_id = ntohl (thread_index);
6138   mp->queue_id = ntohl (queue_id);
6139   mp->is_main = is_main;
6140
6141   /* send it... */
6142   S (mp);
6143   /* Wait for a reply, return the good/bad news... */
6144   W (ret);
6145   return ret;
6146 }
6147
6148 static void vl_api_sw_interface_rx_placement_details_t_handler
6149   (vl_api_sw_interface_rx_placement_details_t * mp)
6150 {
6151   vat_main_t *vam = &vat_main;
6152   u32 worker_id = ntohl (mp->worker_id);
6153
6154   print (vam->ofp,
6155          "\n%-11d %-11s %-6d %-5d %-9s",
6156          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6157          worker_id, ntohl (mp->queue_id),
6158          (mp->mode ==
6159           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6160 }
6161
6162 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6163   (vl_api_sw_interface_rx_placement_details_t * mp)
6164 {
6165   vat_main_t *vam = &vat_main;
6166   vat_json_node_t *node = NULL;
6167
6168   if (VAT_JSON_ARRAY != vam->json_tree.type)
6169     {
6170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6171       vat_json_init_array (&vam->json_tree);
6172     }
6173   node = vat_json_array_add (&vam->json_tree);
6174
6175   vat_json_init_object (node);
6176   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6177   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6178   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6179   vat_json_object_add_uint (node, "mode", mp->mode);
6180 }
6181
6182 static int
6183 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6184 {
6185   unformat_input_t *i = vam->input;
6186   vl_api_sw_interface_rx_placement_dump_t *mp;
6187   vl_api_control_ping_t *mp_ping;
6188   int ret;
6189   u32 sw_if_index;
6190   u8 sw_if_index_set = 0;
6191
6192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6193     {
6194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6195         sw_if_index_set++;
6196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6197         sw_if_index_set++;
6198       else
6199         break;
6200     }
6201
6202   print (vam->ofp,
6203          "\n%-11s %-11s %-6s %-5s %-4s",
6204          "sw_if_index", "main/worker", "thread", "queue", "mode");
6205
6206   /* Dump Interface rx placement */
6207   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6208
6209   if (sw_if_index_set)
6210     mp->sw_if_index = htonl (sw_if_index);
6211   else
6212     mp->sw_if_index = ~0;
6213
6214   S (mp);
6215
6216   /* Use a control ping for synchronization */
6217   MPING (CONTROL_PING, mp_ping);
6218   S (mp_ping);
6219
6220   W (ret);
6221   return ret;
6222 }
6223
6224 static int
6225 api_sw_interface_clear_stats (vat_main_t * vam)
6226 {
6227   unformat_input_t *i = vam->input;
6228   vl_api_sw_interface_clear_stats_t *mp;
6229   u32 sw_if_index;
6230   u8 sw_if_index_set = 0;
6231   int ret;
6232
6233   /* Parse args required to build the message */
6234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6235     {
6236       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6237         sw_if_index_set = 1;
6238       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6239         sw_if_index_set = 1;
6240       else
6241         break;
6242     }
6243
6244   /* Construct the API message */
6245   M (SW_INTERFACE_CLEAR_STATS, mp);
6246
6247   if (sw_if_index_set == 1)
6248     mp->sw_if_index = ntohl (sw_if_index);
6249   else
6250     mp->sw_if_index = ~0;
6251
6252   /* send it... */
6253   S (mp);
6254
6255   /* Wait for a reply, return the good/bad news... */
6256   W (ret);
6257   return ret;
6258 }
6259
6260 static int
6261 api_sw_interface_add_del_address (vat_main_t * vam)
6262 {
6263   unformat_input_t *i = vam->input;
6264   vl_api_sw_interface_add_del_address_t *mp;
6265   u32 sw_if_index;
6266   u8 sw_if_index_set = 0;
6267   u8 is_add = 1, del_all = 0;
6268   u32 address_length = 0;
6269   u8 v4_address_set = 0;
6270   u8 v6_address_set = 0;
6271   ip4_address_t v4address;
6272   ip6_address_t v6address;
6273   int ret;
6274
6275   /* Parse args required to build the message */
6276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6277     {
6278       if (unformat (i, "del-all"))
6279         del_all = 1;
6280       else if (unformat (i, "del"))
6281         is_add = 0;
6282       else
6283         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6284         sw_if_index_set = 1;
6285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6286         sw_if_index_set = 1;
6287       else if (unformat (i, "%U/%d",
6288                          unformat_ip4_address, &v4address, &address_length))
6289         v4_address_set = 1;
6290       else if (unformat (i, "%U/%d",
6291                          unformat_ip6_address, &v6address, &address_length))
6292         v6_address_set = 1;
6293       else
6294         break;
6295     }
6296
6297   if (sw_if_index_set == 0)
6298     {
6299       errmsg ("missing interface name or sw_if_index");
6300       return -99;
6301     }
6302   if (v4_address_set && v6_address_set)
6303     {
6304       errmsg ("both v4 and v6 addresses set");
6305       return -99;
6306     }
6307   if (!v4_address_set && !v6_address_set && !del_all)
6308     {
6309       errmsg ("no addresses set");
6310       return -99;
6311     }
6312
6313   /* Construct the API message */
6314   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6315
6316   mp->sw_if_index = ntohl (sw_if_index);
6317   mp->is_add = is_add;
6318   mp->del_all = del_all;
6319   if (v6_address_set)
6320     {
6321       mp->is_ipv6 = 1;
6322       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6323     }
6324   else
6325     {
6326       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6327     }
6328   mp->address_length = address_length;
6329
6330   /* send it... */
6331   S (mp);
6332
6333   /* Wait for a reply, return good/bad news  */
6334   W (ret);
6335   return ret;
6336 }
6337
6338 static int
6339 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6340 {
6341   unformat_input_t *i = vam->input;
6342   vl_api_sw_interface_set_mpls_enable_t *mp;
6343   u32 sw_if_index;
6344   u8 sw_if_index_set = 0;
6345   u8 enable = 1;
6346   int ret;
6347
6348   /* Parse args required to build the message */
6349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6350     {
6351       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6352         sw_if_index_set = 1;
6353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6354         sw_if_index_set = 1;
6355       else if (unformat (i, "disable"))
6356         enable = 0;
6357       else if (unformat (i, "dis"))
6358         enable = 0;
6359       else
6360         break;
6361     }
6362
6363   if (sw_if_index_set == 0)
6364     {
6365       errmsg ("missing interface name or sw_if_index");
6366       return -99;
6367     }
6368
6369   /* Construct the API message */
6370   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6371
6372   mp->sw_if_index = ntohl (sw_if_index);
6373   mp->enable = enable;
6374
6375   /* send it... */
6376   S (mp);
6377
6378   /* Wait for a reply... */
6379   W (ret);
6380   return ret;
6381 }
6382
6383 static int
6384 api_sw_interface_set_table (vat_main_t * vam)
6385 {
6386   unformat_input_t *i = vam->input;
6387   vl_api_sw_interface_set_table_t *mp;
6388   u32 sw_if_index, vrf_id = 0;
6389   u8 sw_if_index_set = 0;
6390   u8 is_ipv6 = 0;
6391   int ret;
6392
6393   /* Parse args required to build the message */
6394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6395     {
6396       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6397         sw_if_index_set = 1;
6398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6399         sw_if_index_set = 1;
6400       else if (unformat (i, "vrf %d", &vrf_id))
6401         ;
6402       else if (unformat (i, "ipv6"))
6403         is_ipv6 = 1;
6404       else
6405         break;
6406     }
6407
6408   if (sw_if_index_set == 0)
6409     {
6410       errmsg ("missing interface name or sw_if_index");
6411       return -99;
6412     }
6413
6414   /* Construct the API message */
6415   M (SW_INTERFACE_SET_TABLE, mp);
6416
6417   mp->sw_if_index = ntohl (sw_if_index);
6418   mp->is_ipv6 = is_ipv6;
6419   mp->vrf_id = ntohl (vrf_id);
6420
6421   /* send it... */
6422   S (mp);
6423
6424   /* Wait for a reply... */
6425   W (ret);
6426   return ret;
6427 }
6428
6429 static void vl_api_sw_interface_get_table_reply_t_handler
6430   (vl_api_sw_interface_get_table_reply_t * mp)
6431 {
6432   vat_main_t *vam = &vat_main;
6433
6434   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6435
6436   vam->retval = ntohl (mp->retval);
6437   vam->result_ready = 1;
6438
6439 }
6440
6441 static void vl_api_sw_interface_get_table_reply_t_handler_json
6442   (vl_api_sw_interface_get_table_reply_t * mp)
6443 {
6444   vat_main_t *vam = &vat_main;
6445   vat_json_node_t node;
6446
6447   vat_json_init_object (&node);
6448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6449   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6450
6451   vat_json_print (vam->ofp, &node);
6452   vat_json_free (&node);
6453
6454   vam->retval = ntohl (mp->retval);
6455   vam->result_ready = 1;
6456 }
6457
6458 static int
6459 api_sw_interface_get_table (vat_main_t * vam)
6460 {
6461   unformat_input_t *i = vam->input;
6462   vl_api_sw_interface_get_table_t *mp;
6463   u32 sw_if_index;
6464   u8 sw_if_index_set = 0;
6465   u8 is_ipv6 = 0;
6466   int ret;
6467
6468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6469     {
6470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6471         sw_if_index_set = 1;
6472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6473         sw_if_index_set = 1;
6474       else if (unformat (i, "ipv6"))
6475         is_ipv6 = 1;
6476       else
6477         break;
6478     }
6479
6480   if (sw_if_index_set == 0)
6481     {
6482       errmsg ("missing interface name or sw_if_index");
6483       return -99;
6484     }
6485
6486   M (SW_INTERFACE_GET_TABLE, mp);
6487   mp->sw_if_index = htonl (sw_if_index);
6488   mp->is_ipv6 = is_ipv6;
6489
6490   S (mp);
6491   W (ret);
6492   return ret;
6493 }
6494
6495 static int
6496 api_sw_interface_set_vpath (vat_main_t * vam)
6497 {
6498   unformat_input_t *i = vam->input;
6499   vl_api_sw_interface_set_vpath_t *mp;
6500   u32 sw_if_index = 0;
6501   u8 sw_if_index_set = 0;
6502   u8 is_enable = 0;
6503   int ret;
6504
6505   /* Parse args required to build the message */
6506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6507     {
6508       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6509         sw_if_index_set = 1;
6510       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6511         sw_if_index_set = 1;
6512       else if (unformat (i, "enable"))
6513         is_enable = 1;
6514       else if (unformat (i, "disable"))
6515         is_enable = 0;
6516       else
6517         break;
6518     }
6519
6520   if (sw_if_index_set == 0)
6521     {
6522       errmsg ("missing interface name or sw_if_index");
6523       return -99;
6524     }
6525
6526   /* Construct the API message */
6527   M (SW_INTERFACE_SET_VPATH, mp);
6528
6529   mp->sw_if_index = ntohl (sw_if_index);
6530   mp->enable = is_enable;
6531
6532   /* send it... */
6533   S (mp);
6534
6535   /* Wait for a reply... */
6536   W (ret);
6537   return ret;
6538 }
6539
6540 static int
6541 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6542 {
6543   unformat_input_t *i = vam->input;
6544   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6545   u32 sw_if_index = 0;
6546   u8 sw_if_index_set = 0;
6547   u8 is_enable = 1;
6548   u8 is_ipv6 = 0;
6549   int ret;
6550
6551   /* Parse args required to build the message */
6552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6553     {
6554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6555         sw_if_index_set = 1;
6556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6557         sw_if_index_set = 1;
6558       else if (unformat (i, "enable"))
6559         is_enable = 1;
6560       else if (unformat (i, "disable"))
6561         is_enable = 0;
6562       else if (unformat (i, "ip4"))
6563         is_ipv6 = 0;
6564       else if (unformat (i, "ip6"))
6565         is_ipv6 = 1;
6566       else
6567         break;
6568     }
6569
6570   if (sw_if_index_set == 0)
6571     {
6572       errmsg ("missing interface name or sw_if_index");
6573       return -99;
6574     }
6575
6576   /* Construct the API message */
6577   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6578
6579   mp->sw_if_index = ntohl (sw_if_index);
6580   mp->enable = is_enable;
6581   mp->is_ipv6 = is_ipv6;
6582
6583   /* send it... */
6584   S (mp);
6585
6586   /* Wait for a reply... */
6587   W (ret);
6588   return ret;
6589 }
6590
6591 static int
6592 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6593 {
6594   unformat_input_t *i = vam->input;
6595   vl_api_sw_interface_set_geneve_bypass_t *mp;
6596   u32 sw_if_index = 0;
6597   u8 sw_if_index_set = 0;
6598   u8 is_enable = 1;
6599   u8 is_ipv6 = 0;
6600   int ret;
6601
6602   /* Parse args required to build the message */
6603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6604     {
6605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6606         sw_if_index_set = 1;
6607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6608         sw_if_index_set = 1;
6609       else if (unformat (i, "enable"))
6610         is_enable = 1;
6611       else if (unformat (i, "disable"))
6612         is_enable = 0;
6613       else if (unformat (i, "ip4"))
6614         is_ipv6 = 0;
6615       else if (unformat (i, "ip6"))
6616         is_ipv6 = 1;
6617       else
6618         break;
6619     }
6620
6621   if (sw_if_index_set == 0)
6622     {
6623       errmsg ("missing interface name or sw_if_index");
6624       return -99;
6625     }
6626
6627   /* Construct the API message */
6628   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6629
6630   mp->sw_if_index = ntohl (sw_if_index);
6631   mp->enable = is_enable;
6632   mp->is_ipv6 = is_ipv6;
6633
6634   /* send it... */
6635   S (mp);
6636
6637   /* Wait for a reply... */
6638   W (ret);
6639   return ret;
6640 }
6641
6642 static int
6643 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6644 {
6645   unformat_input_t *i = vam->input;
6646   vl_api_sw_interface_set_l2_xconnect_t *mp;
6647   u32 rx_sw_if_index;
6648   u8 rx_sw_if_index_set = 0;
6649   u32 tx_sw_if_index;
6650   u8 tx_sw_if_index_set = 0;
6651   u8 enable = 1;
6652   int ret;
6653
6654   /* Parse args required to build the message */
6655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6656     {
6657       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6658         rx_sw_if_index_set = 1;
6659       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6660         tx_sw_if_index_set = 1;
6661       else if (unformat (i, "rx"))
6662         {
6663           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6664             {
6665               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6666                             &rx_sw_if_index))
6667                 rx_sw_if_index_set = 1;
6668             }
6669           else
6670             break;
6671         }
6672       else if (unformat (i, "tx"))
6673         {
6674           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6675             {
6676               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6677                             &tx_sw_if_index))
6678                 tx_sw_if_index_set = 1;
6679             }
6680           else
6681             break;
6682         }
6683       else if (unformat (i, "enable"))
6684         enable = 1;
6685       else if (unformat (i, "disable"))
6686         enable = 0;
6687       else
6688         break;
6689     }
6690
6691   if (rx_sw_if_index_set == 0)
6692     {
6693       errmsg ("missing rx interface name or rx_sw_if_index");
6694       return -99;
6695     }
6696
6697   if (enable && (tx_sw_if_index_set == 0))
6698     {
6699       errmsg ("missing tx interface name or tx_sw_if_index");
6700       return -99;
6701     }
6702
6703   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6704
6705   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6706   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6707   mp->enable = enable;
6708
6709   S (mp);
6710   W (ret);
6711   return ret;
6712 }
6713
6714 static int
6715 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6716 {
6717   unformat_input_t *i = vam->input;
6718   vl_api_sw_interface_set_l2_bridge_t *mp;
6719   vl_api_l2_port_type_t port_type;
6720   u32 rx_sw_if_index;
6721   u8 rx_sw_if_index_set = 0;
6722   u32 bd_id;
6723   u8 bd_id_set = 0;
6724   u32 shg = 0;
6725   u8 enable = 1;
6726   int ret;
6727
6728   port_type = L2_API_PORT_TYPE_NORMAL;
6729
6730   /* Parse args required to build the message */
6731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6732     {
6733       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6734         rx_sw_if_index_set = 1;
6735       else if (unformat (i, "bd_id %d", &bd_id))
6736         bd_id_set = 1;
6737       else
6738         if (unformat
6739             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6740         rx_sw_if_index_set = 1;
6741       else if (unformat (i, "shg %d", &shg))
6742         ;
6743       else if (unformat (i, "bvi"))
6744         port_type = L2_API_PORT_TYPE_BVI;
6745       else if (unformat (i, "uu-fwd"))
6746         port_type = L2_API_PORT_TYPE_UU_FWD;
6747       else if (unformat (i, "enable"))
6748         enable = 1;
6749       else if (unformat (i, "disable"))
6750         enable = 0;
6751       else
6752         break;
6753     }
6754
6755   if (rx_sw_if_index_set == 0)
6756     {
6757       errmsg ("missing rx interface name or sw_if_index");
6758       return -99;
6759     }
6760
6761   if (enable && (bd_id_set == 0))
6762     {
6763       errmsg ("missing bridge domain");
6764       return -99;
6765     }
6766
6767   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6768
6769   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6770   mp->bd_id = ntohl (bd_id);
6771   mp->shg = (u8) shg;
6772   mp->port_type = ntohl (port_type);
6773   mp->enable = enable;
6774
6775   S (mp);
6776   W (ret);
6777   return ret;
6778 }
6779
6780 static int
6781 api_bridge_domain_dump (vat_main_t * vam)
6782 {
6783   unformat_input_t *i = vam->input;
6784   vl_api_bridge_domain_dump_t *mp;
6785   vl_api_control_ping_t *mp_ping;
6786   u32 bd_id = ~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
6795         break;
6796     }
6797
6798   M (BRIDGE_DOMAIN_DUMP, mp);
6799   mp->bd_id = ntohl (bd_id);
6800   S (mp);
6801
6802   /* Use a control ping for synchronization */
6803   MPING (CONTROL_PING, mp_ping);
6804   S (mp_ping);
6805
6806   W (ret);
6807   return ret;
6808 }
6809
6810 static int
6811 api_bridge_domain_add_del (vat_main_t * vam)
6812 {
6813   unformat_input_t *i = vam->input;
6814   vl_api_bridge_domain_add_del_t *mp;
6815   u32 bd_id = ~0;
6816   u8 is_add = 1;
6817   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6818   u8 *bd_tag = NULL;
6819   u32 mac_age = 0;
6820   int ret;
6821
6822   /* Parse args required to build the message */
6823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6824     {
6825       if (unformat (i, "bd_id %d", &bd_id))
6826         ;
6827       else if (unformat (i, "flood %d", &flood))
6828         ;
6829       else if (unformat (i, "uu-flood %d", &uu_flood))
6830         ;
6831       else if (unformat (i, "forward %d", &forward))
6832         ;
6833       else if (unformat (i, "learn %d", &learn))
6834         ;
6835       else if (unformat (i, "arp-term %d", &arp_term))
6836         ;
6837       else if (unformat (i, "mac-age %d", &mac_age))
6838         ;
6839       else if (unformat (i, "bd-tag %s", &bd_tag))
6840         ;
6841       else if (unformat (i, "del"))
6842         {
6843           is_add = 0;
6844           flood = uu_flood = forward = learn = 0;
6845         }
6846       else
6847         break;
6848     }
6849
6850   if (bd_id == ~0)
6851     {
6852       errmsg ("missing bridge domain");
6853       ret = -99;
6854       goto done;
6855     }
6856
6857   if (mac_age > 255)
6858     {
6859       errmsg ("mac age must be less than 256 ");
6860       ret = -99;
6861       goto done;
6862     }
6863
6864   if ((bd_tag) && (vec_len (bd_tag) > 63))
6865     {
6866       errmsg ("bd-tag cannot be longer than 63");
6867       ret = -99;
6868       goto done;
6869     }
6870
6871   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6872
6873   mp->bd_id = ntohl (bd_id);
6874   mp->flood = flood;
6875   mp->uu_flood = uu_flood;
6876   mp->forward = forward;
6877   mp->learn = learn;
6878   mp->arp_term = arp_term;
6879   mp->is_add = is_add;
6880   mp->mac_age = (u8) mac_age;
6881   if (bd_tag)
6882     {
6883       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6884       mp->bd_tag[vec_len (bd_tag)] = 0;
6885     }
6886   S (mp);
6887   W (ret);
6888
6889 done:
6890   vec_free (bd_tag);
6891   return ret;
6892 }
6893
6894 static int
6895 api_l2fib_flush_bd (vat_main_t * vam)
6896 {
6897   unformat_input_t *i = vam->input;
6898   vl_api_l2fib_flush_bd_t *mp;
6899   u32 bd_id = ~0;
6900   int ret;
6901
6902   /* Parse args required to build the message */
6903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6904     {
6905       if (unformat (i, "bd_id %d", &bd_id));
6906       else
6907         break;
6908     }
6909
6910   if (bd_id == ~0)
6911     {
6912       errmsg ("missing bridge domain");
6913       return -99;
6914     }
6915
6916   M (L2FIB_FLUSH_BD, mp);
6917
6918   mp->bd_id = htonl (bd_id);
6919
6920   S (mp);
6921   W (ret);
6922   return ret;
6923 }
6924
6925 static int
6926 api_l2fib_flush_int (vat_main_t * vam)
6927 {
6928   unformat_input_t *i = vam->input;
6929   vl_api_l2fib_flush_int_t *mp;
6930   u32 sw_if_index = ~0;
6931   int ret;
6932
6933   /* Parse args required to build the message */
6934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935     {
6936       if (unformat (i, "sw_if_index %d", &sw_if_index));
6937       else
6938         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6939       else
6940         break;
6941     }
6942
6943   if (sw_if_index == ~0)
6944     {
6945       errmsg ("missing interface name or sw_if_index");
6946       return -99;
6947     }
6948
6949   M (L2FIB_FLUSH_INT, mp);
6950
6951   mp->sw_if_index = ntohl (sw_if_index);
6952
6953   S (mp);
6954   W (ret);
6955   return ret;
6956 }
6957
6958 static int
6959 api_l2fib_add_del (vat_main_t * vam)
6960 {
6961   unformat_input_t *i = vam->input;
6962   vl_api_l2fib_add_del_t *mp;
6963   f64 timeout;
6964   u8 mac[6] = { 0 };
6965   u8 mac_set = 0;
6966   u32 bd_id;
6967   u8 bd_id_set = 0;
6968   u32 sw_if_index = 0;
6969   u8 sw_if_index_set = 0;
6970   u8 is_add = 1;
6971   u8 static_mac = 0;
6972   u8 filter_mac = 0;
6973   u8 bvi_mac = 0;
6974   int count = 1;
6975   f64 before = 0;
6976   int j;
6977
6978   /* Parse args required to build the message */
6979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980     {
6981       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6982         mac_set = 1;
6983       else if (unformat (i, "bd_id %d", &bd_id))
6984         bd_id_set = 1;
6985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6986         sw_if_index_set = 1;
6987       else if (unformat (i, "sw_if"))
6988         {
6989           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6990             {
6991               if (unformat
6992                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6993                 sw_if_index_set = 1;
6994             }
6995           else
6996             break;
6997         }
6998       else if (unformat (i, "static"))
6999         static_mac = 1;
7000       else if (unformat (i, "filter"))
7001         {
7002           filter_mac = 1;
7003           static_mac = 1;
7004         }
7005       else if (unformat (i, "bvi"))
7006         {
7007           bvi_mac = 1;
7008           static_mac = 1;
7009         }
7010       else if (unformat (i, "del"))
7011         is_add = 0;
7012       else if (unformat (i, "count %d", &count))
7013         ;
7014       else
7015         break;
7016     }
7017
7018   if (mac_set == 0)
7019     {
7020       errmsg ("missing mac address");
7021       return -99;
7022     }
7023
7024   if (bd_id_set == 0)
7025     {
7026       errmsg ("missing bridge domain");
7027       return -99;
7028     }
7029
7030   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7031     {
7032       errmsg ("missing interface name or sw_if_index");
7033       return -99;
7034     }
7035
7036   if (count > 1)
7037     {
7038       /* Turn on async mode */
7039       vam->async_mode = 1;
7040       vam->async_errors = 0;
7041       before = vat_time_now (vam);
7042     }
7043
7044   for (j = 0; j < count; j++)
7045     {
7046       M (L2FIB_ADD_DEL, mp);
7047
7048       clib_memcpy (mp->mac, mac, 6);
7049       mp->bd_id = ntohl (bd_id);
7050       mp->is_add = is_add;
7051       mp->sw_if_index = ntohl (sw_if_index);
7052
7053       if (is_add)
7054         {
7055           mp->static_mac = static_mac;
7056           mp->filter_mac = filter_mac;
7057           mp->bvi_mac = bvi_mac;
7058         }
7059       increment_mac_address (mac);
7060       /* send it... */
7061       S (mp);
7062     }
7063
7064   if (count > 1)
7065     {
7066       vl_api_control_ping_t *mp_ping;
7067       f64 after;
7068
7069       /* Shut off async mode */
7070       vam->async_mode = 0;
7071
7072       MPING (CONTROL_PING, mp_ping);
7073       S (mp_ping);
7074
7075       timeout = vat_time_now (vam) + 1.0;
7076       while (vat_time_now (vam) < timeout)
7077         if (vam->result_ready == 1)
7078           goto out;
7079       vam->retval = -99;
7080
7081     out:
7082       if (vam->retval == -99)
7083         errmsg ("timeout");
7084
7085       if (vam->async_errors > 0)
7086         {
7087           errmsg ("%d asynchronous errors", vam->async_errors);
7088           vam->retval = -98;
7089         }
7090       vam->async_errors = 0;
7091       after = vat_time_now (vam);
7092
7093       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7094              count, after - before, count / (after - before));
7095     }
7096   else
7097     {
7098       int ret;
7099
7100       /* Wait for a reply... */
7101       W (ret);
7102       return ret;
7103     }
7104   /* Return the good/bad news */
7105   return (vam->retval);
7106 }
7107
7108 static int
7109 api_bridge_domain_set_mac_age (vat_main_t * vam)
7110 {
7111   unformat_input_t *i = vam->input;
7112   vl_api_bridge_domain_set_mac_age_t *mp;
7113   u32 bd_id = ~0;
7114   u32 mac_age = 0;
7115   int ret;
7116
7117   /* Parse args required to build the message */
7118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7119     {
7120       if (unformat (i, "bd_id %d", &bd_id));
7121       else if (unformat (i, "mac-age %d", &mac_age));
7122       else
7123         break;
7124     }
7125
7126   if (bd_id == ~0)
7127     {
7128       errmsg ("missing bridge domain");
7129       return -99;
7130     }
7131
7132   if (mac_age > 255)
7133     {
7134       errmsg ("mac age must be less than 256 ");
7135       return -99;
7136     }
7137
7138   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7139
7140   mp->bd_id = htonl (bd_id);
7141   mp->mac_age = (u8) mac_age;
7142
7143   S (mp);
7144   W (ret);
7145   return ret;
7146 }
7147
7148 static int
7149 api_l2_flags (vat_main_t * vam)
7150 {
7151   unformat_input_t *i = vam->input;
7152   vl_api_l2_flags_t *mp;
7153   u32 sw_if_index;
7154   u32 flags = 0;
7155   u8 sw_if_index_set = 0;
7156   u8 is_set = 0;
7157   int ret;
7158
7159   /* Parse args required to build the message */
7160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7161     {
7162       if (unformat (i, "sw_if_index %d", &sw_if_index))
7163         sw_if_index_set = 1;
7164       else if (unformat (i, "sw_if"))
7165         {
7166           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7167             {
7168               if (unformat
7169                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7170                 sw_if_index_set = 1;
7171             }
7172           else
7173             break;
7174         }
7175       else if (unformat (i, "learn"))
7176         flags |= L2_LEARN;
7177       else if (unformat (i, "forward"))
7178         flags |= L2_FWD;
7179       else if (unformat (i, "flood"))
7180         flags |= L2_FLOOD;
7181       else if (unformat (i, "uu-flood"))
7182         flags |= L2_UU_FLOOD;
7183       else if (unformat (i, "arp-term"))
7184         flags |= L2_ARP_TERM;
7185       else if (unformat (i, "off"))
7186         is_set = 0;
7187       else if (unformat (i, "disable"))
7188         is_set = 0;
7189       else
7190         break;
7191     }
7192
7193   if (sw_if_index_set == 0)
7194     {
7195       errmsg ("missing interface name or sw_if_index");
7196       return -99;
7197     }
7198
7199   M (L2_FLAGS, mp);
7200
7201   mp->sw_if_index = ntohl (sw_if_index);
7202   mp->feature_bitmap = ntohl (flags);
7203   mp->is_set = is_set;
7204
7205   S (mp);
7206   W (ret);
7207   return ret;
7208 }
7209
7210 static int
7211 api_bridge_flags (vat_main_t * vam)
7212 {
7213   unformat_input_t *i = vam->input;
7214   vl_api_bridge_flags_t *mp;
7215   u32 bd_id;
7216   u8 bd_id_set = 0;
7217   u8 is_set = 1;
7218   bd_flags_t flags = 0;
7219   int ret;
7220
7221   /* Parse args required to build the message */
7222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7223     {
7224       if (unformat (i, "bd_id %d", &bd_id))
7225         bd_id_set = 1;
7226       else if (unformat (i, "learn"))
7227         flags |= BRIDGE_API_FLAG_LEARN;
7228       else if (unformat (i, "forward"))
7229         flags |= BRIDGE_API_FLAG_FWD;
7230       else if (unformat (i, "flood"))
7231         flags |= BRIDGE_API_FLAG_FLOOD;
7232       else if (unformat (i, "uu-flood"))
7233         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7234       else if (unformat (i, "arp-term"))
7235         flags |= BRIDGE_API_FLAG_ARP_TERM;
7236       else if (unformat (i, "off"))
7237         is_set = 0;
7238       else if (unformat (i, "disable"))
7239         is_set = 0;
7240       else
7241         break;
7242     }
7243
7244   if (bd_id_set == 0)
7245     {
7246       errmsg ("missing bridge domain");
7247       return -99;
7248     }
7249
7250   M (BRIDGE_FLAGS, mp);
7251
7252   mp->bd_id = ntohl (bd_id);
7253   mp->flags = ntohl (flags);
7254   mp->is_set = is_set;
7255
7256   S (mp);
7257   W (ret);
7258   return ret;
7259 }
7260
7261 static int
7262 api_bd_ip_mac_add_del (vat_main_t * vam)
7263 {
7264   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7265   vl_api_mac_address_t mac = { 0 };
7266   unformat_input_t *i = vam->input;
7267   vl_api_bd_ip_mac_add_del_t *mp;
7268   u32 bd_id;
7269   u8 is_add = 1;
7270   u8 bd_id_set = 0;
7271   u8 ip_set = 0;
7272   u8 mac_set = 0;
7273   int ret;
7274
7275
7276   /* Parse args required to build the message */
7277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7278     {
7279       if (unformat (i, "bd_id %d", &bd_id))
7280         {
7281           bd_id_set++;
7282         }
7283       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7284         {
7285           ip_set++;
7286         }
7287       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7288         {
7289           mac_set++;
7290         }
7291       else if (unformat (i, "del"))
7292         is_add = 0;
7293       else
7294         break;
7295     }
7296
7297   if (bd_id_set == 0)
7298     {
7299       errmsg ("missing bridge domain");
7300       return -99;
7301     }
7302   else if (ip_set == 0)
7303     {
7304       errmsg ("missing IP address");
7305       return -99;
7306     }
7307   else if (mac_set == 0)
7308     {
7309       errmsg ("missing MAC address");
7310       return -99;
7311     }
7312
7313   M (BD_IP_MAC_ADD_DEL, mp);
7314
7315   mp->bd_id = ntohl (bd_id);
7316   mp->is_add = is_add;
7317
7318   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7319   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7320
7321   S (mp);
7322   W (ret);
7323   return ret;
7324 }
7325
7326 static int
7327 api_bd_ip_mac_flush (vat_main_t * vam)
7328 {
7329   unformat_input_t *i = vam->input;
7330   vl_api_bd_ip_mac_flush_t *mp;
7331   u32 bd_id;
7332   u8 bd_id_set = 0;
7333   int ret;
7334
7335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7336     {
7337       if (unformat (i, "bd_id %d", &bd_id))
7338         {
7339           bd_id_set++;
7340         }
7341       else
7342         break;
7343     }
7344
7345   if (bd_id_set == 0)
7346     {
7347       errmsg ("missing bridge domain");
7348       return -99;
7349     }
7350
7351   M (BD_IP_MAC_FLUSH, mp);
7352
7353   mp->bd_id = ntohl (bd_id);
7354
7355   S (mp);
7356   W (ret);
7357   return ret;
7358 }
7359
7360 static void vl_api_bd_ip_mac_details_t_handler
7361   (vl_api_bd_ip_mac_details_t * mp)
7362 {
7363   vat_main_t *vam = &vat_main;
7364   u8 *ip = 0;
7365
7366   if (!mp->is_ipv6)
7367     ip =
7368       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7369   else
7370     ip =
7371       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7372
7373   print (vam->ofp,
7374          "\n%-5d %-7s %-20U %-30s",
7375          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7376          format_ethernet_address, mp->mac_address, ip);
7377
7378   vec_free (ip);
7379 }
7380
7381 static void vl_api_bd_ip_mac_details_t_handler_json
7382   (vl_api_bd_ip_mac_details_t * mp)
7383 {
7384   vat_main_t *vam = &vat_main;
7385   vat_json_node_t *node = NULL;
7386
7387   if (VAT_JSON_ARRAY != vam->json_tree.type)
7388     {
7389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7390       vat_json_init_array (&vam->json_tree);
7391     }
7392   node = vat_json_array_add (&vam->json_tree);
7393
7394   vat_json_init_object (node);
7395   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7396   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7397   vat_json_object_add_string_copy (node, "mac_address",
7398                                    format (0, "%U", format_ethernet_address,
7399                                            &mp->mac_address));
7400   u8 *ip = 0;
7401
7402   if (!mp->is_ipv6)
7403     ip =
7404       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7405   else
7406     ip =
7407       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7408   vat_json_object_add_string_copy (node, "ip_address", ip);
7409   vec_free (ip);
7410 }
7411
7412 static int
7413 api_bd_ip_mac_dump (vat_main_t * vam)
7414 {
7415   unformat_input_t *i = vam->input;
7416   vl_api_bd_ip_mac_dump_t *mp;
7417   vl_api_control_ping_t *mp_ping;
7418   int ret;
7419   u32 bd_id;
7420   u8 bd_id_set = 0;
7421
7422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7423     {
7424       if (unformat (i, "bd_id %d", &bd_id))
7425         {
7426           bd_id_set++;
7427         }
7428       else
7429         break;
7430     }
7431
7432   print (vam->ofp,
7433          "\n%-5s %-7s %-20s %-30s",
7434          "bd_id", "is_ipv6", "mac_address", "ip_address");
7435
7436   /* Dump Bridge Domain Ip to Mac entries */
7437   M (BD_IP_MAC_DUMP, mp);
7438
7439   if (bd_id_set)
7440     mp->bd_id = htonl (bd_id);
7441   else
7442     mp->bd_id = ~0;
7443
7444   S (mp);
7445
7446   /* Use a control ping for synchronization */
7447   MPING (CONTROL_PING, mp_ping);
7448   S (mp_ping);
7449
7450   W (ret);
7451   return ret;
7452 }
7453
7454 static int
7455 api_tap_create_v2 (vat_main_t * vam)
7456 {
7457   unformat_input_t *i = vam->input;
7458   vl_api_tap_create_v2_t *mp;
7459   u8 mac_address[6];
7460   u8 random_mac = 1;
7461   u32 id = ~0;
7462   u8 *host_if_name = 0;
7463   u8 *host_ns = 0;
7464   u8 host_mac_addr[6];
7465   u8 host_mac_addr_set = 0;
7466   u8 *host_bridge = 0;
7467   ip4_address_t host_ip4_addr;
7468   ip4_address_t host_ip4_gw;
7469   u8 host_ip4_gw_set = 0;
7470   u32 host_ip4_prefix_len = 0;
7471   ip6_address_t host_ip6_addr;
7472   ip6_address_t host_ip6_gw;
7473   u8 host_ip6_gw_set = 0;
7474   u32 host_ip6_prefix_len = 0;
7475   int ret;
7476   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7477
7478   clib_memset (mac_address, 0, sizeof (mac_address));
7479
7480   /* Parse args required to build the message */
7481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7482     {
7483       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7484         {
7485           random_mac = 0;
7486         }
7487       else if (unformat (i, "id %u", &id))
7488         ;
7489       else if (unformat (i, "host-if-name %s", &host_if_name))
7490         ;
7491       else if (unformat (i, "host-ns %s", &host_ns))
7492         ;
7493       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7494                          host_mac_addr))
7495         host_mac_addr_set = 1;
7496       else if (unformat (i, "host-bridge %s", &host_bridge))
7497         ;
7498       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7499                          &host_ip4_addr, &host_ip4_prefix_len))
7500         ;
7501       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7502                          &host_ip6_addr, &host_ip6_prefix_len))
7503         ;
7504       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7505                          &host_ip4_gw))
7506         host_ip4_gw_set = 1;
7507       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7508                          &host_ip6_gw))
7509         host_ip6_gw_set = 1;
7510       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7511         ;
7512       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7513         ;
7514       else
7515         break;
7516     }
7517
7518   if (vec_len (host_if_name) > 63)
7519     {
7520       errmsg ("tap name too long. ");
7521       return -99;
7522     }
7523   if (vec_len (host_ns) > 63)
7524     {
7525       errmsg ("host name space too long. ");
7526       return -99;
7527     }
7528   if (vec_len (host_bridge) > 63)
7529     {
7530       errmsg ("host bridge name too long. ");
7531       return -99;
7532     }
7533   if (host_ip4_prefix_len > 32)
7534     {
7535       errmsg ("host ip4 prefix length not valid. ");
7536       return -99;
7537     }
7538   if (host_ip6_prefix_len > 128)
7539     {
7540       errmsg ("host ip6 prefix length not valid. ");
7541       return -99;
7542     }
7543   if (!is_pow2 (rx_ring_sz))
7544     {
7545       errmsg ("rx ring size must be power of 2. ");
7546       return -99;
7547     }
7548   if (rx_ring_sz > 32768)
7549     {
7550       errmsg ("rx ring size must be 32768 or lower. ");
7551       return -99;
7552     }
7553   if (!is_pow2 (tx_ring_sz))
7554     {
7555       errmsg ("tx ring size must be power of 2. ");
7556       return -99;
7557     }
7558   if (tx_ring_sz > 32768)
7559     {
7560       errmsg ("tx ring size must be 32768 or lower. ");
7561       return -99;
7562     }
7563
7564   /* Construct the API message */
7565   M (TAP_CREATE_V2, mp);
7566
7567   mp->use_random_mac = random_mac;
7568
7569   mp->id = ntohl (id);
7570   mp->host_namespace_set = host_ns != 0;
7571   mp->host_bridge_set = host_bridge != 0;
7572   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7573   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7574   mp->rx_ring_sz = ntohs (rx_ring_sz);
7575   mp->tx_ring_sz = ntohs (tx_ring_sz);
7576
7577   if (random_mac == 0)
7578     clib_memcpy (mp->mac_address, mac_address, 6);
7579   if (host_mac_addr_set)
7580     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7581   if (host_if_name)
7582     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7583   if (host_ns)
7584     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7585   if (host_bridge)
7586     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7587   if (host_ip4_prefix_len)
7588     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7589   if (host_ip6_prefix_len)
7590     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7591   if (host_ip4_gw_set)
7592     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7593   if (host_ip6_gw_set)
7594     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7595
7596   vec_free (host_ns);
7597   vec_free (host_if_name);
7598   vec_free (host_bridge);
7599
7600   /* send it... */
7601   S (mp);
7602
7603   /* Wait for a reply... */
7604   W (ret);
7605   return ret;
7606 }
7607
7608 static int
7609 api_tap_delete_v2 (vat_main_t * vam)
7610 {
7611   unformat_input_t *i = vam->input;
7612   vl_api_tap_delete_v2_t *mp;
7613   u32 sw_if_index = ~0;
7614   u8 sw_if_index_set = 0;
7615   int ret;
7616
7617   /* Parse args required to build the message */
7618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7619     {
7620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7621         sw_if_index_set = 1;
7622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7623         sw_if_index_set = 1;
7624       else
7625         break;
7626     }
7627
7628   if (sw_if_index_set == 0)
7629     {
7630       errmsg ("missing vpp interface name. ");
7631       return -99;
7632     }
7633
7634   /* Construct the API message */
7635   M (TAP_DELETE_V2, mp);
7636
7637   mp->sw_if_index = ntohl (sw_if_index);
7638
7639   /* send it... */
7640   S (mp);
7641
7642   /* Wait for a reply... */
7643   W (ret);
7644   return ret;
7645 }
7646
7647 uword
7648 unformat_pci_addr (unformat_input_t * input, va_list * args)
7649 {
7650   struct pci_addr_t
7651   {
7652     u16 domain;
7653     u8 bus;
7654     u8 slot:5;
7655     u8 function:3;
7656   } *addr;
7657   addr = va_arg (*args, struct pci_addr_t *);
7658   u32 x[4];
7659
7660   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7661     return 0;
7662
7663   addr->domain = x[0];
7664   addr->bus = x[1];
7665   addr->slot = x[2];
7666   addr->function = x[3];
7667
7668   return 1;
7669 }
7670
7671 static int
7672 api_virtio_pci_create (vat_main_t * vam)
7673 {
7674   unformat_input_t *i = vam->input;
7675   vl_api_virtio_pci_create_t *mp;
7676   u8 mac_address[6];
7677   u8 random_mac = 1;
7678   u8 gso_enabled = 0;
7679   u32 pci_addr = 0;
7680   u64 features = (u64) ~ (0ULL);
7681   int ret;
7682
7683   clib_memset (mac_address, 0, sizeof (mac_address));
7684
7685   /* Parse args required to build the message */
7686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7689         {
7690           random_mac = 0;
7691         }
7692       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7693         ;
7694       else if (unformat (i, "features 0x%llx", &features))
7695         ;
7696       else if (unformat (i, "gso-enabled"))
7697         gso_enabled = 1;
7698       else
7699         break;
7700     }
7701
7702   if (pci_addr == 0)
7703     {
7704       errmsg ("pci address must be non zero. ");
7705       return -99;
7706     }
7707
7708   /* Construct the API message */
7709   M (VIRTIO_PCI_CREATE, mp);
7710
7711   mp->use_random_mac = random_mac;
7712
7713   mp->pci_addr = htonl (pci_addr);
7714   mp->features = clib_host_to_net_u64 (features);
7715   mp->gso_enabled = gso_enabled;
7716
7717   if (random_mac == 0)
7718     clib_memcpy (mp->mac_address, mac_address, 6);
7719
7720   /* send it... */
7721   S (mp);
7722
7723   /* Wait for a reply... */
7724   W (ret);
7725   return ret;
7726 }
7727
7728 static int
7729 api_virtio_pci_delete (vat_main_t * vam)
7730 {
7731   unformat_input_t *i = vam->input;
7732   vl_api_virtio_pci_delete_t *mp;
7733   u32 sw_if_index = ~0;
7734   u8 sw_if_index_set = 0;
7735   int ret;
7736
7737   /* Parse args required to build the message */
7738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7739     {
7740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7741         sw_if_index_set = 1;
7742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7743         sw_if_index_set = 1;
7744       else
7745         break;
7746     }
7747
7748   if (sw_if_index_set == 0)
7749     {
7750       errmsg ("missing vpp interface name. ");
7751       return -99;
7752     }
7753
7754   /* Construct the API message */
7755   M (VIRTIO_PCI_DELETE, mp);
7756
7757   mp->sw_if_index = htonl (sw_if_index);
7758
7759   /* send it... */
7760   S (mp);
7761
7762   /* Wait for a reply... */
7763   W (ret);
7764   return ret;
7765 }
7766
7767 static int
7768 api_bond_create (vat_main_t * vam)
7769 {
7770   unformat_input_t *i = vam->input;
7771   vl_api_bond_create_t *mp;
7772   u8 mac_address[6];
7773   u8 custom_mac = 0;
7774   int ret;
7775   u8 mode;
7776   u8 lb;
7777   u8 mode_is_set = 0;
7778   u32 id = ~0;
7779
7780   clib_memset (mac_address, 0, sizeof (mac_address));
7781   lb = BOND_LB_L2;
7782
7783   /* Parse args required to build the message */
7784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7785     {
7786       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7787         mode_is_set = 1;
7788       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7789                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7790         ;
7791       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7792                          mac_address))
7793         custom_mac = 1;
7794       else if (unformat (i, "id %u", &id))
7795         ;
7796       else
7797         break;
7798     }
7799
7800   if (mode_is_set == 0)
7801     {
7802       errmsg ("Missing bond mode. ");
7803       return -99;
7804     }
7805
7806   /* Construct the API message */
7807   M (BOND_CREATE, mp);
7808
7809   mp->use_custom_mac = custom_mac;
7810
7811   mp->mode = mode;
7812   mp->lb = lb;
7813   mp->id = htonl (id);
7814
7815   if (custom_mac)
7816     clib_memcpy (mp->mac_address, mac_address, 6);
7817
7818   /* send it... */
7819   S (mp);
7820
7821   /* Wait for a reply... */
7822   W (ret);
7823   return ret;
7824 }
7825
7826 static int
7827 api_bond_delete (vat_main_t * vam)
7828 {
7829   unformat_input_t *i = vam->input;
7830   vl_api_bond_delete_t *mp;
7831   u32 sw_if_index = ~0;
7832   u8 sw_if_index_set = 0;
7833   int ret;
7834
7835   /* Parse args required to build the message */
7836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7837     {
7838       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7839         sw_if_index_set = 1;
7840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7841         sw_if_index_set = 1;
7842       else
7843         break;
7844     }
7845
7846   if (sw_if_index_set == 0)
7847     {
7848       errmsg ("missing vpp interface name. ");
7849       return -99;
7850     }
7851
7852   /* Construct the API message */
7853   M (BOND_DELETE, mp);
7854
7855   mp->sw_if_index = ntohl (sw_if_index);
7856
7857   /* send it... */
7858   S (mp);
7859
7860   /* Wait for a reply... */
7861   W (ret);
7862   return ret;
7863 }
7864
7865 static int
7866 api_bond_enslave (vat_main_t * vam)
7867 {
7868   unformat_input_t *i = vam->input;
7869   vl_api_bond_enslave_t *mp;
7870   u32 bond_sw_if_index;
7871   int ret;
7872   u8 is_passive;
7873   u8 is_long_timeout;
7874   u32 bond_sw_if_index_is_set = 0;
7875   u32 sw_if_index;
7876   u8 sw_if_index_is_set = 0;
7877
7878   /* Parse args required to build the message */
7879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7880     {
7881       if (unformat (i, "sw_if_index %d", &sw_if_index))
7882         sw_if_index_is_set = 1;
7883       else if (unformat (i, "bond %u", &bond_sw_if_index))
7884         bond_sw_if_index_is_set = 1;
7885       else if (unformat (i, "passive %d", &is_passive))
7886         ;
7887       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7888         ;
7889       else
7890         break;
7891     }
7892
7893   if (bond_sw_if_index_is_set == 0)
7894     {
7895       errmsg ("Missing bond sw_if_index. ");
7896       return -99;
7897     }
7898   if (sw_if_index_is_set == 0)
7899     {
7900       errmsg ("Missing slave sw_if_index. ");
7901       return -99;
7902     }
7903
7904   /* Construct the API message */
7905   M (BOND_ENSLAVE, mp);
7906
7907   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7908   mp->sw_if_index = ntohl (sw_if_index);
7909   mp->is_long_timeout = is_long_timeout;
7910   mp->is_passive = is_passive;
7911
7912   /* send it... */
7913   S (mp);
7914
7915   /* Wait for a reply... */
7916   W (ret);
7917   return ret;
7918 }
7919
7920 static int
7921 api_bond_detach_slave (vat_main_t * vam)
7922 {
7923   unformat_input_t *i = vam->input;
7924   vl_api_bond_detach_slave_t *mp;
7925   u32 sw_if_index = ~0;
7926   u8 sw_if_index_set = 0;
7927   int ret;
7928
7929   /* Parse args required to build the message */
7930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7931     {
7932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7933         sw_if_index_set = 1;
7934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7935         sw_if_index_set = 1;
7936       else
7937         break;
7938     }
7939
7940   if (sw_if_index_set == 0)
7941     {
7942       errmsg ("missing vpp interface name. ");
7943       return -99;
7944     }
7945
7946   /* Construct the API message */
7947   M (BOND_DETACH_SLAVE, mp);
7948
7949   mp->sw_if_index = ntohl (sw_if_index);
7950
7951   /* send it... */
7952   S (mp);
7953
7954   /* Wait for a reply... */
7955   W (ret);
7956   return ret;
7957 }
7958
7959 static int
7960 api_ip_table_add_del (vat_main_t * vam)
7961 {
7962   unformat_input_t *i = vam->input;
7963   vl_api_ip_table_add_del_t *mp;
7964   u32 table_id = ~0;
7965   u8 is_ipv6 = 0;
7966   u8 is_add = 1;
7967   int ret = 0;
7968
7969   /* Parse args required to build the message */
7970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7971     {
7972       if (unformat (i, "ipv6"))
7973         is_ipv6 = 1;
7974       else if (unformat (i, "del"))
7975         is_add = 0;
7976       else if (unformat (i, "add"))
7977         is_add = 1;
7978       else if (unformat (i, "table %d", &table_id))
7979         ;
7980       else
7981         {
7982           clib_warning ("parse error '%U'", format_unformat_error, i);
7983           return -99;
7984         }
7985     }
7986
7987   if (~0 == table_id)
7988     {
7989       errmsg ("missing table-ID");
7990       return -99;
7991     }
7992
7993   /* Construct the API message */
7994   M (IP_TABLE_ADD_DEL, mp);
7995
7996   mp->table_id = ntohl (table_id);
7997   mp->is_ipv6 = is_ipv6;
7998   mp->is_add = is_add;
7999
8000   /* send it... */
8001   S (mp);
8002
8003   /* Wait for a reply... */
8004   W (ret);
8005
8006   return ret;
8007 }
8008
8009 static int
8010 api_ip_add_del_route (vat_main_t * vam)
8011 {
8012   unformat_input_t *i = vam->input;
8013   vl_api_ip_add_del_route_t *mp;
8014   u32 sw_if_index = ~0, vrf_id = 0;
8015   u8 is_ipv6 = 0;
8016   u8 is_local = 0, is_drop = 0;
8017   u8 is_unreach = 0, is_prohibit = 0;
8018   u8 is_add = 1;
8019   u32 next_hop_weight = 1;
8020   u8 is_multipath = 0;
8021   u8 address_set = 0;
8022   u8 address_length_set = 0;
8023   u32 next_hop_table_id = 0;
8024   u32 resolve_attempts = 0;
8025   u32 dst_address_length = 0;
8026   u8 next_hop_set = 0;
8027   ip4_address_t v4_dst_address, v4_next_hop_address;
8028   ip6_address_t v6_dst_address, v6_next_hop_address;
8029   int count = 1;
8030   int j;
8031   f64 before = 0;
8032   u32 random_add_del = 0;
8033   u32 *random_vector = 0;
8034   uword *random_hash;
8035   u32 random_seed = 0xdeaddabe;
8036   u32 classify_table_index = ~0;
8037   u8 is_classify = 0;
8038   u8 resolve_host = 0, resolve_attached = 0;
8039   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8040   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8041   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8042
8043   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8044   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8045   /* Parse args required to build the message */
8046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8047     {
8048       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8049         ;
8050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8051         ;
8052       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8053         {
8054           address_set = 1;
8055           is_ipv6 = 0;
8056         }
8057       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8058         {
8059           address_set = 1;
8060           is_ipv6 = 1;
8061         }
8062       else if (unformat (i, "/%d", &dst_address_length))
8063         {
8064           address_length_set = 1;
8065         }
8066
8067       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8068                                          &v4_next_hop_address))
8069         {
8070           next_hop_set = 1;
8071         }
8072       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8073                                          &v6_next_hop_address))
8074         {
8075           next_hop_set = 1;
8076         }
8077       else
8078         if (unformat
8079             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8080         {
8081           next_hop_set = 1;
8082         }
8083       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8084         {
8085           next_hop_set = 1;
8086         }
8087       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8088         ;
8089       else if (unformat (i, "weight %d", &next_hop_weight))
8090         ;
8091       else if (unformat (i, "drop"))
8092         {
8093           is_drop = 1;
8094         }
8095       else if (unformat (i, "null-send-unreach"))
8096         {
8097           is_unreach = 1;
8098         }
8099       else if (unformat (i, "null-send-prohibit"))
8100         {
8101           is_prohibit = 1;
8102         }
8103       else if (unformat (i, "local"))
8104         {
8105           is_local = 1;
8106         }
8107       else if (unformat (i, "classify %d", &classify_table_index))
8108         {
8109           is_classify = 1;
8110         }
8111       else if (unformat (i, "del"))
8112         is_add = 0;
8113       else if (unformat (i, "add"))
8114         is_add = 1;
8115       else if (unformat (i, "resolve-via-host"))
8116         resolve_host = 1;
8117       else if (unformat (i, "resolve-via-attached"))
8118         resolve_attached = 1;
8119       else if (unformat (i, "multipath"))
8120         is_multipath = 1;
8121       else if (unformat (i, "vrf %d", &vrf_id))
8122         ;
8123       else if (unformat (i, "count %d", &count))
8124         ;
8125       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8126         ;
8127       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8128         ;
8129       else if (unformat (i, "out-label %d", &next_hop_out_label))
8130         {
8131           vl_api_fib_mpls_label_t fib_label = {
8132             .label = ntohl (next_hop_out_label),
8133             .ttl = 64,
8134             .exp = 0,
8135           };
8136           vec_add1 (next_hop_out_label_stack, fib_label);
8137         }
8138       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8139         ;
8140       else if (unformat (i, "random"))
8141         random_add_del = 1;
8142       else if (unformat (i, "seed %d", &random_seed))
8143         ;
8144       else
8145         {
8146           clib_warning ("parse error '%U'", format_unformat_error, i);
8147           return -99;
8148         }
8149     }
8150
8151   if (!next_hop_set && !is_drop && !is_local &&
8152       !is_classify && !is_unreach && !is_prohibit &&
8153       MPLS_LABEL_INVALID == next_hop_via_label)
8154     {
8155       errmsg
8156         ("next hop / local / drop / unreach / prohibit / classify not set");
8157       return -99;
8158     }
8159
8160   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8161     {
8162       errmsg ("next hop and next-hop via label set");
8163       return -99;
8164     }
8165   if (address_set == 0)
8166     {
8167       errmsg ("missing addresses");
8168       return -99;
8169     }
8170
8171   if (address_length_set == 0)
8172     {
8173       errmsg ("missing address length");
8174       return -99;
8175     }
8176
8177   /* Generate a pile of unique, random routes */
8178   if (random_add_del)
8179     {
8180       u32 this_random_address;
8181       random_hash = hash_create (count, sizeof (uword));
8182
8183       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8184       for (j = 0; j <= count; j++)
8185         {
8186           do
8187             {
8188               this_random_address = random_u32 (&random_seed);
8189               this_random_address =
8190                 clib_host_to_net_u32 (this_random_address);
8191             }
8192           while (hash_get (random_hash, this_random_address));
8193           vec_add1 (random_vector, this_random_address);
8194           hash_set (random_hash, this_random_address, 1);
8195         }
8196       hash_free (random_hash);
8197       v4_dst_address.as_u32 = random_vector[0];
8198     }
8199
8200   if (count > 1)
8201     {
8202       /* Turn on async mode */
8203       vam->async_mode = 1;
8204       vam->async_errors = 0;
8205       before = vat_time_now (vam);
8206     }
8207
8208   for (j = 0; j < count; j++)
8209     {
8210       /* Construct the API message */
8211       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8212           vec_len (next_hop_out_label_stack));
8213
8214       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8215       mp->table_id = ntohl (vrf_id);
8216
8217       mp->is_add = is_add;
8218       mp->is_drop = is_drop;
8219       mp->is_unreach = is_unreach;
8220       mp->is_prohibit = is_prohibit;
8221       mp->is_ipv6 = is_ipv6;
8222       mp->is_local = is_local;
8223       mp->is_classify = is_classify;
8224       mp->is_multipath = is_multipath;
8225       mp->is_resolve_host = resolve_host;
8226       mp->is_resolve_attached = resolve_attached;
8227       mp->next_hop_weight = next_hop_weight;
8228       mp->next_hop_preference = 0;
8229       mp->dst_address_length = dst_address_length;
8230       mp->next_hop_table_id = ntohl (next_hop_table_id);
8231       mp->classify_table_index = ntohl (classify_table_index);
8232       mp->next_hop_via_label = ntohl (next_hop_via_label);
8233       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8234       if (0 != mp->next_hop_n_out_labels)
8235         {
8236           memcpy (mp->next_hop_out_label_stack,
8237                   next_hop_out_label_stack,
8238                   (vec_len (next_hop_out_label_stack) *
8239                    sizeof (vl_api_fib_mpls_label_t)));
8240           vec_free (next_hop_out_label_stack);
8241         }
8242
8243       if (is_ipv6)
8244         {
8245           clib_memcpy (mp->dst_address, &v6_dst_address,
8246                        sizeof (v6_dst_address));
8247           if (next_hop_set)
8248             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8249                          sizeof (v6_next_hop_address));
8250           increment_v6_address (&v6_dst_address);
8251         }
8252       else
8253         {
8254           clib_memcpy (mp->dst_address, &v4_dst_address,
8255                        sizeof (v4_dst_address));
8256           if (next_hop_set)
8257             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8258                          sizeof (v4_next_hop_address));
8259           if (random_add_del)
8260             v4_dst_address.as_u32 = random_vector[j + 1];
8261           else
8262             increment_v4_address (&v4_dst_address);
8263         }
8264       /* send it... */
8265       S (mp);
8266       /* If we receive SIGTERM, stop now... */
8267       if (vam->do_exit)
8268         break;
8269     }
8270
8271   /* When testing multiple add/del ops, use a control-ping to sync */
8272   if (count > 1)
8273     {
8274       vl_api_control_ping_t *mp_ping;
8275       f64 after;
8276       f64 timeout;
8277
8278       /* Shut off async mode */
8279       vam->async_mode = 0;
8280
8281       MPING (CONTROL_PING, mp_ping);
8282       S (mp_ping);
8283
8284       timeout = vat_time_now (vam) + 1.0;
8285       while (vat_time_now (vam) < timeout)
8286         if (vam->result_ready == 1)
8287           goto out;
8288       vam->retval = -99;
8289
8290     out:
8291       if (vam->retval == -99)
8292         errmsg ("timeout");
8293
8294       if (vam->async_errors > 0)
8295         {
8296           errmsg ("%d asynchronous errors", vam->async_errors);
8297           vam->retval = -98;
8298         }
8299       vam->async_errors = 0;
8300       after = vat_time_now (vam);
8301
8302       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8303       if (j > 0)
8304         count = j;
8305
8306       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8307              count, after - before, count / (after - before));
8308     }
8309   else
8310     {
8311       int ret;
8312
8313       /* Wait for a reply... */
8314       W (ret);
8315       return ret;
8316     }
8317
8318   /* Return the good/bad news */
8319   return (vam->retval);
8320 }
8321
8322 static int
8323 api_ip_mroute_add_del (vat_main_t * vam)
8324 {
8325   unformat_input_t *i = vam->input;
8326   vl_api_ip_mroute_add_del_t *mp;
8327   u32 sw_if_index = ~0, vrf_id = 0;
8328   u8 is_ipv6 = 0;
8329   u8 is_local = 0;
8330   u8 is_add = 1;
8331   u8 address_set = 0;
8332   u32 grp_address_length = 0;
8333   ip4_address_t v4_grp_address, v4_src_address;
8334   ip6_address_t v6_grp_address, v6_src_address;
8335   mfib_itf_flags_t iflags = 0;
8336   mfib_entry_flags_t eflags = 0;
8337   int ret;
8338
8339   /* Parse args required to build the message */
8340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8341     {
8342       if (unformat (i, "sw_if_index %d", &sw_if_index))
8343         ;
8344       else if (unformat (i, "%U %U",
8345                          unformat_ip4_address, &v4_src_address,
8346                          unformat_ip4_address, &v4_grp_address))
8347         {
8348           grp_address_length = 64;
8349           address_set = 1;
8350           is_ipv6 = 0;
8351         }
8352       else if (unformat (i, "%U %U",
8353                          unformat_ip6_address, &v6_src_address,
8354                          unformat_ip6_address, &v6_grp_address))
8355         {
8356           grp_address_length = 256;
8357           address_set = 1;
8358           is_ipv6 = 1;
8359         }
8360       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8361         {
8362           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8363           grp_address_length = 32;
8364           address_set = 1;
8365           is_ipv6 = 0;
8366         }
8367       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8368         {
8369           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8370           grp_address_length = 128;
8371           address_set = 1;
8372           is_ipv6 = 1;
8373         }
8374       else if (unformat (i, "/%d", &grp_address_length))
8375         ;
8376       else if (unformat (i, "local"))
8377         {
8378           is_local = 1;
8379         }
8380       else if (unformat (i, "del"))
8381         is_add = 0;
8382       else if (unformat (i, "add"))
8383         is_add = 1;
8384       else if (unformat (i, "vrf %d", &vrf_id))
8385         ;
8386       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8387         ;
8388       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8389         ;
8390       else
8391         {
8392           clib_warning ("parse error '%U'", format_unformat_error, i);
8393           return -99;
8394         }
8395     }
8396
8397   if (address_set == 0)
8398     {
8399       errmsg ("missing addresses\n");
8400       return -99;
8401     }
8402
8403   /* Construct the API message */
8404   M (IP_MROUTE_ADD_DEL, mp);
8405
8406   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8407   mp->table_id = ntohl (vrf_id);
8408
8409   mp->is_add = is_add;
8410   mp->is_ipv6 = is_ipv6;
8411   mp->is_local = is_local;
8412   mp->itf_flags = ntohl (iflags);
8413   mp->entry_flags = ntohl (eflags);
8414   mp->grp_address_length = grp_address_length;
8415   mp->grp_address_length = ntohs (mp->grp_address_length);
8416
8417   if (is_ipv6)
8418     {
8419       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8420       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8421     }
8422   else
8423     {
8424       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8425       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8426
8427     }
8428
8429   /* send it... */
8430   S (mp);
8431   /* Wait for a reply... */
8432   W (ret);
8433   return ret;
8434 }
8435
8436 static int
8437 api_mpls_table_add_del (vat_main_t * vam)
8438 {
8439   unformat_input_t *i = vam->input;
8440   vl_api_mpls_table_add_del_t *mp;
8441   u32 table_id = ~0;
8442   u8 is_add = 1;
8443   int ret = 0;
8444
8445   /* Parse args required to build the message */
8446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8447     {
8448       if (unformat (i, "table %d", &table_id))
8449         ;
8450       else if (unformat (i, "del"))
8451         is_add = 0;
8452       else if (unformat (i, "add"))
8453         is_add = 1;
8454       else
8455         {
8456           clib_warning ("parse error '%U'", format_unformat_error, i);
8457           return -99;
8458         }
8459     }
8460
8461   if (~0 == table_id)
8462     {
8463       errmsg ("missing table-ID");
8464       return -99;
8465     }
8466
8467   /* Construct the API message */
8468   M (MPLS_TABLE_ADD_DEL, mp);
8469
8470   mp->mt_table_id = ntohl (table_id);
8471   mp->mt_is_add = is_add;
8472
8473   /* send it... */
8474   S (mp);
8475
8476   /* Wait for a reply... */
8477   W (ret);
8478
8479   return ret;
8480 }
8481
8482 static int
8483 api_mpls_route_add_del (vat_main_t * vam)
8484 {
8485   unformat_input_t *i = vam->input;
8486   vl_api_mpls_route_add_del_t *mp;
8487   u32 sw_if_index = ~0, table_id = 0;
8488   u8 is_add = 1;
8489   u32 next_hop_weight = 1;
8490   u8 is_multipath = 0;
8491   u32 next_hop_table_id = 0;
8492   u8 next_hop_set = 0;
8493   ip4_address_t v4_next_hop_address = {
8494     .as_u32 = 0,
8495   };
8496   ip6_address_t v6_next_hop_address = { {0} };
8497   int count = 1;
8498   int j;
8499   f64 before = 0;
8500   u32 classify_table_index = ~0;
8501   u8 is_classify = 0;
8502   u8 resolve_host = 0, resolve_attached = 0;
8503   u8 is_interface_rx = 0;
8504   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8505   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8506   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8507   mpls_label_t local_label = MPLS_LABEL_INVALID;
8508   u8 is_eos = 0;
8509   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8510
8511   /* Parse args required to build the message */
8512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8513     {
8514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8515         ;
8516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8517         ;
8518       else if (unformat (i, "%d", &local_label))
8519         ;
8520       else if (unformat (i, "eos"))
8521         is_eos = 1;
8522       else if (unformat (i, "non-eos"))
8523         is_eos = 0;
8524       else if (unformat (i, "via %U", unformat_ip4_address,
8525                          &v4_next_hop_address))
8526         {
8527           next_hop_set = 1;
8528           next_hop_proto = DPO_PROTO_IP4;
8529         }
8530       else if (unformat (i, "via %U", unformat_ip6_address,
8531                          &v6_next_hop_address))
8532         {
8533           next_hop_set = 1;
8534           next_hop_proto = DPO_PROTO_IP6;
8535         }
8536       else if (unformat (i, "weight %d", &next_hop_weight))
8537         ;
8538       else if (unformat (i, "classify %d", &classify_table_index))
8539         {
8540           is_classify = 1;
8541         }
8542       else if (unformat (i, "del"))
8543         is_add = 0;
8544       else if (unformat (i, "add"))
8545         is_add = 1;
8546       else if (unformat (i, "resolve-via-host"))
8547         resolve_host = 1;
8548       else if (unformat (i, "resolve-via-attached"))
8549         resolve_attached = 1;
8550       else if (unformat (i, "multipath"))
8551         is_multipath = 1;
8552       else if (unformat (i, "count %d", &count))
8553         ;
8554       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8555         {
8556           next_hop_set = 1;
8557           next_hop_proto = DPO_PROTO_IP4;
8558         }
8559       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8560         {
8561           next_hop_set = 1;
8562           next_hop_proto = DPO_PROTO_IP6;
8563         }
8564       else
8565         if (unformat
8566             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8567              &sw_if_index))
8568         {
8569           next_hop_set = 1;
8570           next_hop_proto = DPO_PROTO_ETHERNET;
8571           is_interface_rx = 1;
8572         }
8573       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8574         {
8575           next_hop_set = 1;
8576           next_hop_proto = DPO_PROTO_ETHERNET;
8577           is_interface_rx = 1;
8578         }
8579       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8580         next_hop_set = 1;
8581       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8582         next_hop_set = 1;
8583       else if (unformat (i, "out-label %d", &next_hop_out_label))
8584         {
8585           vl_api_fib_mpls_label_t fib_label = {
8586             .label = ntohl (next_hop_out_label),
8587             .ttl = 64,
8588             .exp = 0,
8589           };
8590           vec_add1 (next_hop_out_label_stack, fib_label);
8591         }
8592       else
8593         {
8594           clib_warning ("parse error '%U'", format_unformat_error, i);
8595           return -99;
8596         }
8597     }
8598
8599   if (!next_hop_set && !is_classify)
8600     {
8601       errmsg ("next hop / classify not set");
8602       return -99;
8603     }
8604
8605   if (MPLS_LABEL_INVALID == local_label)
8606     {
8607       errmsg ("missing label");
8608       return -99;
8609     }
8610
8611   if (count > 1)
8612     {
8613       /* Turn on async mode */
8614       vam->async_mode = 1;
8615       vam->async_errors = 0;
8616       before = vat_time_now (vam);
8617     }
8618
8619   for (j = 0; j < count; j++)
8620     {
8621       /* Construct the API message */
8622       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8623           vec_len (next_hop_out_label_stack));
8624
8625       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8626       mp->mr_table_id = ntohl (table_id);
8627
8628       mp->mr_is_add = is_add;
8629       mp->mr_next_hop_proto = next_hop_proto;
8630       mp->mr_is_classify = is_classify;
8631       mp->mr_is_multipath = is_multipath;
8632       mp->mr_is_resolve_host = resolve_host;
8633       mp->mr_is_resolve_attached = resolve_attached;
8634       mp->mr_is_interface_rx = is_interface_rx;
8635       mp->mr_next_hop_weight = next_hop_weight;
8636       mp->mr_next_hop_preference = 0;
8637       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8638       mp->mr_classify_table_index = ntohl (classify_table_index);
8639       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8640       mp->mr_label = ntohl (local_label);
8641       mp->mr_eos = is_eos;
8642
8643       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8644       if (0 != mp->mr_next_hop_n_out_labels)
8645         {
8646           memcpy (mp->mr_next_hop_out_label_stack,
8647                   next_hop_out_label_stack,
8648                   vec_len (next_hop_out_label_stack) *
8649                   sizeof (vl_api_fib_mpls_label_t));
8650           vec_free (next_hop_out_label_stack);
8651         }
8652
8653       if (next_hop_set)
8654         {
8655           if (DPO_PROTO_IP4 == next_hop_proto)
8656             {
8657               clib_memcpy (mp->mr_next_hop,
8658                            &v4_next_hop_address,
8659                            sizeof (v4_next_hop_address));
8660             }
8661           else if (DPO_PROTO_IP6 == next_hop_proto)
8662
8663             {
8664               clib_memcpy (mp->mr_next_hop,
8665                            &v6_next_hop_address,
8666                            sizeof (v6_next_hop_address));
8667             }
8668         }
8669       local_label++;
8670
8671       /* send it... */
8672       S (mp);
8673       /* If we receive SIGTERM, stop now... */
8674       if (vam->do_exit)
8675         break;
8676     }
8677
8678   /* When testing multiple add/del ops, use a control-ping to sync */
8679   if (count > 1)
8680     {
8681       vl_api_control_ping_t *mp_ping;
8682       f64 after;
8683       f64 timeout;
8684
8685       /* Shut off async mode */
8686       vam->async_mode = 0;
8687
8688       MPING (CONTROL_PING, mp_ping);
8689       S (mp_ping);
8690
8691       timeout = vat_time_now (vam) + 1.0;
8692       while (vat_time_now (vam) < timeout)
8693         if (vam->result_ready == 1)
8694           goto out;
8695       vam->retval = -99;
8696
8697     out:
8698       if (vam->retval == -99)
8699         errmsg ("timeout");
8700
8701       if (vam->async_errors > 0)
8702         {
8703           errmsg ("%d asynchronous errors", vam->async_errors);
8704           vam->retval = -98;
8705         }
8706       vam->async_errors = 0;
8707       after = vat_time_now (vam);
8708
8709       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8710       if (j > 0)
8711         count = j;
8712
8713       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8714              count, after - before, count / (after - before));
8715     }
8716   else
8717     {
8718       int ret;
8719
8720       /* Wait for a reply... */
8721       W (ret);
8722       return ret;
8723     }
8724
8725   /* Return the good/bad news */
8726   return (vam->retval);
8727 }
8728
8729 static int
8730 api_mpls_ip_bind_unbind (vat_main_t * vam)
8731 {
8732   unformat_input_t *i = vam->input;
8733   vl_api_mpls_ip_bind_unbind_t *mp;
8734   u32 ip_table_id = 0;
8735   u8 is_bind = 1;
8736   u8 is_ip4 = 1;
8737   ip4_address_t v4_address;
8738   ip6_address_t v6_address;
8739   u32 address_length;
8740   u8 address_set = 0;
8741   mpls_label_t local_label = MPLS_LABEL_INVALID;
8742   int ret;
8743
8744   /* Parse args required to build the message */
8745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8746     {
8747       if (unformat (i, "%U/%d", unformat_ip4_address,
8748                     &v4_address, &address_length))
8749         {
8750           is_ip4 = 1;
8751           address_set = 1;
8752         }
8753       else if (unformat (i, "%U/%d", unformat_ip6_address,
8754                          &v6_address, &address_length))
8755         {
8756           is_ip4 = 0;
8757           address_set = 1;
8758         }
8759       else if (unformat (i, "%d", &local_label))
8760         ;
8761       else if (unformat (i, "table-id %d", &ip_table_id))
8762         ;
8763       else if (unformat (i, "unbind"))
8764         is_bind = 0;
8765       else if (unformat (i, "bind"))
8766         is_bind = 1;
8767       else
8768         {
8769           clib_warning ("parse error '%U'", format_unformat_error, i);
8770           return -99;
8771         }
8772     }
8773
8774   if (!address_set)
8775     {
8776       errmsg ("IP address not set");
8777       return -99;
8778     }
8779
8780   if (MPLS_LABEL_INVALID == local_label)
8781     {
8782       errmsg ("missing label");
8783       return -99;
8784     }
8785
8786   /* Construct the API message */
8787   M (MPLS_IP_BIND_UNBIND, mp);
8788
8789   mp->mb_is_bind = is_bind;
8790   mp->mb_is_ip4 = is_ip4;
8791   mp->mb_ip_table_id = ntohl (ip_table_id);
8792   mp->mb_mpls_table_id = 0;
8793   mp->mb_label = ntohl (local_label);
8794   mp->mb_address_length = address_length;
8795
8796   if (is_ip4)
8797     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8798   else
8799     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8800
8801   /* send it... */
8802   S (mp);
8803
8804   /* Wait for a reply... */
8805   W (ret);
8806   return ret;
8807 }
8808
8809 static int
8810 api_sr_mpls_policy_add (vat_main_t * vam)
8811 {
8812   unformat_input_t *i = vam->input;
8813   vl_api_sr_mpls_policy_add_t *mp;
8814   u32 bsid = 0;
8815   u32 weight = 1;
8816   u8 type = 0;
8817   u8 n_segments = 0;
8818   u32 sid;
8819   u32 *segments = NULL;
8820   int ret;
8821
8822   /* Parse args required to build the message */
8823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8824     {
8825       if (unformat (i, "bsid %d", &bsid))
8826         ;
8827       else if (unformat (i, "weight %d", &weight))
8828         ;
8829       else if (unformat (i, "spray"))
8830         type = 1;
8831       else if (unformat (i, "next %d", &sid))
8832         {
8833           n_segments += 1;
8834           vec_add1 (segments, htonl (sid));
8835         }
8836       else
8837         {
8838           clib_warning ("parse error '%U'", format_unformat_error, i);
8839           return -99;
8840         }
8841     }
8842
8843   if (bsid == 0)
8844     {
8845       errmsg ("bsid not set");
8846       return -99;
8847     }
8848
8849   if (n_segments == 0)
8850     {
8851       errmsg ("no sid in segment stack");
8852       return -99;
8853     }
8854
8855   /* Construct the API message */
8856   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8857
8858   mp->bsid = htonl (bsid);
8859   mp->weight = htonl (weight);
8860   mp->type = type;
8861   mp->n_segments = n_segments;
8862   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8863   vec_free (segments);
8864
8865   /* send it... */
8866   S (mp);
8867
8868   /* Wait for a reply... */
8869   W (ret);
8870   return ret;
8871 }
8872
8873 static int
8874 api_sr_mpls_policy_del (vat_main_t * vam)
8875 {
8876   unformat_input_t *i = vam->input;
8877   vl_api_sr_mpls_policy_del_t *mp;
8878   u32 bsid = 0;
8879   int ret;
8880
8881   /* Parse args required to build the message */
8882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8883     {
8884       if (unformat (i, "bsid %d", &bsid))
8885         ;
8886       else
8887         {
8888           clib_warning ("parse error '%U'", format_unformat_error, i);
8889           return -99;
8890         }
8891     }
8892
8893   if (bsid == 0)
8894     {
8895       errmsg ("bsid not set");
8896       return -99;
8897     }
8898
8899   /* Construct the API message */
8900   M (SR_MPLS_POLICY_DEL, mp);
8901
8902   mp->bsid = htonl (bsid);
8903
8904   /* send it... */
8905   S (mp);
8906
8907   /* Wait for a reply... */
8908   W (ret);
8909   return ret;
8910 }
8911
8912 static int
8913 api_bier_table_add_del (vat_main_t * vam)
8914 {
8915   unformat_input_t *i = vam->input;
8916   vl_api_bier_table_add_del_t *mp;
8917   u8 is_add = 1;
8918   u32 set = 0, sub_domain = 0, hdr_len = 3;
8919   mpls_label_t local_label = MPLS_LABEL_INVALID;
8920   int ret;
8921
8922   /* Parse args required to build the message */
8923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8924     {
8925       if (unformat (i, "sub-domain %d", &sub_domain))
8926         ;
8927       else if (unformat (i, "set %d", &set))
8928         ;
8929       else if (unformat (i, "label %d", &local_label))
8930         ;
8931       else if (unformat (i, "hdr-len %d", &hdr_len))
8932         ;
8933       else if (unformat (i, "add"))
8934         is_add = 1;
8935       else if (unformat (i, "del"))
8936         is_add = 0;
8937       else
8938         {
8939           clib_warning ("parse error '%U'", format_unformat_error, i);
8940           return -99;
8941         }
8942     }
8943
8944   if (MPLS_LABEL_INVALID == local_label)
8945     {
8946       errmsg ("missing label\n");
8947       return -99;
8948     }
8949
8950   /* Construct the API message */
8951   M (BIER_TABLE_ADD_DEL, mp);
8952
8953   mp->bt_is_add = is_add;
8954   mp->bt_label = ntohl (local_label);
8955   mp->bt_tbl_id.bt_set = set;
8956   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8957   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8958
8959   /* send it... */
8960   S (mp);
8961
8962   /* Wait for a reply... */
8963   W (ret);
8964
8965   return (ret);
8966 }
8967
8968 static int
8969 api_bier_route_add_del (vat_main_t * vam)
8970 {
8971   unformat_input_t *i = vam->input;
8972   vl_api_bier_route_add_del_t *mp;
8973   u8 is_add = 1;
8974   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8975   ip4_address_t v4_next_hop_address;
8976   ip6_address_t v6_next_hop_address;
8977   u8 next_hop_set = 0;
8978   u8 next_hop_proto_is_ip4 = 1;
8979   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8980   int ret;
8981
8982   /* Parse args required to build the message */
8983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8984     {
8985       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8986         {
8987           next_hop_proto_is_ip4 = 1;
8988           next_hop_set = 1;
8989         }
8990       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8991         {
8992           next_hop_proto_is_ip4 = 0;
8993           next_hop_set = 1;
8994         }
8995       if (unformat (i, "sub-domain %d", &sub_domain))
8996         ;
8997       else if (unformat (i, "set %d", &set))
8998         ;
8999       else if (unformat (i, "hdr-len %d", &hdr_len))
9000         ;
9001       else if (unformat (i, "bp %d", &bp))
9002         ;
9003       else if (unformat (i, "add"))
9004         is_add = 1;
9005       else if (unformat (i, "del"))
9006         is_add = 0;
9007       else if (unformat (i, "out-label %d", &next_hop_out_label))
9008         ;
9009       else
9010         {
9011           clib_warning ("parse error '%U'", format_unformat_error, i);
9012           return -99;
9013         }
9014     }
9015
9016   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9017     {
9018       errmsg ("next hop / label set\n");
9019       return -99;
9020     }
9021   if (0 == bp)
9022     {
9023       errmsg ("bit=position not set\n");
9024       return -99;
9025     }
9026
9027   /* Construct the API message */
9028   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9029
9030   mp->br_is_add = is_add;
9031   mp->br_tbl_id.bt_set = set;
9032   mp->br_tbl_id.bt_sub_domain = sub_domain;
9033   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9034   mp->br_bp = ntohs (bp);
9035   mp->br_n_paths = 1;
9036   mp->br_paths[0].n_labels = 1;
9037   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9038   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9039
9040   if (next_hop_proto_is_ip4)
9041     {
9042       clib_memcpy (mp->br_paths[0].next_hop,
9043                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9044     }
9045   else
9046     {
9047       clib_memcpy (mp->br_paths[0].next_hop,
9048                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9049     }
9050
9051   /* send it... */
9052   S (mp);
9053
9054   /* Wait for a reply... */
9055   W (ret);
9056
9057   return (ret);
9058 }
9059
9060 static int
9061 api_proxy_arp_add_del (vat_main_t * vam)
9062 {
9063   unformat_input_t *i = vam->input;
9064   vl_api_proxy_arp_add_del_t *mp;
9065   u32 vrf_id = 0;
9066   u8 is_add = 1;
9067   vl_api_ip4_address_t lo, hi;
9068   u8 range_set = 0;
9069   int ret;
9070
9071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9072     {
9073       if (unformat (i, "vrf %d", &vrf_id))
9074         ;
9075       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9076                          unformat_vl_api_ip4_address, &hi))
9077         range_set = 1;
9078       else if (unformat (i, "del"))
9079         is_add = 0;
9080       else
9081         {
9082           clib_warning ("parse error '%U'", format_unformat_error, i);
9083           return -99;
9084         }
9085     }
9086
9087   if (range_set == 0)
9088     {
9089       errmsg ("address range not set");
9090       return -99;
9091     }
9092
9093   M (PROXY_ARP_ADD_DEL, mp);
9094
9095   mp->proxy.table_id = ntohl (vrf_id);
9096   mp->is_add = is_add;
9097   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9098   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9099
9100   S (mp);
9101   W (ret);
9102   return ret;
9103 }
9104
9105 static int
9106 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9107 {
9108   unformat_input_t *i = vam->input;
9109   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9110   u32 sw_if_index;
9111   u8 enable = 1;
9112   u8 sw_if_index_set = 0;
9113   int ret;
9114
9115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9118         sw_if_index_set = 1;
9119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9120         sw_if_index_set = 1;
9121       else if (unformat (i, "enable"))
9122         enable = 1;
9123       else if (unformat (i, "disable"))
9124         enable = 0;
9125       else
9126         {
9127           clib_warning ("parse error '%U'", format_unformat_error, i);
9128           return -99;
9129         }
9130     }
9131
9132   if (sw_if_index_set == 0)
9133     {
9134       errmsg ("missing interface name or sw_if_index");
9135       return -99;
9136     }
9137
9138   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9139
9140   mp->sw_if_index = ntohl (sw_if_index);
9141   mp->enable_disable = enable;
9142
9143   S (mp);
9144   W (ret);
9145   return ret;
9146 }
9147
9148 static int
9149 api_mpls_tunnel_add_del (vat_main_t * vam)
9150 {
9151   unformat_input_t *i = vam->input;
9152   vl_api_mpls_tunnel_add_del_t *mp;
9153
9154   u8 is_add = 1;
9155   u8 l2_only = 0;
9156   u32 sw_if_index = ~0;
9157   u32 next_hop_sw_if_index = ~0;
9158   u32 next_hop_proto_is_ip4 = 1;
9159
9160   u32 next_hop_table_id = 0;
9161   ip4_address_t v4_next_hop_address = {
9162     .as_u32 = 0,
9163   };
9164   ip6_address_t v6_next_hop_address = { {0} };
9165   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9166   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9167   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9168   int ret;
9169
9170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9171     {
9172       if (unformat (i, "add"))
9173         is_add = 1;
9174       else
9175         if (unformat
9176             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9177         is_add = 0;
9178       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9179         is_add = 0;
9180       else if (unformat (i, "via %U",
9181                          unformat_ip4_address, &v4_next_hop_address))
9182         {
9183           next_hop_proto_is_ip4 = 1;
9184         }
9185       else if (unformat (i, "via %U",
9186                          unformat_ip6_address, &v6_next_hop_address))
9187         {
9188           next_hop_proto_is_ip4 = 0;
9189         }
9190       else if (unformat (i, "via-label %d", &next_hop_via_label))
9191         ;
9192       else
9193         if (unformat
9194             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9195         ;
9196       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9197         ;
9198       else if (unformat (i, "l2-only"))
9199         l2_only = 1;
9200       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9201         ;
9202       else if (unformat (i, "out-label %d", &next_hop_out_label))
9203         {
9204           vl_api_fib_mpls_label_t fib_label = {
9205             .label = ntohl (next_hop_out_label),
9206             .ttl = 64,
9207             .exp = 0,
9208           };
9209           vec_add1 (next_hop_out_label_stack, fib_label);
9210         }
9211       else
9212         {
9213           clib_warning ("parse error '%U'", format_unformat_error, i);
9214           return -99;
9215         }
9216     }
9217
9218   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9219       vec_len (next_hop_out_label_stack));
9220
9221   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9222   mp->mt_sw_if_index = ntohl (sw_if_index);
9223   mp->mt_is_add = is_add;
9224   mp->mt_l2_only = l2_only;
9225   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9226   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9227   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9228   mp->mt_next_hop_weight = 1;
9229   mp->mt_next_hop_preference = 0;
9230
9231   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9232
9233   if (0 != mp->mt_next_hop_n_out_labels)
9234     {
9235       clib_memcpy (mp->mt_next_hop_out_label_stack,
9236                    next_hop_out_label_stack,
9237                    (vec_len (next_hop_out_label_stack) *
9238                     sizeof (vl_api_fib_mpls_label_t)));
9239       vec_free (next_hop_out_label_stack);
9240     }
9241
9242   if (next_hop_proto_is_ip4)
9243     {
9244       clib_memcpy (mp->mt_next_hop,
9245                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9246     }
9247   else
9248     {
9249       clib_memcpy (mp->mt_next_hop,
9250                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9251     }
9252
9253   S (mp);
9254   W (ret);
9255   return ret;
9256 }
9257
9258 static int
9259 api_sw_interface_set_unnumbered (vat_main_t * vam)
9260 {
9261   unformat_input_t *i = vam->input;
9262   vl_api_sw_interface_set_unnumbered_t *mp;
9263   u32 sw_if_index;
9264   u32 unnum_sw_index = ~0;
9265   u8 is_add = 1;
9266   u8 sw_if_index_set = 0;
9267   int ret;
9268
9269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9270     {
9271       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9272         sw_if_index_set = 1;
9273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9274         sw_if_index_set = 1;
9275       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9276         ;
9277       else if (unformat (i, "del"))
9278         is_add = 0;
9279       else
9280         {
9281           clib_warning ("parse error '%U'", format_unformat_error, i);
9282           return -99;
9283         }
9284     }
9285
9286   if (sw_if_index_set == 0)
9287     {
9288       errmsg ("missing interface name or sw_if_index");
9289       return -99;
9290     }
9291
9292   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9293
9294   mp->sw_if_index = ntohl (sw_if_index);
9295   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9296   mp->is_add = is_add;
9297
9298   S (mp);
9299   W (ret);
9300   return ret;
9301 }
9302
9303 static int
9304 api_ip_neighbor_add_del (vat_main_t * vam)
9305 {
9306   vl_api_mac_address_t mac_address;
9307   unformat_input_t *i = vam->input;
9308   vl_api_ip_neighbor_add_del_t *mp;
9309   vl_api_address_t ip_address;
9310   u32 sw_if_index;
9311   u8 sw_if_index_set = 0;
9312   u8 is_add = 1;
9313   u8 mac_set = 0;
9314   u8 address_set = 0;
9315   int ret;
9316   ip_neighbor_flags_t flags;
9317
9318   flags = IP_NEIGHBOR_FLAG_NONE;
9319   clib_memset (&ip_address, 0, sizeof (ip_address));
9320   clib_memset (&mac_address, 0, sizeof (mac_address));
9321   /* Parse args required to build the message */
9322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9323     {
9324       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9325         {
9326           mac_set = 1;
9327         }
9328       else if (unformat (i, "del"))
9329         is_add = 0;
9330       else
9331         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9332         sw_if_index_set = 1;
9333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9334         sw_if_index_set = 1;
9335       else if (unformat (i, "static"))
9336         flags |= IP_NEIGHBOR_FLAG_STATIC;
9337       else if (unformat (i, "no-fib-entry"))
9338         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9339       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9340         address_set = 1;
9341       else
9342         {
9343           clib_warning ("parse error '%U'", format_unformat_error, i);
9344           return -99;
9345         }
9346     }
9347
9348   if (sw_if_index_set == 0)
9349     {
9350       errmsg ("missing interface name or sw_if_index");
9351       return -99;
9352     }
9353   if (!address_set)
9354     {
9355       errmsg ("no address set");
9356       return -99;
9357     }
9358
9359   /* Construct the API message */
9360   M (IP_NEIGHBOR_ADD_DEL, mp);
9361
9362   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9363   mp->is_add = is_add;
9364   mp->neighbor.flags = htonl (flags);
9365   if (mac_set)
9366     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9367                  sizeof (mac_address));
9368   if (address_set)
9369     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9370
9371   /* send it... */
9372   S (mp);
9373
9374   /* Wait for a reply, return good/bad news  */
9375   W (ret);
9376   return ret;
9377 }
9378
9379 static int
9380 api_create_vlan_subif (vat_main_t * vam)
9381 {
9382   unformat_input_t *i = vam->input;
9383   vl_api_create_vlan_subif_t *mp;
9384   u32 sw_if_index;
9385   u8 sw_if_index_set = 0;
9386   u32 vlan_id;
9387   u8 vlan_id_set = 0;
9388   int ret;
9389
9390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9391     {
9392       if (unformat (i, "sw_if_index %d", &sw_if_index))
9393         sw_if_index_set = 1;
9394       else
9395         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9396         sw_if_index_set = 1;
9397       else if (unformat (i, "vlan %d", &vlan_id))
9398         vlan_id_set = 1;
9399       else
9400         {
9401           clib_warning ("parse error '%U'", format_unformat_error, i);
9402           return -99;
9403         }
9404     }
9405
9406   if (sw_if_index_set == 0)
9407     {
9408       errmsg ("missing interface name or sw_if_index");
9409       return -99;
9410     }
9411
9412   if (vlan_id_set == 0)
9413     {
9414       errmsg ("missing vlan_id");
9415       return -99;
9416     }
9417   M (CREATE_VLAN_SUBIF, mp);
9418
9419   mp->sw_if_index = ntohl (sw_if_index);
9420   mp->vlan_id = ntohl (vlan_id);
9421
9422   S (mp);
9423   W (ret);
9424   return ret;
9425 }
9426
9427 #define foreach_create_subif_bit                \
9428 _(no_tags)                                      \
9429 _(one_tag)                                      \
9430 _(two_tags)                                     \
9431 _(dot1ad)                                       \
9432 _(exact_match)                                  \
9433 _(default_sub)                                  \
9434 _(outer_vlan_id_any)                            \
9435 _(inner_vlan_id_any)
9436
9437 static int
9438 api_create_subif (vat_main_t * vam)
9439 {
9440   unformat_input_t *i = vam->input;
9441   vl_api_create_subif_t *mp;
9442   u32 sw_if_index;
9443   u8 sw_if_index_set = 0;
9444   u32 sub_id;
9445   u8 sub_id_set = 0;
9446   u32 no_tags = 0;
9447   u32 one_tag = 0;
9448   u32 two_tags = 0;
9449   u32 dot1ad = 0;
9450   u32 exact_match = 0;
9451   u32 default_sub = 0;
9452   u32 outer_vlan_id_any = 0;
9453   u32 inner_vlan_id_any = 0;
9454   u32 tmp;
9455   u16 outer_vlan_id = 0;
9456   u16 inner_vlan_id = 0;
9457   int ret;
9458
9459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9460     {
9461       if (unformat (i, "sw_if_index %d", &sw_if_index))
9462         sw_if_index_set = 1;
9463       else
9464         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9465         sw_if_index_set = 1;
9466       else if (unformat (i, "sub_id %d", &sub_id))
9467         sub_id_set = 1;
9468       else if (unformat (i, "outer_vlan_id %d", &tmp))
9469         outer_vlan_id = tmp;
9470       else if (unformat (i, "inner_vlan_id %d", &tmp))
9471         inner_vlan_id = tmp;
9472
9473 #define _(a) else if (unformat (i, #a)) a = 1 ;
9474       foreach_create_subif_bit
9475 #undef _
9476         else
9477         {
9478           clib_warning ("parse error '%U'", format_unformat_error, i);
9479           return -99;
9480         }
9481     }
9482
9483   if (sw_if_index_set == 0)
9484     {
9485       errmsg ("missing interface name or sw_if_index");
9486       return -99;
9487     }
9488
9489   if (sub_id_set == 0)
9490     {
9491       errmsg ("missing sub_id");
9492       return -99;
9493     }
9494   M (CREATE_SUBIF, mp);
9495
9496   mp->sw_if_index = ntohl (sw_if_index);
9497   mp->sub_id = ntohl (sub_id);
9498
9499 #define _(a) mp->a = a;
9500   foreach_create_subif_bit;
9501 #undef _
9502
9503   mp->outer_vlan_id = ntohs (outer_vlan_id);
9504   mp->inner_vlan_id = ntohs (inner_vlan_id);
9505
9506   S (mp);
9507   W (ret);
9508   return ret;
9509 }
9510
9511 static int
9512 api_reset_fib (vat_main_t * vam)
9513 {
9514   unformat_input_t *i = vam->input;
9515   vl_api_reset_fib_t *mp;
9516   u32 vrf_id = 0;
9517   u8 is_ipv6 = 0;
9518   u8 vrf_id_set = 0;
9519
9520   int ret;
9521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9522     {
9523       if (unformat (i, "vrf %d", &vrf_id))
9524         vrf_id_set = 1;
9525       else if (unformat (i, "ipv6"))
9526         is_ipv6 = 1;
9527       else
9528         {
9529           clib_warning ("parse error '%U'", format_unformat_error, i);
9530           return -99;
9531         }
9532     }
9533
9534   if (vrf_id_set == 0)
9535     {
9536       errmsg ("missing vrf id");
9537       return -99;
9538     }
9539
9540   M (RESET_FIB, mp);
9541
9542   mp->vrf_id = ntohl (vrf_id);
9543   mp->is_ipv6 = is_ipv6;
9544
9545   S (mp);
9546   W (ret);
9547   return ret;
9548 }
9549
9550 static int
9551 api_dhcp_proxy_config (vat_main_t * vam)
9552 {
9553   unformat_input_t *i = vam->input;
9554   vl_api_dhcp_proxy_config_t *mp;
9555   u32 rx_vrf_id = 0;
9556   u32 server_vrf_id = 0;
9557   u8 is_add = 1;
9558   u8 v4_address_set = 0;
9559   u8 v6_address_set = 0;
9560   ip4_address_t v4address;
9561   ip6_address_t v6address;
9562   u8 v4_src_address_set = 0;
9563   u8 v6_src_address_set = 0;
9564   ip4_address_t v4srcaddress;
9565   ip6_address_t v6srcaddress;
9566   int ret;
9567
9568   /* Parse args required to build the message */
9569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9570     {
9571       if (unformat (i, "del"))
9572         is_add = 0;
9573       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9574         ;
9575       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9576         ;
9577       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9578         v4_address_set = 1;
9579       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9580         v6_address_set = 1;
9581       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9582         v4_src_address_set = 1;
9583       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9584         v6_src_address_set = 1;
9585       else
9586         break;
9587     }
9588
9589   if (v4_address_set && v6_address_set)
9590     {
9591       errmsg ("both v4 and v6 server addresses set");
9592       return -99;
9593     }
9594   if (!v4_address_set && !v6_address_set)
9595     {
9596       errmsg ("no server addresses set");
9597       return -99;
9598     }
9599
9600   if (v4_src_address_set && v6_src_address_set)
9601     {
9602       errmsg ("both v4 and v6  src addresses set");
9603       return -99;
9604     }
9605   if (!v4_src_address_set && !v6_src_address_set)
9606     {
9607       errmsg ("no src addresses set");
9608       return -99;
9609     }
9610
9611   if (!(v4_src_address_set && v4_address_set) &&
9612       !(v6_src_address_set && v6_address_set))
9613     {
9614       errmsg ("no matching server and src addresses set");
9615       return -99;
9616     }
9617
9618   /* Construct the API message */
9619   M (DHCP_PROXY_CONFIG, mp);
9620
9621   mp->is_add = is_add;
9622   mp->rx_vrf_id = ntohl (rx_vrf_id);
9623   mp->server_vrf_id = ntohl (server_vrf_id);
9624   if (v6_address_set)
9625     {
9626       mp->is_ipv6 = 1;
9627       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9628       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9629     }
9630   else
9631     {
9632       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9633       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9634     }
9635
9636   /* send it... */
9637   S (mp);
9638
9639   /* Wait for a reply, return good/bad news  */
9640   W (ret);
9641   return ret;
9642 }
9643
9644 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9645 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9646
9647 static void
9648 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9649 {
9650   vat_main_t *vam = &vat_main;
9651   u32 i, count = mp->count;
9652   vl_api_dhcp_server_t *s;
9653
9654   if (mp->is_ipv6)
9655     print (vam->ofp,
9656            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9657            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9658            ntohl (mp->rx_vrf_id),
9659            format_ip6_address, mp->dhcp_src_address,
9660            mp->vss_type, mp->vss_vpn_ascii_id,
9661            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9662   else
9663     print (vam->ofp,
9664            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9665            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9666            ntohl (mp->rx_vrf_id),
9667            format_ip4_address, mp->dhcp_src_address,
9668            mp->vss_type, mp->vss_vpn_ascii_id,
9669            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9670
9671   for (i = 0; i < count; i++)
9672     {
9673       s = &mp->servers[i];
9674
9675       if (mp->is_ipv6)
9676         print (vam->ofp,
9677                " Server Table-ID %d, Server Address %U",
9678                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9679       else
9680         print (vam->ofp,
9681                " Server Table-ID %d, Server Address %U",
9682                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9683     }
9684 }
9685
9686 static void vl_api_dhcp_proxy_details_t_handler_json
9687   (vl_api_dhcp_proxy_details_t * mp)
9688 {
9689   vat_main_t *vam = &vat_main;
9690   vat_json_node_t *node = NULL;
9691   u32 i, count = mp->count;
9692   struct in_addr ip4;
9693   struct in6_addr ip6;
9694   vl_api_dhcp_server_t *s;
9695
9696   if (VAT_JSON_ARRAY != vam->json_tree.type)
9697     {
9698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9699       vat_json_init_array (&vam->json_tree);
9700     }
9701   node = vat_json_array_add (&vam->json_tree);
9702
9703   vat_json_init_object (node);
9704   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9705   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9706                              sizeof (mp->vss_type));
9707   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9708                                    mp->vss_vpn_ascii_id);
9709   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9710   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9711
9712   if (mp->is_ipv6)
9713     {
9714       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9715       vat_json_object_add_ip6 (node, "src_address", ip6);
9716     }
9717   else
9718     {
9719       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9720       vat_json_object_add_ip4 (node, "src_address", ip4);
9721     }
9722
9723   for (i = 0; i < count; i++)
9724     {
9725       s = &mp->servers[i];
9726
9727       vat_json_object_add_uint (node, "server-table-id",
9728                                 ntohl (s->server_vrf_id));
9729
9730       if (mp->is_ipv6)
9731         {
9732           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9733           vat_json_object_add_ip4 (node, "src_address", ip4);
9734         }
9735       else
9736         {
9737           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9738           vat_json_object_add_ip6 (node, "server_address", ip6);
9739         }
9740     }
9741 }
9742
9743 static int
9744 api_dhcp_proxy_dump (vat_main_t * vam)
9745 {
9746   unformat_input_t *i = vam->input;
9747   vl_api_control_ping_t *mp_ping;
9748   vl_api_dhcp_proxy_dump_t *mp;
9749   u8 is_ipv6 = 0;
9750   int ret;
9751
9752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9753     {
9754       if (unformat (i, "ipv6"))
9755         is_ipv6 = 1;
9756       else
9757         {
9758           clib_warning ("parse error '%U'", format_unformat_error, i);
9759           return -99;
9760         }
9761     }
9762
9763   M (DHCP_PROXY_DUMP, mp);
9764
9765   mp->is_ip6 = is_ipv6;
9766   S (mp);
9767
9768   /* Use a control ping for synchronization */
9769   MPING (CONTROL_PING, mp_ping);
9770   S (mp_ping);
9771
9772   W (ret);
9773   return ret;
9774 }
9775
9776 static int
9777 api_dhcp_proxy_set_vss (vat_main_t * vam)
9778 {
9779   unformat_input_t *i = vam->input;
9780   vl_api_dhcp_proxy_set_vss_t *mp;
9781   u8 is_ipv6 = 0;
9782   u8 is_add = 1;
9783   u32 tbl_id = ~0;
9784   u8 vss_type = VSS_TYPE_DEFAULT;
9785   u8 *vpn_ascii_id = 0;
9786   u32 oui = 0;
9787   u32 fib_id = 0;
9788   int ret;
9789
9790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9791     {
9792       if (unformat (i, "tbl_id %d", &tbl_id))
9793         ;
9794       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9795         vss_type = VSS_TYPE_ASCII;
9796       else if (unformat (i, "fib_id %d", &fib_id))
9797         vss_type = VSS_TYPE_VPN_ID;
9798       else if (unformat (i, "oui %d", &oui))
9799         vss_type = VSS_TYPE_VPN_ID;
9800       else if (unformat (i, "ipv6"))
9801         is_ipv6 = 1;
9802       else if (unformat (i, "del"))
9803         is_add = 0;
9804       else
9805         break;
9806     }
9807
9808   if (tbl_id == ~0)
9809     {
9810       errmsg ("missing tbl_id ");
9811       vec_free (vpn_ascii_id);
9812       return -99;
9813     }
9814
9815   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9816     {
9817       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9818       vec_free (vpn_ascii_id);
9819       return -99;
9820     }
9821
9822   M (DHCP_PROXY_SET_VSS, mp);
9823   mp->tbl_id = ntohl (tbl_id);
9824   mp->vss_type = vss_type;
9825   if (vpn_ascii_id)
9826     {
9827       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9828       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9829     }
9830   mp->vpn_index = ntohl (fib_id);
9831   mp->oui = ntohl (oui);
9832   mp->is_ipv6 = is_ipv6;
9833   mp->is_add = is_add;
9834
9835   S (mp);
9836   W (ret);
9837
9838   vec_free (vpn_ascii_id);
9839   return ret;
9840 }
9841
9842 static int
9843 api_dhcp_client_config (vat_main_t * vam)
9844 {
9845   unformat_input_t *i = vam->input;
9846   vl_api_dhcp_client_config_t *mp;
9847   u32 sw_if_index;
9848   u8 sw_if_index_set = 0;
9849   u8 is_add = 1;
9850   u8 *hostname = 0;
9851   u8 disable_event = 0;
9852   int ret;
9853
9854   /* Parse args required to build the message */
9855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9856     {
9857       if (unformat (i, "del"))
9858         is_add = 0;
9859       else
9860         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9861         sw_if_index_set = 1;
9862       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9863         sw_if_index_set = 1;
9864       else if (unformat (i, "hostname %s", &hostname))
9865         ;
9866       else if (unformat (i, "disable_event"))
9867         disable_event = 1;
9868       else
9869         break;
9870     }
9871
9872   if (sw_if_index_set == 0)
9873     {
9874       errmsg ("missing interface name or sw_if_index");
9875       return -99;
9876     }
9877
9878   if (vec_len (hostname) > 63)
9879     {
9880       errmsg ("hostname too long");
9881     }
9882   vec_add1 (hostname, 0);
9883
9884   /* Construct the API message */
9885   M (DHCP_CLIENT_CONFIG, mp);
9886
9887   mp->is_add = is_add;
9888   mp->client.sw_if_index = htonl (sw_if_index);
9889   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9890   vec_free (hostname);
9891   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9892   mp->client.pid = htonl (getpid ());
9893
9894   /* send it... */
9895   S (mp);
9896
9897   /* Wait for a reply, return good/bad news  */
9898   W (ret);
9899   return ret;
9900 }
9901
9902 static int
9903 api_set_ip_flow_hash (vat_main_t * vam)
9904 {
9905   unformat_input_t *i = vam->input;
9906   vl_api_set_ip_flow_hash_t *mp;
9907   u32 vrf_id = 0;
9908   u8 is_ipv6 = 0;
9909   u8 vrf_id_set = 0;
9910   u8 src = 0;
9911   u8 dst = 0;
9912   u8 sport = 0;
9913   u8 dport = 0;
9914   u8 proto = 0;
9915   u8 reverse = 0;
9916   int ret;
9917
9918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9919     {
9920       if (unformat (i, "vrf %d", &vrf_id))
9921         vrf_id_set = 1;
9922       else if (unformat (i, "ipv6"))
9923         is_ipv6 = 1;
9924       else if (unformat (i, "src"))
9925         src = 1;
9926       else if (unformat (i, "dst"))
9927         dst = 1;
9928       else if (unformat (i, "sport"))
9929         sport = 1;
9930       else if (unformat (i, "dport"))
9931         dport = 1;
9932       else if (unformat (i, "proto"))
9933         proto = 1;
9934       else if (unformat (i, "reverse"))
9935         reverse = 1;
9936
9937       else
9938         {
9939           clib_warning ("parse error '%U'", format_unformat_error, i);
9940           return -99;
9941         }
9942     }
9943
9944   if (vrf_id_set == 0)
9945     {
9946       errmsg ("missing vrf id");
9947       return -99;
9948     }
9949
9950   M (SET_IP_FLOW_HASH, mp);
9951   mp->src = src;
9952   mp->dst = dst;
9953   mp->sport = sport;
9954   mp->dport = dport;
9955   mp->proto = proto;
9956   mp->reverse = reverse;
9957   mp->vrf_id = ntohl (vrf_id);
9958   mp->is_ipv6 = is_ipv6;
9959
9960   S (mp);
9961   W (ret);
9962   return ret;
9963 }
9964
9965 static int
9966 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9967 {
9968   unformat_input_t *i = vam->input;
9969   vl_api_sw_interface_ip6_enable_disable_t *mp;
9970   u32 sw_if_index;
9971   u8 sw_if_index_set = 0;
9972   u8 enable = 0;
9973   int ret;
9974
9975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9976     {
9977       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9978         sw_if_index_set = 1;
9979       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9980         sw_if_index_set = 1;
9981       else if (unformat (i, "enable"))
9982         enable = 1;
9983       else if (unformat (i, "disable"))
9984         enable = 0;
9985       else
9986         {
9987           clib_warning ("parse error '%U'", format_unformat_error, i);
9988           return -99;
9989         }
9990     }
9991
9992   if (sw_if_index_set == 0)
9993     {
9994       errmsg ("missing interface name or sw_if_index");
9995       return -99;
9996     }
9997
9998   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9999
10000   mp->sw_if_index = ntohl (sw_if_index);
10001   mp->enable = enable;
10002
10003   S (mp);
10004   W (ret);
10005   return ret;
10006 }
10007
10008 static int
10009 api_ip6nd_proxy_add_del (vat_main_t * vam)
10010 {
10011   unformat_input_t *i = vam->input;
10012   vl_api_ip6nd_proxy_add_del_t *mp;
10013   u32 sw_if_index = ~0;
10014   u8 v6_address_set = 0;
10015   vl_api_ip6_address_t v6address;
10016   u8 is_del = 0;
10017   int ret;
10018
10019   /* Parse args required to build the message */
10020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10021     {
10022       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10023         ;
10024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10025         ;
10026       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10027         v6_address_set = 1;
10028       if (unformat (i, "del"))
10029         is_del = 1;
10030       else
10031         {
10032           clib_warning ("parse error '%U'", format_unformat_error, i);
10033           return -99;
10034         }
10035     }
10036
10037   if (sw_if_index == ~0)
10038     {
10039       errmsg ("missing interface name or sw_if_index");
10040       return -99;
10041     }
10042   if (!v6_address_set)
10043     {
10044       errmsg ("no address set");
10045       return -99;
10046     }
10047
10048   /* Construct the API message */
10049   M (IP6ND_PROXY_ADD_DEL, mp);
10050
10051   mp->is_del = is_del;
10052   mp->sw_if_index = ntohl (sw_if_index);
10053   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10054
10055   /* send it... */
10056   S (mp);
10057
10058   /* Wait for a reply, return good/bad news  */
10059   W (ret);
10060   return ret;
10061 }
10062
10063 static int
10064 api_ip6nd_proxy_dump (vat_main_t * vam)
10065 {
10066   vl_api_ip6nd_proxy_dump_t *mp;
10067   vl_api_control_ping_t *mp_ping;
10068   int ret;
10069
10070   M (IP6ND_PROXY_DUMP, mp);
10071
10072   S (mp);
10073
10074   /* Use a control ping for synchronization */
10075   MPING (CONTROL_PING, mp_ping);
10076   S (mp_ping);
10077
10078   W (ret);
10079   return ret;
10080 }
10081
10082 static void vl_api_ip6nd_proxy_details_t_handler
10083   (vl_api_ip6nd_proxy_details_t * mp)
10084 {
10085   vat_main_t *vam = &vat_main;
10086
10087   print (vam->ofp, "host %U sw_if_index %d",
10088          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10089 }
10090
10091 static void vl_api_ip6nd_proxy_details_t_handler_json
10092   (vl_api_ip6nd_proxy_details_t * mp)
10093 {
10094   vat_main_t *vam = &vat_main;
10095   struct in6_addr ip6;
10096   vat_json_node_t *node = NULL;
10097
10098   if (VAT_JSON_ARRAY != vam->json_tree.type)
10099     {
10100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10101       vat_json_init_array (&vam->json_tree);
10102     }
10103   node = vat_json_array_add (&vam->json_tree);
10104
10105   vat_json_init_object (node);
10106   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10107
10108   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10109   vat_json_object_add_ip6 (node, "host", ip6);
10110 }
10111
10112 static int
10113 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10114 {
10115   unformat_input_t *i = vam->input;
10116   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10117   u32 sw_if_index;
10118   u8 sw_if_index_set = 0;
10119   u8 v6_address_set = 0;
10120   vl_api_prefix_t pfx;
10121   u8 use_default = 0;
10122   u8 no_advertise = 0;
10123   u8 off_link = 0;
10124   u8 no_autoconfig = 0;
10125   u8 no_onlink = 0;
10126   u8 is_no = 0;
10127   u32 val_lifetime = 0;
10128   u32 pref_lifetime = 0;
10129   int ret;
10130
10131   /* Parse args required to build the message */
10132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10133     {
10134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10135         sw_if_index_set = 1;
10136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10137         sw_if_index_set = 1;
10138       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10139         v6_address_set = 1;
10140       else if (unformat (i, "val_life %d", &val_lifetime))
10141         ;
10142       else if (unformat (i, "pref_life %d", &pref_lifetime))
10143         ;
10144       else if (unformat (i, "def"))
10145         use_default = 1;
10146       else if (unformat (i, "noadv"))
10147         no_advertise = 1;
10148       else if (unformat (i, "offl"))
10149         off_link = 1;
10150       else if (unformat (i, "noauto"))
10151         no_autoconfig = 1;
10152       else if (unformat (i, "nolink"))
10153         no_onlink = 1;
10154       else if (unformat (i, "isno"))
10155         is_no = 1;
10156       else
10157         {
10158           clib_warning ("parse error '%U'", format_unformat_error, i);
10159           return -99;
10160         }
10161     }
10162
10163   if (sw_if_index_set == 0)
10164     {
10165       errmsg ("missing interface name or sw_if_index");
10166       return -99;
10167     }
10168   if (!v6_address_set)
10169     {
10170       errmsg ("no address set");
10171       return -99;
10172     }
10173
10174   /* Construct the API message */
10175   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10176
10177   mp->sw_if_index = ntohl (sw_if_index);
10178   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10179   mp->use_default = use_default;
10180   mp->no_advertise = no_advertise;
10181   mp->off_link = off_link;
10182   mp->no_autoconfig = no_autoconfig;
10183   mp->no_onlink = no_onlink;
10184   mp->is_no = is_no;
10185   mp->val_lifetime = ntohl (val_lifetime);
10186   mp->pref_lifetime = ntohl (pref_lifetime);
10187
10188   /* send it... */
10189   S (mp);
10190
10191   /* Wait for a reply, return good/bad news  */
10192   W (ret);
10193   return ret;
10194 }
10195
10196 static int
10197 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10198 {
10199   unformat_input_t *i = vam->input;
10200   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10201   u32 sw_if_index;
10202   u8 sw_if_index_set = 0;
10203   u8 suppress = 0;
10204   u8 managed = 0;
10205   u8 other = 0;
10206   u8 ll_option = 0;
10207   u8 send_unicast = 0;
10208   u8 cease = 0;
10209   u8 is_no = 0;
10210   u8 default_router = 0;
10211   u32 max_interval = 0;
10212   u32 min_interval = 0;
10213   u32 lifetime = 0;
10214   u32 initial_count = 0;
10215   u32 initial_interval = 0;
10216   int ret;
10217
10218
10219   /* Parse args required to build the message */
10220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10221     {
10222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10223         sw_if_index_set = 1;
10224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10225         sw_if_index_set = 1;
10226       else if (unformat (i, "maxint %d", &max_interval))
10227         ;
10228       else if (unformat (i, "minint %d", &min_interval))
10229         ;
10230       else if (unformat (i, "life %d", &lifetime))
10231         ;
10232       else if (unformat (i, "count %d", &initial_count))
10233         ;
10234       else if (unformat (i, "interval %d", &initial_interval))
10235         ;
10236       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10237         suppress = 1;
10238       else if (unformat (i, "managed"))
10239         managed = 1;
10240       else if (unformat (i, "other"))
10241         other = 1;
10242       else if (unformat (i, "ll"))
10243         ll_option = 1;
10244       else if (unformat (i, "send"))
10245         send_unicast = 1;
10246       else if (unformat (i, "cease"))
10247         cease = 1;
10248       else if (unformat (i, "isno"))
10249         is_no = 1;
10250       else if (unformat (i, "def"))
10251         default_router = 1;
10252       else
10253         {
10254           clib_warning ("parse error '%U'", format_unformat_error, i);
10255           return -99;
10256         }
10257     }
10258
10259   if (sw_if_index_set == 0)
10260     {
10261       errmsg ("missing interface name or sw_if_index");
10262       return -99;
10263     }
10264
10265   /* Construct the API message */
10266   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10267
10268   mp->sw_if_index = ntohl (sw_if_index);
10269   mp->max_interval = ntohl (max_interval);
10270   mp->min_interval = ntohl (min_interval);
10271   mp->lifetime = ntohl (lifetime);
10272   mp->initial_count = ntohl (initial_count);
10273   mp->initial_interval = ntohl (initial_interval);
10274   mp->suppress = suppress;
10275   mp->managed = managed;
10276   mp->other = other;
10277   mp->ll_option = ll_option;
10278   mp->send_unicast = send_unicast;
10279   mp->cease = cease;
10280   mp->is_no = is_no;
10281   mp->default_router = default_router;
10282
10283   /* send it... */
10284   S (mp);
10285
10286   /* Wait for a reply, return good/bad news  */
10287   W (ret);
10288   return ret;
10289 }
10290
10291 static int
10292 api_set_arp_neighbor_limit (vat_main_t * vam)
10293 {
10294   unformat_input_t *i = vam->input;
10295   vl_api_set_arp_neighbor_limit_t *mp;
10296   u32 arp_nbr_limit;
10297   u8 limit_set = 0;
10298   u8 is_ipv6 = 0;
10299   int ret;
10300
10301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10302     {
10303       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10304         limit_set = 1;
10305       else if (unformat (i, "ipv6"))
10306         is_ipv6 = 1;
10307       else
10308         {
10309           clib_warning ("parse error '%U'", format_unformat_error, i);
10310           return -99;
10311         }
10312     }
10313
10314   if (limit_set == 0)
10315     {
10316       errmsg ("missing limit value");
10317       return -99;
10318     }
10319
10320   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10321
10322   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10323   mp->is_ipv6 = is_ipv6;
10324
10325   S (mp);
10326   W (ret);
10327   return ret;
10328 }
10329
10330 static int
10331 api_l2_patch_add_del (vat_main_t * vam)
10332 {
10333   unformat_input_t *i = vam->input;
10334   vl_api_l2_patch_add_del_t *mp;
10335   u32 rx_sw_if_index;
10336   u8 rx_sw_if_index_set = 0;
10337   u32 tx_sw_if_index;
10338   u8 tx_sw_if_index_set = 0;
10339   u8 is_add = 1;
10340   int ret;
10341
10342   /* Parse args required to build the message */
10343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10344     {
10345       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10346         rx_sw_if_index_set = 1;
10347       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10348         tx_sw_if_index_set = 1;
10349       else if (unformat (i, "rx"))
10350         {
10351           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10352             {
10353               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10354                             &rx_sw_if_index))
10355                 rx_sw_if_index_set = 1;
10356             }
10357           else
10358             break;
10359         }
10360       else if (unformat (i, "tx"))
10361         {
10362           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10363             {
10364               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10365                             &tx_sw_if_index))
10366                 tx_sw_if_index_set = 1;
10367             }
10368           else
10369             break;
10370         }
10371       else if (unformat (i, "del"))
10372         is_add = 0;
10373       else
10374         break;
10375     }
10376
10377   if (rx_sw_if_index_set == 0)
10378     {
10379       errmsg ("missing rx interface name or rx_sw_if_index");
10380       return -99;
10381     }
10382
10383   if (tx_sw_if_index_set == 0)
10384     {
10385       errmsg ("missing tx interface name or tx_sw_if_index");
10386       return -99;
10387     }
10388
10389   M (L2_PATCH_ADD_DEL, mp);
10390
10391   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10392   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10393   mp->is_add = is_add;
10394
10395   S (mp);
10396   W (ret);
10397   return ret;
10398 }
10399
10400 u8 is_del;
10401 u8 localsid_addr[16];
10402 u8 end_psp;
10403 u8 behavior;
10404 u32 sw_if_index;
10405 u32 vlan_index;
10406 u32 fib_table;
10407 u8 nh_addr[16];
10408
10409 static int
10410 api_sr_localsid_add_del (vat_main_t * vam)
10411 {
10412   unformat_input_t *i = vam->input;
10413   vl_api_sr_localsid_add_del_t *mp;
10414
10415   u8 is_del;
10416   ip6_address_t localsid;
10417   u8 end_psp = 0;
10418   u8 behavior = ~0;
10419   u32 sw_if_index;
10420   u32 fib_table = ~(u32) 0;
10421   ip6_address_t nh_addr6;
10422   ip4_address_t nh_addr4;
10423   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10424   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10425
10426   bool nexthop_set = 0;
10427
10428   int ret;
10429
10430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10431     {
10432       if (unformat (i, "del"))
10433         is_del = 1;
10434       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10435       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10436         nexthop_set = 1;
10437       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10438         nexthop_set = 1;
10439       else if (unformat (i, "behavior %u", &behavior));
10440       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10441       else if (unformat (i, "fib-table %u", &fib_table));
10442       else if (unformat (i, "end.psp %u", &behavior));
10443       else
10444         break;
10445     }
10446
10447   M (SR_LOCALSID_ADD_DEL, mp);
10448
10449   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10450   if (nexthop_set)
10451     {
10452       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10453       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10454     }
10455   mp->behavior = behavior;
10456   mp->sw_if_index = ntohl (sw_if_index);
10457   mp->fib_table = ntohl (fib_table);
10458   mp->end_psp = end_psp;
10459   mp->is_del = is_del;
10460
10461   S (mp);
10462   W (ret);
10463   return ret;
10464 }
10465
10466 static int
10467 api_ioam_enable (vat_main_t * vam)
10468 {
10469   unformat_input_t *input = vam->input;
10470   vl_api_ioam_enable_t *mp;
10471   u32 id = 0;
10472   int has_trace_option = 0;
10473   int has_pot_option = 0;
10474   int has_seqno_option = 0;
10475   int has_analyse_option = 0;
10476   int ret;
10477
10478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10479     {
10480       if (unformat (input, "trace"))
10481         has_trace_option = 1;
10482       else if (unformat (input, "pot"))
10483         has_pot_option = 1;
10484       else if (unformat (input, "seqno"))
10485         has_seqno_option = 1;
10486       else if (unformat (input, "analyse"))
10487         has_analyse_option = 1;
10488       else
10489         break;
10490     }
10491   M (IOAM_ENABLE, mp);
10492   mp->id = htons (id);
10493   mp->seqno = has_seqno_option;
10494   mp->analyse = has_analyse_option;
10495   mp->pot_enable = has_pot_option;
10496   mp->trace_enable = has_trace_option;
10497
10498   S (mp);
10499   W (ret);
10500   return ret;
10501 }
10502
10503
10504 static int
10505 api_ioam_disable (vat_main_t * vam)
10506 {
10507   vl_api_ioam_disable_t *mp;
10508   int ret;
10509
10510   M (IOAM_DISABLE, mp);
10511   S (mp);
10512   W (ret);
10513   return ret;
10514 }
10515
10516 #define foreach_tcp_proto_field                 \
10517 _(src_port)                                     \
10518 _(dst_port)
10519
10520 #define foreach_udp_proto_field                 \
10521 _(src_port)                                     \
10522 _(dst_port)
10523
10524 #define foreach_ip4_proto_field                 \
10525 _(src_address)                                  \
10526 _(dst_address)                                  \
10527 _(tos)                                          \
10528 _(length)                                       \
10529 _(fragment_id)                                  \
10530 _(ttl)                                          \
10531 _(protocol)                                     \
10532 _(checksum)
10533
10534 typedef struct
10535 {
10536   u16 src_port, dst_port;
10537 } tcpudp_header_t;
10538
10539 #if VPP_API_TEST_BUILTIN == 0
10540 uword
10541 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10542 {
10543   u8 **maskp = va_arg (*args, u8 **);
10544   u8 *mask = 0;
10545   u8 found_something = 0;
10546   tcp_header_t *tcp;
10547
10548 #define _(a) u8 a=0;
10549   foreach_tcp_proto_field;
10550 #undef _
10551
10552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10553     {
10554       if (0);
10555 #define _(a) else if (unformat (input, #a)) a=1;
10556       foreach_tcp_proto_field
10557 #undef _
10558         else
10559         break;
10560     }
10561
10562 #define _(a) found_something += a;
10563   foreach_tcp_proto_field;
10564 #undef _
10565
10566   if (found_something == 0)
10567     return 0;
10568
10569   vec_validate (mask, sizeof (*tcp) - 1);
10570
10571   tcp = (tcp_header_t *) mask;
10572
10573 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10574   foreach_tcp_proto_field;
10575 #undef _
10576
10577   *maskp = mask;
10578   return 1;
10579 }
10580
10581 uword
10582 unformat_udp_mask (unformat_input_t * input, va_list * args)
10583 {
10584   u8 **maskp = va_arg (*args, u8 **);
10585   u8 *mask = 0;
10586   u8 found_something = 0;
10587   udp_header_t *udp;
10588
10589 #define _(a) u8 a=0;
10590   foreach_udp_proto_field;
10591 #undef _
10592
10593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10594     {
10595       if (0);
10596 #define _(a) else if (unformat (input, #a)) a=1;
10597       foreach_udp_proto_field
10598 #undef _
10599         else
10600         break;
10601     }
10602
10603 #define _(a) found_something += a;
10604   foreach_udp_proto_field;
10605 #undef _
10606
10607   if (found_something == 0)
10608     return 0;
10609
10610   vec_validate (mask, sizeof (*udp) - 1);
10611
10612   udp = (udp_header_t *) mask;
10613
10614 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10615   foreach_udp_proto_field;
10616 #undef _
10617
10618   *maskp = mask;
10619   return 1;
10620 }
10621
10622 uword
10623 unformat_l4_mask (unformat_input_t * input, va_list * args)
10624 {
10625   u8 **maskp = va_arg (*args, u8 **);
10626   u16 src_port = 0, dst_port = 0;
10627   tcpudp_header_t *tcpudp;
10628
10629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10630     {
10631       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10632         return 1;
10633       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10634         return 1;
10635       else if (unformat (input, "src_port"))
10636         src_port = 0xFFFF;
10637       else if (unformat (input, "dst_port"))
10638         dst_port = 0xFFFF;
10639       else
10640         return 0;
10641     }
10642
10643   if (!src_port && !dst_port)
10644     return 0;
10645
10646   u8 *mask = 0;
10647   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10648
10649   tcpudp = (tcpudp_header_t *) mask;
10650   tcpudp->src_port = src_port;
10651   tcpudp->dst_port = dst_port;
10652
10653   *maskp = mask;
10654
10655   return 1;
10656 }
10657
10658 uword
10659 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10660 {
10661   u8 **maskp = va_arg (*args, u8 **);
10662   u8 *mask = 0;
10663   u8 found_something = 0;
10664   ip4_header_t *ip;
10665
10666 #define _(a) u8 a=0;
10667   foreach_ip4_proto_field;
10668 #undef _
10669   u8 version = 0;
10670   u8 hdr_length = 0;
10671
10672
10673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10674     {
10675       if (unformat (input, "version"))
10676         version = 1;
10677       else if (unformat (input, "hdr_length"))
10678         hdr_length = 1;
10679       else if (unformat (input, "src"))
10680         src_address = 1;
10681       else if (unformat (input, "dst"))
10682         dst_address = 1;
10683       else if (unformat (input, "proto"))
10684         protocol = 1;
10685
10686 #define _(a) else if (unformat (input, #a)) a=1;
10687       foreach_ip4_proto_field
10688 #undef _
10689         else
10690         break;
10691     }
10692
10693 #define _(a) found_something += a;
10694   foreach_ip4_proto_field;
10695 #undef _
10696
10697   if (found_something == 0)
10698     return 0;
10699
10700   vec_validate (mask, sizeof (*ip) - 1);
10701
10702   ip = (ip4_header_t *) mask;
10703
10704 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10705   foreach_ip4_proto_field;
10706 #undef _
10707
10708   ip->ip_version_and_header_length = 0;
10709
10710   if (version)
10711     ip->ip_version_and_header_length |= 0xF0;
10712
10713   if (hdr_length)
10714     ip->ip_version_and_header_length |= 0x0F;
10715
10716   *maskp = mask;
10717   return 1;
10718 }
10719
10720 #define foreach_ip6_proto_field                 \
10721 _(src_address)                                  \
10722 _(dst_address)                                  \
10723 _(payload_length)                               \
10724 _(hop_limit)                                    \
10725 _(protocol)
10726
10727 uword
10728 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10729 {
10730   u8 **maskp = va_arg (*args, u8 **);
10731   u8 *mask = 0;
10732   u8 found_something = 0;
10733   ip6_header_t *ip;
10734   u32 ip_version_traffic_class_and_flow_label;
10735
10736 #define _(a) u8 a=0;
10737   foreach_ip6_proto_field;
10738 #undef _
10739   u8 version = 0;
10740   u8 traffic_class = 0;
10741   u8 flow_label = 0;
10742
10743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10744     {
10745       if (unformat (input, "version"))
10746         version = 1;
10747       else if (unformat (input, "traffic-class"))
10748         traffic_class = 1;
10749       else if (unformat (input, "flow-label"))
10750         flow_label = 1;
10751       else if (unformat (input, "src"))
10752         src_address = 1;
10753       else if (unformat (input, "dst"))
10754         dst_address = 1;
10755       else if (unformat (input, "proto"))
10756         protocol = 1;
10757
10758 #define _(a) else if (unformat (input, #a)) a=1;
10759       foreach_ip6_proto_field
10760 #undef _
10761         else
10762         break;
10763     }
10764
10765 #define _(a) found_something += a;
10766   foreach_ip6_proto_field;
10767 #undef _
10768
10769   if (found_something == 0)
10770     return 0;
10771
10772   vec_validate (mask, sizeof (*ip) - 1);
10773
10774   ip = (ip6_header_t *) mask;
10775
10776 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10777   foreach_ip6_proto_field;
10778 #undef _
10779
10780   ip_version_traffic_class_and_flow_label = 0;
10781
10782   if (version)
10783     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10784
10785   if (traffic_class)
10786     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10787
10788   if (flow_label)
10789     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10790
10791   ip->ip_version_traffic_class_and_flow_label =
10792     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10793
10794   *maskp = mask;
10795   return 1;
10796 }
10797
10798 uword
10799 unformat_l3_mask (unformat_input_t * input, va_list * args)
10800 {
10801   u8 **maskp = va_arg (*args, u8 **);
10802
10803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10804     {
10805       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10806         return 1;
10807       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10808         return 1;
10809       else
10810         break;
10811     }
10812   return 0;
10813 }
10814
10815 uword
10816 unformat_l2_mask (unformat_input_t * input, va_list * args)
10817 {
10818   u8 **maskp = va_arg (*args, u8 **);
10819   u8 *mask = 0;
10820   u8 src = 0;
10821   u8 dst = 0;
10822   u8 proto = 0;
10823   u8 tag1 = 0;
10824   u8 tag2 = 0;
10825   u8 ignore_tag1 = 0;
10826   u8 ignore_tag2 = 0;
10827   u8 cos1 = 0;
10828   u8 cos2 = 0;
10829   u8 dot1q = 0;
10830   u8 dot1ad = 0;
10831   int len = 14;
10832
10833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10834     {
10835       if (unformat (input, "src"))
10836         src = 1;
10837       else if (unformat (input, "dst"))
10838         dst = 1;
10839       else if (unformat (input, "proto"))
10840         proto = 1;
10841       else if (unformat (input, "tag1"))
10842         tag1 = 1;
10843       else if (unformat (input, "tag2"))
10844         tag2 = 1;
10845       else if (unformat (input, "ignore-tag1"))
10846         ignore_tag1 = 1;
10847       else if (unformat (input, "ignore-tag2"))
10848         ignore_tag2 = 1;
10849       else if (unformat (input, "cos1"))
10850         cos1 = 1;
10851       else if (unformat (input, "cos2"))
10852         cos2 = 1;
10853       else if (unformat (input, "dot1q"))
10854         dot1q = 1;
10855       else if (unformat (input, "dot1ad"))
10856         dot1ad = 1;
10857       else
10858         break;
10859     }
10860   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10861        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10862     return 0;
10863
10864   if (tag1 || ignore_tag1 || cos1 || dot1q)
10865     len = 18;
10866   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10867     len = 22;
10868
10869   vec_validate (mask, len - 1);
10870
10871   if (dst)
10872     clib_memset (mask, 0xff, 6);
10873
10874   if (src)
10875     clib_memset (mask + 6, 0xff, 6);
10876
10877   if (tag2 || dot1ad)
10878     {
10879       /* inner vlan tag */
10880       if (tag2)
10881         {
10882           mask[19] = 0xff;
10883           mask[18] = 0x0f;
10884         }
10885       if (cos2)
10886         mask[18] |= 0xe0;
10887       if (proto)
10888         mask[21] = mask[20] = 0xff;
10889       if (tag1)
10890         {
10891           mask[15] = 0xff;
10892           mask[14] = 0x0f;
10893         }
10894       if (cos1)
10895         mask[14] |= 0xe0;
10896       *maskp = mask;
10897       return 1;
10898     }
10899   if (tag1 | dot1q)
10900     {
10901       if (tag1)
10902         {
10903           mask[15] = 0xff;
10904           mask[14] = 0x0f;
10905         }
10906       if (cos1)
10907         mask[14] |= 0xe0;
10908       if (proto)
10909         mask[16] = mask[17] = 0xff;
10910
10911       *maskp = mask;
10912       return 1;
10913     }
10914   if (cos2)
10915     mask[18] |= 0xe0;
10916   if (cos1)
10917     mask[14] |= 0xe0;
10918   if (proto)
10919     mask[12] = mask[13] = 0xff;
10920
10921   *maskp = mask;
10922   return 1;
10923 }
10924
10925 uword
10926 unformat_classify_mask (unformat_input_t * input, va_list * args)
10927 {
10928   u8 **maskp = va_arg (*args, u8 **);
10929   u32 *skipp = va_arg (*args, u32 *);
10930   u32 *matchp = va_arg (*args, u32 *);
10931   u32 match;
10932   u8 *mask = 0;
10933   u8 *l2 = 0;
10934   u8 *l3 = 0;
10935   u8 *l4 = 0;
10936   int i;
10937
10938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10939     {
10940       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10941         ;
10942       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10943         ;
10944       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10945         ;
10946       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10947         ;
10948       else
10949         break;
10950     }
10951
10952   if (l4 && !l3)
10953     {
10954       vec_free (mask);
10955       vec_free (l2);
10956       vec_free (l4);
10957       return 0;
10958     }
10959
10960   if (mask || l2 || l3 || l4)
10961     {
10962       if (l2 || l3 || l4)
10963         {
10964           /* "With a free Ethernet header in every package" */
10965           if (l2 == 0)
10966             vec_validate (l2, 13);
10967           mask = l2;
10968           if (vec_len (l3))
10969             {
10970               vec_append (mask, l3);
10971               vec_free (l3);
10972             }
10973           if (vec_len (l4))
10974             {
10975               vec_append (mask, l4);
10976               vec_free (l4);
10977             }
10978         }
10979
10980       /* Scan forward looking for the first significant mask octet */
10981       for (i = 0; i < vec_len (mask); i++)
10982         if (mask[i])
10983           break;
10984
10985       /* compute (skip, match) params */
10986       *skipp = i / sizeof (u32x4);
10987       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10988
10989       /* Pad mask to an even multiple of the vector size */
10990       while (vec_len (mask) % sizeof (u32x4))
10991         vec_add1 (mask, 0);
10992
10993       match = vec_len (mask) / sizeof (u32x4);
10994
10995       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10996         {
10997           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10998           if (*tmp || *(tmp + 1))
10999             break;
11000           match--;
11001         }
11002       if (match == 0)
11003         clib_warning ("BUG: match 0");
11004
11005       _vec_len (mask) = match * sizeof (u32x4);
11006
11007       *matchp = match;
11008       *maskp = mask;
11009
11010       return 1;
11011     }
11012
11013   return 0;
11014 }
11015 #endif /* VPP_API_TEST_BUILTIN */
11016
11017 #define foreach_l2_next                         \
11018 _(drop, DROP)                                   \
11019 _(ethernet, ETHERNET_INPUT)                     \
11020 _(ip4, IP4_INPUT)                               \
11021 _(ip6, IP6_INPUT)
11022
11023 uword
11024 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11025 {
11026   u32 *miss_next_indexp = va_arg (*args, u32 *);
11027   u32 next_index = 0;
11028   u32 tmp;
11029
11030 #define _(n,N) \
11031   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11032   foreach_l2_next;
11033 #undef _
11034
11035   if (unformat (input, "%d", &tmp))
11036     {
11037       next_index = tmp;
11038       goto out;
11039     }
11040
11041   return 0;
11042
11043 out:
11044   *miss_next_indexp = next_index;
11045   return 1;
11046 }
11047
11048 #define foreach_ip_next                         \
11049 _(drop, DROP)                                   \
11050 _(local, LOCAL)                                 \
11051 _(rewrite, REWRITE)
11052
11053 uword
11054 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11055 {
11056   u32 *miss_next_indexp = va_arg (*args, u32 *);
11057   u32 next_index = 0;
11058   u32 tmp;
11059
11060 #define _(n,N) \
11061   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11062   foreach_ip_next;
11063 #undef _
11064
11065   if (unformat (input, "%d", &tmp))
11066     {
11067       next_index = tmp;
11068       goto out;
11069     }
11070
11071   return 0;
11072
11073 out:
11074   *miss_next_indexp = next_index;
11075   return 1;
11076 }
11077
11078 #define foreach_acl_next                        \
11079 _(deny, DENY)
11080
11081 uword
11082 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11083 {
11084   u32 *miss_next_indexp = va_arg (*args, u32 *);
11085   u32 next_index = 0;
11086   u32 tmp;
11087
11088 #define _(n,N) \
11089   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11090   foreach_acl_next;
11091 #undef _
11092
11093   if (unformat (input, "permit"))
11094     {
11095       next_index = ~0;
11096       goto out;
11097     }
11098   else if (unformat (input, "%d", &tmp))
11099     {
11100       next_index = tmp;
11101       goto out;
11102     }
11103
11104   return 0;
11105
11106 out:
11107   *miss_next_indexp = next_index;
11108   return 1;
11109 }
11110
11111 uword
11112 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11113 {
11114   u32 *r = va_arg (*args, u32 *);
11115
11116   if (unformat (input, "conform-color"))
11117     *r = POLICE_CONFORM;
11118   else if (unformat (input, "exceed-color"))
11119     *r = POLICE_EXCEED;
11120   else
11121     return 0;
11122
11123   return 1;
11124 }
11125
11126 static int
11127 api_classify_add_del_table (vat_main_t * vam)
11128 {
11129   unformat_input_t *i = vam->input;
11130   vl_api_classify_add_del_table_t *mp;
11131
11132   u32 nbuckets = 2;
11133   u32 skip = ~0;
11134   u32 match = ~0;
11135   int is_add = 1;
11136   int del_chain = 0;
11137   u32 table_index = ~0;
11138   u32 next_table_index = ~0;
11139   u32 miss_next_index = ~0;
11140   u32 memory_size = 32 << 20;
11141   u8 *mask = 0;
11142   u32 current_data_flag = 0;
11143   int current_data_offset = 0;
11144   int ret;
11145
11146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11147     {
11148       if (unformat (i, "del"))
11149         is_add = 0;
11150       else if (unformat (i, "del-chain"))
11151         {
11152           is_add = 0;
11153           del_chain = 1;
11154         }
11155       else if (unformat (i, "buckets %d", &nbuckets))
11156         ;
11157       else if (unformat (i, "memory_size %d", &memory_size))
11158         ;
11159       else if (unformat (i, "skip %d", &skip))
11160         ;
11161       else if (unformat (i, "match %d", &match))
11162         ;
11163       else if (unformat (i, "table %d", &table_index))
11164         ;
11165       else if (unformat (i, "mask %U", unformat_classify_mask,
11166                          &mask, &skip, &match))
11167         ;
11168       else if (unformat (i, "next-table %d", &next_table_index))
11169         ;
11170       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11171                          &miss_next_index))
11172         ;
11173       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11174                          &miss_next_index))
11175         ;
11176       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11177                          &miss_next_index))
11178         ;
11179       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11180         ;
11181       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11182         ;
11183       else
11184         break;
11185     }
11186
11187   if (is_add && mask == 0)
11188     {
11189       errmsg ("Mask required");
11190       return -99;
11191     }
11192
11193   if (is_add && skip == ~0)
11194     {
11195       errmsg ("skip count required");
11196       return -99;
11197     }
11198
11199   if (is_add && match == ~0)
11200     {
11201       errmsg ("match count required");
11202       return -99;
11203     }
11204
11205   if (!is_add && table_index == ~0)
11206     {
11207       errmsg ("table index required for delete");
11208       return -99;
11209     }
11210
11211   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11212
11213   mp->is_add = is_add;
11214   mp->del_chain = del_chain;
11215   mp->table_index = ntohl (table_index);
11216   mp->nbuckets = ntohl (nbuckets);
11217   mp->memory_size = ntohl (memory_size);
11218   mp->skip_n_vectors = ntohl (skip);
11219   mp->match_n_vectors = ntohl (match);
11220   mp->next_table_index = ntohl (next_table_index);
11221   mp->miss_next_index = ntohl (miss_next_index);
11222   mp->current_data_flag = ntohl (current_data_flag);
11223   mp->current_data_offset = ntohl (current_data_offset);
11224   mp->mask_len = ntohl (vec_len (mask));
11225   clib_memcpy (mp->mask, mask, vec_len (mask));
11226
11227   vec_free (mask);
11228
11229   S (mp);
11230   W (ret);
11231   return ret;
11232 }
11233
11234 #if VPP_API_TEST_BUILTIN == 0
11235 uword
11236 unformat_l4_match (unformat_input_t * input, va_list * args)
11237 {
11238   u8 **matchp = va_arg (*args, u8 **);
11239
11240   u8 *proto_header = 0;
11241   int src_port = 0;
11242   int dst_port = 0;
11243
11244   tcpudp_header_t h;
11245
11246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11247     {
11248       if (unformat (input, "src_port %d", &src_port))
11249         ;
11250       else if (unformat (input, "dst_port %d", &dst_port))
11251         ;
11252       else
11253         return 0;
11254     }
11255
11256   h.src_port = clib_host_to_net_u16 (src_port);
11257   h.dst_port = clib_host_to_net_u16 (dst_port);
11258   vec_validate (proto_header, sizeof (h) - 1);
11259   memcpy (proto_header, &h, sizeof (h));
11260
11261   *matchp = proto_header;
11262
11263   return 1;
11264 }
11265
11266 uword
11267 unformat_ip4_match (unformat_input_t * input, va_list * args)
11268 {
11269   u8 **matchp = va_arg (*args, u8 **);
11270   u8 *match = 0;
11271   ip4_header_t *ip;
11272   int version = 0;
11273   u32 version_val;
11274   int hdr_length = 0;
11275   u32 hdr_length_val;
11276   int src = 0, dst = 0;
11277   ip4_address_t src_val, dst_val;
11278   int proto = 0;
11279   u32 proto_val;
11280   int tos = 0;
11281   u32 tos_val;
11282   int length = 0;
11283   u32 length_val;
11284   int fragment_id = 0;
11285   u32 fragment_id_val;
11286   int ttl = 0;
11287   int ttl_val;
11288   int checksum = 0;
11289   u32 checksum_val;
11290
11291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11292     {
11293       if (unformat (input, "version %d", &version_val))
11294         version = 1;
11295       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11296         hdr_length = 1;
11297       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11298         src = 1;
11299       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11300         dst = 1;
11301       else if (unformat (input, "proto %d", &proto_val))
11302         proto = 1;
11303       else if (unformat (input, "tos %d", &tos_val))
11304         tos = 1;
11305       else if (unformat (input, "length %d", &length_val))
11306         length = 1;
11307       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11308         fragment_id = 1;
11309       else if (unformat (input, "ttl %d", &ttl_val))
11310         ttl = 1;
11311       else if (unformat (input, "checksum %d", &checksum_val))
11312         checksum = 1;
11313       else
11314         break;
11315     }
11316
11317   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11318       + ttl + checksum == 0)
11319     return 0;
11320
11321   /*
11322    * Aligned because we use the real comparison functions
11323    */
11324   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11325
11326   ip = (ip4_header_t *) match;
11327
11328   /* These are realistically matched in practice */
11329   if (src)
11330     ip->src_address.as_u32 = src_val.as_u32;
11331
11332   if (dst)
11333     ip->dst_address.as_u32 = dst_val.as_u32;
11334
11335   if (proto)
11336     ip->protocol = proto_val;
11337
11338
11339   /* These are not, but they're included for completeness */
11340   if (version)
11341     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11342
11343   if (hdr_length)
11344     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11345
11346   if (tos)
11347     ip->tos = tos_val;
11348
11349   if (length)
11350     ip->length = clib_host_to_net_u16 (length_val);
11351
11352   if (ttl)
11353     ip->ttl = ttl_val;
11354
11355   if (checksum)
11356     ip->checksum = clib_host_to_net_u16 (checksum_val);
11357
11358   *matchp = match;
11359   return 1;
11360 }
11361
11362 uword
11363 unformat_ip6_match (unformat_input_t * input, va_list * args)
11364 {
11365   u8 **matchp = va_arg (*args, u8 **);
11366   u8 *match = 0;
11367   ip6_header_t *ip;
11368   int version = 0;
11369   u32 version_val;
11370   u8 traffic_class = 0;
11371   u32 traffic_class_val = 0;
11372   u8 flow_label = 0;
11373   u8 flow_label_val;
11374   int src = 0, dst = 0;
11375   ip6_address_t src_val, dst_val;
11376   int proto = 0;
11377   u32 proto_val;
11378   int payload_length = 0;
11379   u32 payload_length_val;
11380   int hop_limit = 0;
11381   int hop_limit_val;
11382   u32 ip_version_traffic_class_and_flow_label;
11383
11384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11385     {
11386       if (unformat (input, "version %d", &version_val))
11387         version = 1;
11388       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11389         traffic_class = 1;
11390       else if (unformat (input, "flow_label %d", &flow_label_val))
11391         flow_label = 1;
11392       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11393         src = 1;
11394       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11395         dst = 1;
11396       else if (unformat (input, "proto %d", &proto_val))
11397         proto = 1;
11398       else if (unformat (input, "payload_length %d", &payload_length_val))
11399         payload_length = 1;
11400       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11401         hop_limit = 1;
11402       else
11403         break;
11404     }
11405
11406   if (version + traffic_class + flow_label + src + dst + proto +
11407       payload_length + hop_limit == 0)
11408     return 0;
11409
11410   /*
11411    * Aligned because we use the real comparison functions
11412    */
11413   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11414
11415   ip = (ip6_header_t *) match;
11416
11417   if (src)
11418     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11419
11420   if (dst)
11421     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11422
11423   if (proto)
11424     ip->protocol = proto_val;
11425
11426   ip_version_traffic_class_and_flow_label = 0;
11427
11428   if (version)
11429     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11430
11431   if (traffic_class)
11432     ip_version_traffic_class_and_flow_label |=
11433       (traffic_class_val & 0xFF) << 20;
11434
11435   if (flow_label)
11436     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11437
11438   ip->ip_version_traffic_class_and_flow_label =
11439     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11440
11441   if (payload_length)
11442     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11443
11444   if (hop_limit)
11445     ip->hop_limit = hop_limit_val;
11446
11447   *matchp = match;
11448   return 1;
11449 }
11450
11451 uword
11452 unformat_l3_match (unformat_input_t * input, va_list * args)
11453 {
11454   u8 **matchp = va_arg (*args, u8 **);
11455
11456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11457     {
11458       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11459         return 1;
11460       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11461         return 1;
11462       else
11463         break;
11464     }
11465   return 0;
11466 }
11467
11468 uword
11469 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11470 {
11471   u8 *tagp = va_arg (*args, u8 *);
11472   u32 tag;
11473
11474   if (unformat (input, "%d", &tag))
11475     {
11476       tagp[0] = (tag >> 8) & 0x0F;
11477       tagp[1] = tag & 0xFF;
11478       return 1;
11479     }
11480
11481   return 0;
11482 }
11483
11484 uword
11485 unformat_l2_match (unformat_input_t * input, va_list * args)
11486 {
11487   u8 **matchp = va_arg (*args, u8 **);
11488   u8 *match = 0;
11489   u8 src = 0;
11490   u8 src_val[6];
11491   u8 dst = 0;
11492   u8 dst_val[6];
11493   u8 proto = 0;
11494   u16 proto_val;
11495   u8 tag1 = 0;
11496   u8 tag1_val[2];
11497   u8 tag2 = 0;
11498   u8 tag2_val[2];
11499   int len = 14;
11500   u8 ignore_tag1 = 0;
11501   u8 ignore_tag2 = 0;
11502   u8 cos1 = 0;
11503   u8 cos2 = 0;
11504   u32 cos1_val = 0;
11505   u32 cos2_val = 0;
11506
11507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11508     {
11509       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11510         src = 1;
11511       else
11512         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11513         dst = 1;
11514       else if (unformat (input, "proto %U",
11515                          unformat_ethernet_type_host_byte_order, &proto_val))
11516         proto = 1;
11517       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11518         tag1 = 1;
11519       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11520         tag2 = 1;
11521       else if (unformat (input, "ignore-tag1"))
11522         ignore_tag1 = 1;
11523       else if (unformat (input, "ignore-tag2"))
11524         ignore_tag2 = 1;
11525       else if (unformat (input, "cos1 %d", &cos1_val))
11526         cos1 = 1;
11527       else if (unformat (input, "cos2 %d", &cos2_val))
11528         cos2 = 1;
11529       else
11530         break;
11531     }
11532   if ((src + dst + proto + tag1 + tag2 +
11533        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11534     return 0;
11535
11536   if (tag1 || ignore_tag1 || cos1)
11537     len = 18;
11538   if (tag2 || ignore_tag2 || cos2)
11539     len = 22;
11540
11541   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11542
11543   if (dst)
11544     clib_memcpy (match, dst_val, 6);
11545
11546   if (src)
11547     clib_memcpy (match + 6, src_val, 6);
11548
11549   if (tag2)
11550     {
11551       /* inner vlan tag */
11552       match[19] = tag2_val[1];
11553       match[18] = tag2_val[0];
11554       if (cos2)
11555         match[18] |= (cos2_val & 0x7) << 5;
11556       if (proto)
11557         {
11558           match[21] = proto_val & 0xff;
11559           match[20] = proto_val >> 8;
11560         }
11561       if (tag1)
11562         {
11563           match[15] = tag1_val[1];
11564           match[14] = tag1_val[0];
11565         }
11566       if (cos1)
11567         match[14] |= (cos1_val & 0x7) << 5;
11568       *matchp = match;
11569       return 1;
11570     }
11571   if (tag1)
11572     {
11573       match[15] = tag1_val[1];
11574       match[14] = tag1_val[0];
11575       if (proto)
11576         {
11577           match[17] = proto_val & 0xff;
11578           match[16] = proto_val >> 8;
11579         }
11580       if (cos1)
11581         match[14] |= (cos1_val & 0x7) << 5;
11582
11583       *matchp = match;
11584       return 1;
11585     }
11586   if (cos2)
11587     match[18] |= (cos2_val & 0x7) << 5;
11588   if (cos1)
11589     match[14] |= (cos1_val & 0x7) << 5;
11590   if (proto)
11591     {
11592       match[13] = proto_val & 0xff;
11593       match[12] = proto_val >> 8;
11594     }
11595
11596   *matchp = match;
11597   return 1;
11598 }
11599
11600 uword
11601 unformat_qos_source (unformat_input_t * input, va_list * args)
11602 {
11603   int *qs = va_arg (*args, int *);
11604
11605   if (unformat (input, "ip"))
11606     *qs = QOS_SOURCE_IP;
11607   else if (unformat (input, "mpls"))
11608     *qs = QOS_SOURCE_MPLS;
11609   else if (unformat (input, "ext"))
11610     *qs = QOS_SOURCE_EXT;
11611   else if (unformat (input, "vlan"))
11612     *qs = QOS_SOURCE_VLAN;
11613   else
11614     return 0;
11615
11616   return 1;
11617 }
11618 #endif
11619
11620 uword
11621 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11622 {
11623   u8 **matchp = va_arg (*args, u8 **);
11624   u32 skip_n_vectors = va_arg (*args, u32);
11625   u32 match_n_vectors = va_arg (*args, u32);
11626
11627   u8 *match = 0;
11628   u8 *l2 = 0;
11629   u8 *l3 = 0;
11630   u8 *l4 = 0;
11631
11632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11633     {
11634       if (unformat (input, "hex %U", unformat_hex_string, &match))
11635         ;
11636       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11637         ;
11638       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11639         ;
11640       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11641         ;
11642       else
11643         break;
11644     }
11645
11646   if (l4 && !l3)
11647     {
11648       vec_free (match);
11649       vec_free (l2);
11650       vec_free (l4);
11651       return 0;
11652     }
11653
11654   if (match || l2 || l3 || l4)
11655     {
11656       if (l2 || l3 || l4)
11657         {
11658           /* "Win a free Ethernet header in every packet" */
11659           if (l2 == 0)
11660             vec_validate_aligned (l2, 13, sizeof (u32x4));
11661           match = l2;
11662           if (vec_len (l3))
11663             {
11664               vec_append_aligned (match, l3, sizeof (u32x4));
11665               vec_free (l3);
11666             }
11667           if (vec_len (l4))
11668             {
11669               vec_append_aligned (match, l4, sizeof (u32x4));
11670               vec_free (l4);
11671             }
11672         }
11673
11674       /* Make sure the vector is big enough even if key is all 0's */
11675       vec_validate_aligned
11676         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11677          sizeof (u32x4));
11678
11679       /* Set size, include skipped vectors */
11680       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11681
11682       *matchp = match;
11683
11684       return 1;
11685     }
11686
11687   return 0;
11688 }
11689
11690 static int
11691 api_classify_add_del_session (vat_main_t * vam)
11692 {
11693   unformat_input_t *i = vam->input;
11694   vl_api_classify_add_del_session_t *mp;
11695   int is_add = 1;
11696   u32 table_index = ~0;
11697   u32 hit_next_index = ~0;
11698   u32 opaque_index = ~0;
11699   u8 *match = 0;
11700   i32 advance = 0;
11701   u32 skip_n_vectors = 0;
11702   u32 match_n_vectors = 0;
11703   u32 action = 0;
11704   u32 metadata = 0;
11705   int ret;
11706
11707   /*
11708    * Warning: you have to supply skip_n and match_n
11709    * because the API client cant simply look at the classify
11710    * table object.
11711    */
11712
11713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11714     {
11715       if (unformat (i, "del"))
11716         is_add = 0;
11717       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11718                          &hit_next_index))
11719         ;
11720       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11721                          &hit_next_index))
11722         ;
11723       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11724                          &hit_next_index))
11725         ;
11726       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11727         ;
11728       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11729         ;
11730       else if (unformat (i, "opaque-index %d", &opaque_index))
11731         ;
11732       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11733         ;
11734       else if (unformat (i, "match_n %d", &match_n_vectors))
11735         ;
11736       else if (unformat (i, "match %U", api_unformat_classify_match,
11737                          &match, skip_n_vectors, match_n_vectors))
11738         ;
11739       else if (unformat (i, "advance %d", &advance))
11740         ;
11741       else if (unformat (i, "table-index %d", &table_index))
11742         ;
11743       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11744         action = 1;
11745       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11746         action = 2;
11747       else if (unformat (i, "action %d", &action))
11748         ;
11749       else if (unformat (i, "metadata %d", &metadata))
11750         ;
11751       else
11752         break;
11753     }
11754
11755   if (table_index == ~0)
11756     {
11757       errmsg ("Table index required");
11758       return -99;
11759     }
11760
11761   if (is_add && match == 0)
11762     {
11763       errmsg ("Match value required");
11764       return -99;
11765     }
11766
11767   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11768
11769   mp->is_add = is_add;
11770   mp->table_index = ntohl (table_index);
11771   mp->hit_next_index = ntohl (hit_next_index);
11772   mp->opaque_index = ntohl (opaque_index);
11773   mp->advance = ntohl (advance);
11774   mp->action = action;
11775   mp->metadata = ntohl (metadata);
11776   mp->match_len = ntohl (vec_len (match));
11777   clib_memcpy (mp->match, match, vec_len (match));
11778   vec_free (match);
11779
11780   S (mp);
11781   W (ret);
11782   return ret;
11783 }
11784
11785 static int
11786 api_classify_set_interface_ip_table (vat_main_t * vam)
11787 {
11788   unformat_input_t *i = vam->input;
11789   vl_api_classify_set_interface_ip_table_t *mp;
11790   u32 sw_if_index;
11791   int sw_if_index_set;
11792   u32 table_index = ~0;
11793   u8 is_ipv6 = 0;
11794   int ret;
11795
11796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11797     {
11798       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11799         sw_if_index_set = 1;
11800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11801         sw_if_index_set = 1;
11802       else if (unformat (i, "table %d", &table_index))
11803         ;
11804       else
11805         {
11806           clib_warning ("parse error '%U'", format_unformat_error, i);
11807           return -99;
11808         }
11809     }
11810
11811   if (sw_if_index_set == 0)
11812     {
11813       errmsg ("missing interface name or sw_if_index");
11814       return -99;
11815     }
11816
11817
11818   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11819
11820   mp->sw_if_index = ntohl (sw_if_index);
11821   mp->table_index = ntohl (table_index);
11822   mp->is_ipv6 = is_ipv6;
11823
11824   S (mp);
11825   W (ret);
11826   return ret;
11827 }
11828
11829 static int
11830 api_classify_set_interface_l2_tables (vat_main_t * vam)
11831 {
11832   unformat_input_t *i = vam->input;
11833   vl_api_classify_set_interface_l2_tables_t *mp;
11834   u32 sw_if_index;
11835   int sw_if_index_set;
11836   u32 ip4_table_index = ~0;
11837   u32 ip6_table_index = ~0;
11838   u32 other_table_index = ~0;
11839   u32 is_input = 1;
11840   int ret;
11841
11842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11843     {
11844       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11845         sw_if_index_set = 1;
11846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11847         sw_if_index_set = 1;
11848       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11849         ;
11850       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11851         ;
11852       else if (unformat (i, "other-table %d", &other_table_index))
11853         ;
11854       else if (unformat (i, "is-input %d", &is_input))
11855         ;
11856       else
11857         {
11858           clib_warning ("parse error '%U'", format_unformat_error, i);
11859           return -99;
11860         }
11861     }
11862
11863   if (sw_if_index_set == 0)
11864     {
11865       errmsg ("missing interface name or sw_if_index");
11866       return -99;
11867     }
11868
11869
11870   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11871
11872   mp->sw_if_index = ntohl (sw_if_index);
11873   mp->ip4_table_index = ntohl (ip4_table_index);
11874   mp->ip6_table_index = ntohl (ip6_table_index);
11875   mp->other_table_index = ntohl (other_table_index);
11876   mp->is_input = (u8) is_input;
11877
11878   S (mp);
11879   W (ret);
11880   return ret;
11881 }
11882
11883 static int
11884 api_set_ipfix_exporter (vat_main_t * vam)
11885 {
11886   unformat_input_t *i = vam->input;
11887   vl_api_set_ipfix_exporter_t *mp;
11888   ip4_address_t collector_address;
11889   u8 collector_address_set = 0;
11890   u32 collector_port = ~0;
11891   ip4_address_t src_address;
11892   u8 src_address_set = 0;
11893   u32 vrf_id = ~0;
11894   u32 path_mtu = ~0;
11895   u32 template_interval = ~0;
11896   u8 udp_checksum = 0;
11897   int ret;
11898
11899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11900     {
11901       if (unformat (i, "collector_address %U", unformat_ip4_address,
11902                     &collector_address))
11903         collector_address_set = 1;
11904       else if (unformat (i, "collector_port %d", &collector_port))
11905         ;
11906       else if (unformat (i, "src_address %U", unformat_ip4_address,
11907                          &src_address))
11908         src_address_set = 1;
11909       else if (unformat (i, "vrf_id %d", &vrf_id))
11910         ;
11911       else if (unformat (i, "path_mtu %d", &path_mtu))
11912         ;
11913       else if (unformat (i, "template_interval %d", &template_interval))
11914         ;
11915       else if (unformat (i, "udp_checksum"))
11916         udp_checksum = 1;
11917       else
11918         break;
11919     }
11920
11921   if (collector_address_set == 0)
11922     {
11923       errmsg ("collector_address required");
11924       return -99;
11925     }
11926
11927   if (src_address_set == 0)
11928     {
11929       errmsg ("src_address required");
11930       return -99;
11931     }
11932
11933   M (SET_IPFIX_EXPORTER, mp);
11934
11935   memcpy (mp->collector_address, collector_address.data,
11936           sizeof (collector_address.data));
11937   mp->collector_port = htons ((u16) collector_port);
11938   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11939   mp->vrf_id = htonl (vrf_id);
11940   mp->path_mtu = htonl (path_mtu);
11941   mp->template_interval = htonl (template_interval);
11942   mp->udp_checksum = udp_checksum;
11943
11944   S (mp);
11945   W (ret);
11946   return ret;
11947 }
11948
11949 static int
11950 api_set_ipfix_classify_stream (vat_main_t * vam)
11951 {
11952   unformat_input_t *i = vam->input;
11953   vl_api_set_ipfix_classify_stream_t *mp;
11954   u32 domain_id = 0;
11955   u32 src_port = UDP_DST_PORT_ipfix;
11956   int ret;
11957
11958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11959     {
11960       if (unformat (i, "domain %d", &domain_id))
11961         ;
11962       else if (unformat (i, "src_port %d", &src_port))
11963         ;
11964       else
11965         {
11966           errmsg ("unknown input `%U'", format_unformat_error, i);
11967           return -99;
11968         }
11969     }
11970
11971   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11972
11973   mp->domain_id = htonl (domain_id);
11974   mp->src_port = htons ((u16) src_port);
11975
11976   S (mp);
11977   W (ret);
11978   return ret;
11979 }
11980
11981 static int
11982 api_ipfix_classify_table_add_del (vat_main_t * vam)
11983 {
11984   unformat_input_t *i = vam->input;
11985   vl_api_ipfix_classify_table_add_del_t *mp;
11986   int is_add = -1;
11987   u32 classify_table_index = ~0;
11988   u8 ip_version = 0;
11989   u8 transport_protocol = 255;
11990   int ret;
11991
11992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11993     {
11994       if (unformat (i, "add"))
11995         is_add = 1;
11996       else if (unformat (i, "del"))
11997         is_add = 0;
11998       else if (unformat (i, "table %d", &classify_table_index))
11999         ;
12000       else if (unformat (i, "ip4"))
12001         ip_version = 4;
12002       else if (unformat (i, "ip6"))
12003         ip_version = 6;
12004       else if (unformat (i, "tcp"))
12005         transport_protocol = 6;
12006       else if (unformat (i, "udp"))
12007         transport_protocol = 17;
12008       else
12009         {
12010           errmsg ("unknown input `%U'", format_unformat_error, i);
12011           return -99;
12012         }
12013     }
12014
12015   if (is_add == -1)
12016     {
12017       errmsg ("expecting: add|del");
12018       return -99;
12019     }
12020   if (classify_table_index == ~0)
12021     {
12022       errmsg ("classifier table not specified");
12023       return -99;
12024     }
12025   if (ip_version == 0)
12026     {
12027       errmsg ("IP version not specified");
12028       return -99;
12029     }
12030
12031   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12032
12033   mp->is_add = is_add;
12034   mp->table_id = htonl (classify_table_index);
12035   mp->ip_version = ip_version;
12036   mp->transport_protocol = transport_protocol;
12037
12038   S (mp);
12039   W (ret);
12040   return ret;
12041 }
12042
12043 static int
12044 api_get_node_index (vat_main_t * vam)
12045 {
12046   unformat_input_t *i = vam->input;
12047   vl_api_get_node_index_t *mp;
12048   u8 *name = 0;
12049   int ret;
12050
12051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12052     {
12053       if (unformat (i, "node %s", &name))
12054         ;
12055       else
12056         break;
12057     }
12058   if (name == 0)
12059     {
12060       errmsg ("node name required");
12061       return -99;
12062     }
12063   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12064     {
12065       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12066       return -99;
12067     }
12068
12069   M (GET_NODE_INDEX, mp);
12070   clib_memcpy (mp->node_name, name, vec_len (name));
12071   vec_free (name);
12072
12073   S (mp);
12074   W (ret);
12075   return ret;
12076 }
12077
12078 static int
12079 api_get_next_index (vat_main_t * vam)
12080 {
12081   unformat_input_t *i = vam->input;
12082   vl_api_get_next_index_t *mp;
12083   u8 *node_name = 0, *next_node_name = 0;
12084   int ret;
12085
12086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12087     {
12088       if (unformat (i, "node-name %s", &node_name))
12089         ;
12090       else if (unformat (i, "next-node-name %s", &next_node_name))
12091         break;
12092     }
12093
12094   if (node_name == 0)
12095     {
12096       errmsg ("node name required");
12097       return -99;
12098     }
12099   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12100     {
12101       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12102       return -99;
12103     }
12104
12105   if (next_node_name == 0)
12106     {
12107       errmsg ("next node name required");
12108       return -99;
12109     }
12110   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12111     {
12112       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12113       return -99;
12114     }
12115
12116   M (GET_NEXT_INDEX, mp);
12117   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12118   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12119   vec_free (node_name);
12120   vec_free (next_node_name);
12121
12122   S (mp);
12123   W (ret);
12124   return ret;
12125 }
12126
12127 static int
12128 api_add_node_next (vat_main_t * vam)
12129 {
12130   unformat_input_t *i = vam->input;
12131   vl_api_add_node_next_t *mp;
12132   u8 *name = 0;
12133   u8 *next = 0;
12134   int ret;
12135
12136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12137     {
12138       if (unformat (i, "node %s", &name))
12139         ;
12140       else if (unformat (i, "next %s", &next))
12141         ;
12142       else
12143         break;
12144     }
12145   if (name == 0)
12146     {
12147       errmsg ("node name required");
12148       return -99;
12149     }
12150   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12151     {
12152       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12153       return -99;
12154     }
12155   if (next == 0)
12156     {
12157       errmsg ("next node required");
12158       return -99;
12159     }
12160   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12161     {
12162       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12163       return -99;
12164     }
12165
12166   M (ADD_NODE_NEXT, mp);
12167   clib_memcpy (mp->node_name, name, vec_len (name));
12168   clib_memcpy (mp->next_name, next, vec_len (next));
12169   vec_free (name);
12170   vec_free (next);
12171
12172   S (mp);
12173   W (ret);
12174   return ret;
12175 }
12176
12177 static int
12178 api_l2tpv3_create_tunnel (vat_main_t * vam)
12179 {
12180   unformat_input_t *i = vam->input;
12181   ip6_address_t client_address, our_address;
12182   int client_address_set = 0;
12183   int our_address_set = 0;
12184   u32 local_session_id = 0;
12185   u32 remote_session_id = 0;
12186   u64 local_cookie = 0;
12187   u64 remote_cookie = 0;
12188   u8 l2_sublayer_present = 0;
12189   vl_api_l2tpv3_create_tunnel_t *mp;
12190   int ret;
12191
12192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12193     {
12194       if (unformat (i, "client_address %U", unformat_ip6_address,
12195                     &client_address))
12196         client_address_set = 1;
12197       else if (unformat (i, "our_address %U", unformat_ip6_address,
12198                          &our_address))
12199         our_address_set = 1;
12200       else if (unformat (i, "local_session_id %d", &local_session_id))
12201         ;
12202       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12203         ;
12204       else if (unformat (i, "local_cookie %lld", &local_cookie))
12205         ;
12206       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12207         ;
12208       else if (unformat (i, "l2-sublayer-present"))
12209         l2_sublayer_present = 1;
12210       else
12211         break;
12212     }
12213
12214   if (client_address_set == 0)
12215     {
12216       errmsg ("client_address required");
12217       return -99;
12218     }
12219
12220   if (our_address_set == 0)
12221     {
12222       errmsg ("our_address required");
12223       return -99;
12224     }
12225
12226   M (L2TPV3_CREATE_TUNNEL, mp);
12227
12228   clib_memcpy (mp->client_address, client_address.as_u8,
12229                sizeof (mp->client_address));
12230
12231   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12232
12233   mp->local_session_id = ntohl (local_session_id);
12234   mp->remote_session_id = ntohl (remote_session_id);
12235   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12236   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12237   mp->l2_sublayer_present = l2_sublayer_present;
12238   mp->is_ipv6 = 1;
12239
12240   S (mp);
12241   W (ret);
12242   return ret;
12243 }
12244
12245 static int
12246 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12247 {
12248   unformat_input_t *i = vam->input;
12249   u32 sw_if_index;
12250   u8 sw_if_index_set = 0;
12251   u64 new_local_cookie = 0;
12252   u64 new_remote_cookie = 0;
12253   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12254   int ret;
12255
12256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12257     {
12258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12259         sw_if_index_set = 1;
12260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12261         sw_if_index_set = 1;
12262       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12263         ;
12264       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12265         ;
12266       else
12267         break;
12268     }
12269
12270   if (sw_if_index_set == 0)
12271     {
12272       errmsg ("missing interface name or sw_if_index");
12273       return -99;
12274     }
12275
12276   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12277
12278   mp->sw_if_index = ntohl (sw_if_index);
12279   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12280   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12281
12282   S (mp);
12283   W (ret);
12284   return ret;
12285 }
12286
12287 static int
12288 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12289 {
12290   unformat_input_t *i = vam->input;
12291   vl_api_l2tpv3_interface_enable_disable_t *mp;
12292   u32 sw_if_index;
12293   u8 sw_if_index_set = 0;
12294   u8 enable_disable = 1;
12295   int ret;
12296
12297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12298     {
12299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12300         sw_if_index_set = 1;
12301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12302         sw_if_index_set = 1;
12303       else if (unformat (i, "enable"))
12304         enable_disable = 1;
12305       else if (unformat (i, "disable"))
12306         enable_disable = 0;
12307       else
12308         break;
12309     }
12310
12311   if (sw_if_index_set == 0)
12312     {
12313       errmsg ("missing interface name or sw_if_index");
12314       return -99;
12315     }
12316
12317   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12318
12319   mp->sw_if_index = ntohl (sw_if_index);
12320   mp->enable_disable = enable_disable;
12321
12322   S (mp);
12323   W (ret);
12324   return ret;
12325 }
12326
12327 static int
12328 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12329 {
12330   unformat_input_t *i = vam->input;
12331   vl_api_l2tpv3_set_lookup_key_t *mp;
12332   u8 key = ~0;
12333   int ret;
12334
12335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12336     {
12337       if (unformat (i, "lookup_v6_src"))
12338         key = L2T_LOOKUP_SRC_ADDRESS;
12339       else if (unformat (i, "lookup_v6_dst"))
12340         key = L2T_LOOKUP_DST_ADDRESS;
12341       else if (unformat (i, "lookup_session_id"))
12342         key = L2T_LOOKUP_SESSION_ID;
12343       else
12344         break;
12345     }
12346
12347   if (key == (u8) ~ 0)
12348     {
12349       errmsg ("l2tp session lookup key unset");
12350       return -99;
12351     }
12352
12353   M (L2TPV3_SET_LOOKUP_KEY, mp);
12354
12355   mp->key = key;
12356
12357   S (mp);
12358   W (ret);
12359   return ret;
12360 }
12361
12362 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12363   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12364 {
12365   vat_main_t *vam = &vat_main;
12366
12367   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12368          format_ip6_address, mp->our_address,
12369          format_ip6_address, mp->client_address,
12370          clib_net_to_host_u32 (mp->sw_if_index));
12371
12372   print (vam->ofp,
12373          "   local cookies %016llx %016llx remote cookie %016llx",
12374          clib_net_to_host_u64 (mp->local_cookie[0]),
12375          clib_net_to_host_u64 (mp->local_cookie[1]),
12376          clib_net_to_host_u64 (mp->remote_cookie));
12377
12378   print (vam->ofp, "   local session-id %d remote session-id %d",
12379          clib_net_to_host_u32 (mp->local_session_id),
12380          clib_net_to_host_u32 (mp->remote_session_id));
12381
12382   print (vam->ofp, "   l2 specific sublayer %s\n",
12383          mp->l2_sublayer_present ? "preset" : "absent");
12384
12385 }
12386
12387 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12388   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12389 {
12390   vat_main_t *vam = &vat_main;
12391   vat_json_node_t *node = NULL;
12392   struct in6_addr addr;
12393
12394   if (VAT_JSON_ARRAY != vam->json_tree.type)
12395     {
12396       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12397       vat_json_init_array (&vam->json_tree);
12398     }
12399   node = vat_json_array_add (&vam->json_tree);
12400
12401   vat_json_init_object (node);
12402
12403   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12404   vat_json_object_add_ip6 (node, "our_address", addr);
12405   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12406   vat_json_object_add_ip6 (node, "client_address", addr);
12407
12408   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12409   vat_json_init_array (lc);
12410   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12411   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12412   vat_json_object_add_uint (node, "remote_cookie",
12413                             clib_net_to_host_u64 (mp->remote_cookie));
12414
12415   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12416   vat_json_object_add_uint (node, "local_session_id",
12417                             clib_net_to_host_u32 (mp->local_session_id));
12418   vat_json_object_add_uint (node, "remote_session_id",
12419                             clib_net_to_host_u32 (mp->remote_session_id));
12420   vat_json_object_add_string_copy (node, "l2_sublayer",
12421                                    mp->l2_sublayer_present ? (u8 *) "present"
12422                                    : (u8 *) "absent");
12423 }
12424
12425 static int
12426 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12427 {
12428   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12429   vl_api_control_ping_t *mp_ping;
12430   int ret;
12431
12432   /* Get list of l2tpv3-tunnel interfaces */
12433   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12434   S (mp);
12435
12436   /* Use a control ping for synchronization */
12437   MPING (CONTROL_PING, mp_ping);
12438   S (mp_ping);
12439
12440   W (ret);
12441   return ret;
12442 }
12443
12444
12445 static void vl_api_sw_interface_tap_v2_details_t_handler
12446   (vl_api_sw_interface_tap_v2_details_t * mp)
12447 {
12448   vat_main_t *vam = &vat_main;
12449
12450   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12451                     mp->host_ip4_prefix_len);
12452   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12453                     mp->host_ip6_prefix_len);
12454
12455   print (vam->ofp,
12456          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12457          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12458          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12459          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12460          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12461
12462   vec_free (ip4);
12463   vec_free (ip6);
12464 }
12465
12466 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12467   (vl_api_sw_interface_tap_v2_details_t * mp)
12468 {
12469   vat_main_t *vam = &vat_main;
12470   vat_json_node_t *node = NULL;
12471
12472   if (VAT_JSON_ARRAY != vam->json_tree.type)
12473     {
12474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12475       vat_json_init_array (&vam->json_tree);
12476     }
12477   node = vat_json_array_add (&vam->json_tree);
12478
12479   vat_json_init_object (node);
12480   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12482   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12483   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12484   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12485   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12486   vat_json_object_add_string_copy (node, "host_mac_addr",
12487                                    format (0, "%U", format_ethernet_address,
12488                                            &mp->host_mac_addr));
12489   vat_json_object_add_string_copy (node, "host_namespace",
12490                                    mp->host_namespace);
12491   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12492   vat_json_object_add_string_copy (node, "host_ip4_addr",
12493                                    format (0, "%U/%d", format_ip4_address,
12494                                            mp->host_ip4_addr,
12495                                            mp->host_ip4_prefix_len));
12496   vat_json_object_add_string_copy (node, "host_ip6_addr",
12497                                    format (0, "%U/%d", format_ip6_address,
12498                                            mp->host_ip6_addr,
12499                                            mp->host_ip6_prefix_len));
12500
12501 }
12502
12503 static int
12504 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12505 {
12506   vl_api_sw_interface_tap_v2_dump_t *mp;
12507   vl_api_control_ping_t *mp_ping;
12508   int ret;
12509
12510   print (vam->ofp,
12511          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12512          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12513          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12514          "host_ip6_addr");
12515
12516   /* Get list of tap interfaces */
12517   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12518   S (mp);
12519
12520   /* Use a control ping for synchronization */
12521   MPING (CONTROL_PING, mp_ping);
12522   S (mp_ping);
12523
12524   W (ret);
12525   return ret;
12526 }
12527
12528 static void vl_api_sw_interface_virtio_pci_details_t_handler
12529   (vl_api_sw_interface_virtio_pci_details_t * mp)
12530 {
12531   vat_main_t *vam = &vat_main;
12532
12533   typedef union
12534   {
12535     struct
12536     {
12537       u16 domain;
12538       u8 bus;
12539       u8 slot:5;
12540       u8 function:3;
12541     };
12542     u32 as_u32;
12543   } pci_addr_t;
12544   pci_addr_t addr;
12545   addr.as_u32 = ntohl (mp->pci_addr);
12546   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12547                          addr.slot, addr.function);
12548
12549   print (vam->ofp,
12550          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12551          pci_addr, ntohl (mp->sw_if_index),
12552          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12553          format_ethernet_address, mp->mac_addr,
12554          clib_net_to_host_u64 (mp->features));
12555   vec_free (pci_addr);
12556 }
12557
12558 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12559   (vl_api_sw_interface_virtio_pci_details_t * mp)
12560 {
12561   vat_main_t *vam = &vat_main;
12562   vat_json_node_t *node = NULL;
12563
12564   if (VAT_JSON_ARRAY != vam->json_tree.type)
12565     {
12566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12567       vat_json_init_array (&vam->json_tree);
12568     }
12569   node = vat_json_array_add (&vam->json_tree);
12570
12571   vat_json_init_object (node);
12572   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12573   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12574   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12575   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12576   vat_json_object_add_uint (node, "features",
12577                             clib_net_to_host_u64 (mp->features));
12578   vat_json_object_add_string_copy (node, "mac_addr",
12579                                    format (0, "%U", format_ethernet_address,
12580                                            &mp->mac_addr));
12581 }
12582
12583 static int
12584 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12585 {
12586   vl_api_sw_interface_virtio_pci_dump_t *mp;
12587   vl_api_control_ping_t *mp_ping;
12588   int ret;
12589
12590   print (vam->ofp,
12591          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12592          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12593          "mac_addr", "features");
12594
12595   /* Get list of tap interfaces */
12596   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12597   S (mp);
12598
12599   /* Use a control ping for synchronization */
12600   MPING (CONTROL_PING, mp_ping);
12601   S (mp_ping);
12602
12603   W (ret);
12604   return ret;
12605 }
12606
12607 static int
12608 api_vxlan_offload_rx (vat_main_t * vam)
12609 {
12610   unformat_input_t *line_input = vam->input;
12611   vl_api_vxlan_offload_rx_t *mp;
12612   u32 hw_if_index = ~0, rx_if_index = ~0;
12613   u8 is_add = 1;
12614   int ret;
12615
12616   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12617     {
12618       if (unformat (line_input, "del"))
12619         is_add = 0;
12620       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12621                          &hw_if_index))
12622         ;
12623       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12624         ;
12625       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12626                          &rx_if_index))
12627         ;
12628       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12629         ;
12630       else
12631         {
12632           errmsg ("parse error '%U'", format_unformat_error, line_input);
12633           return -99;
12634         }
12635     }
12636
12637   if (hw_if_index == ~0)
12638     {
12639       errmsg ("no hw interface");
12640       return -99;
12641     }
12642
12643   if (rx_if_index == ~0)
12644     {
12645       errmsg ("no rx tunnel");
12646       return -99;
12647     }
12648
12649   M (VXLAN_OFFLOAD_RX, mp);
12650
12651   mp->hw_if_index = ntohl (hw_if_index);
12652   mp->sw_if_index = ntohl (rx_if_index);
12653   mp->enable = is_add;
12654
12655   S (mp);
12656   W (ret);
12657   return ret;
12658 }
12659
12660 static uword unformat_vxlan_decap_next
12661   (unformat_input_t * input, va_list * args)
12662 {
12663   u32 *result = va_arg (*args, u32 *);
12664   u32 tmp;
12665
12666   if (unformat (input, "l2"))
12667     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12668   else if (unformat (input, "%d", &tmp))
12669     *result = tmp;
12670   else
12671     return 0;
12672   return 1;
12673 }
12674
12675 static int
12676 api_vxlan_add_del_tunnel (vat_main_t * vam)
12677 {
12678   unformat_input_t *line_input = vam->input;
12679   vl_api_vxlan_add_del_tunnel_t *mp;
12680   ip46_address_t src, dst;
12681   u8 is_add = 1;
12682   u8 ipv4_set = 0, ipv6_set = 0;
12683   u8 src_set = 0;
12684   u8 dst_set = 0;
12685   u8 grp_set = 0;
12686   u32 instance = ~0;
12687   u32 mcast_sw_if_index = ~0;
12688   u32 encap_vrf_id = 0;
12689   u32 decap_next_index = ~0;
12690   u32 vni = 0;
12691   int ret;
12692
12693   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12694   clib_memset (&src, 0, sizeof src);
12695   clib_memset (&dst, 0, sizeof dst);
12696
12697   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12698     {
12699       if (unformat (line_input, "del"))
12700         is_add = 0;
12701       else if (unformat (line_input, "instance %d", &instance))
12702         ;
12703       else
12704         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12705         {
12706           ipv4_set = 1;
12707           src_set = 1;
12708         }
12709       else
12710         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12711         {
12712           ipv4_set = 1;
12713           dst_set = 1;
12714         }
12715       else
12716         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12717         {
12718           ipv6_set = 1;
12719           src_set = 1;
12720         }
12721       else
12722         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12723         {
12724           ipv6_set = 1;
12725           dst_set = 1;
12726         }
12727       else if (unformat (line_input, "group %U %U",
12728                          unformat_ip4_address, &dst.ip4,
12729                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12730         {
12731           grp_set = dst_set = 1;
12732           ipv4_set = 1;
12733         }
12734       else if (unformat (line_input, "group %U",
12735                          unformat_ip4_address, &dst.ip4))
12736         {
12737           grp_set = dst_set = 1;
12738           ipv4_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U %U",
12741                          unformat_ip6_address, &dst.ip6,
12742                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12743         {
12744           grp_set = dst_set = 1;
12745           ipv6_set = 1;
12746         }
12747       else if (unformat (line_input, "group %U",
12748                          unformat_ip6_address, &dst.ip6))
12749         {
12750           grp_set = dst_set = 1;
12751           ipv6_set = 1;
12752         }
12753       else
12754         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12755         ;
12756       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12757         ;
12758       else if (unformat (line_input, "decap-next %U",
12759                          unformat_vxlan_decap_next, &decap_next_index))
12760         ;
12761       else if (unformat (line_input, "vni %d", &vni))
12762         ;
12763       else
12764         {
12765           errmsg ("parse error '%U'", format_unformat_error, line_input);
12766           return -99;
12767         }
12768     }
12769
12770   if (src_set == 0)
12771     {
12772       errmsg ("tunnel src address not specified");
12773       return -99;
12774     }
12775   if (dst_set == 0)
12776     {
12777       errmsg ("tunnel dst address not specified");
12778       return -99;
12779     }
12780
12781   if (grp_set && !ip46_address_is_multicast (&dst))
12782     {
12783       errmsg ("tunnel group address not multicast");
12784       return -99;
12785     }
12786   if (grp_set && mcast_sw_if_index == ~0)
12787     {
12788       errmsg ("tunnel nonexistent multicast device");
12789       return -99;
12790     }
12791   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12792     {
12793       errmsg ("tunnel dst address must be unicast");
12794       return -99;
12795     }
12796
12797
12798   if (ipv4_set && ipv6_set)
12799     {
12800       errmsg ("both IPv4 and IPv6 addresses specified");
12801       return -99;
12802     }
12803
12804   if ((vni == 0) || (vni >> 24))
12805     {
12806       errmsg ("vni not specified or out of range");
12807       return -99;
12808     }
12809
12810   M (VXLAN_ADD_DEL_TUNNEL, mp);
12811
12812   if (ipv6_set)
12813     {
12814       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12815       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12816     }
12817   else
12818     {
12819       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12820       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12821     }
12822
12823   mp->instance = htonl (instance);
12824   mp->encap_vrf_id = ntohl (encap_vrf_id);
12825   mp->decap_next_index = ntohl (decap_next_index);
12826   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12827   mp->vni = ntohl (vni);
12828   mp->is_add = is_add;
12829   mp->is_ipv6 = ipv6_set;
12830
12831   S (mp);
12832   W (ret);
12833   return ret;
12834 }
12835
12836 static void vl_api_vxlan_tunnel_details_t_handler
12837   (vl_api_vxlan_tunnel_details_t * mp)
12838 {
12839   vat_main_t *vam = &vat_main;
12840   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12841   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12842
12843   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12844          ntohl (mp->sw_if_index),
12845          ntohl (mp->instance),
12846          format_ip46_address, &src, IP46_TYPE_ANY,
12847          format_ip46_address, &dst, IP46_TYPE_ANY,
12848          ntohl (mp->encap_vrf_id),
12849          ntohl (mp->decap_next_index), ntohl (mp->vni),
12850          ntohl (mp->mcast_sw_if_index));
12851 }
12852
12853 static void vl_api_vxlan_tunnel_details_t_handler_json
12854   (vl_api_vxlan_tunnel_details_t * mp)
12855 {
12856   vat_main_t *vam = &vat_main;
12857   vat_json_node_t *node = NULL;
12858
12859   if (VAT_JSON_ARRAY != vam->json_tree.type)
12860     {
12861       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12862       vat_json_init_array (&vam->json_tree);
12863     }
12864   node = vat_json_array_add (&vam->json_tree);
12865
12866   vat_json_init_object (node);
12867   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12868
12869   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12870
12871   if (mp->is_ipv6)
12872     {
12873       struct in6_addr ip6;
12874
12875       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12876       vat_json_object_add_ip6 (node, "src_address", ip6);
12877       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12878       vat_json_object_add_ip6 (node, "dst_address", ip6);
12879     }
12880   else
12881     {
12882       struct in_addr ip4;
12883
12884       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12885       vat_json_object_add_ip4 (node, "src_address", ip4);
12886       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12887       vat_json_object_add_ip4 (node, "dst_address", ip4);
12888     }
12889   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12890   vat_json_object_add_uint (node, "decap_next_index",
12891                             ntohl (mp->decap_next_index));
12892   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12893   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12894   vat_json_object_add_uint (node, "mcast_sw_if_index",
12895                             ntohl (mp->mcast_sw_if_index));
12896 }
12897
12898 static int
12899 api_vxlan_tunnel_dump (vat_main_t * vam)
12900 {
12901   unformat_input_t *i = vam->input;
12902   vl_api_vxlan_tunnel_dump_t *mp;
12903   vl_api_control_ping_t *mp_ping;
12904   u32 sw_if_index;
12905   u8 sw_if_index_set = 0;
12906   int ret;
12907
12908   /* Parse args required to build the message */
12909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12910     {
12911       if (unformat (i, "sw_if_index %d", &sw_if_index))
12912         sw_if_index_set = 1;
12913       else
12914         break;
12915     }
12916
12917   if (sw_if_index_set == 0)
12918     {
12919       sw_if_index = ~0;
12920     }
12921
12922   if (!vam->json_output)
12923     {
12924       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12925              "sw_if_index", "instance", "src_address", "dst_address",
12926              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12927     }
12928
12929   /* Get list of vxlan-tunnel interfaces */
12930   M (VXLAN_TUNNEL_DUMP, mp);
12931
12932   mp->sw_if_index = htonl (sw_if_index);
12933
12934   S (mp);
12935
12936   /* Use a control ping for synchronization */
12937   MPING (CONTROL_PING, mp_ping);
12938   S (mp_ping);
12939
12940   W (ret);
12941   return ret;
12942 }
12943
12944 static uword unformat_geneve_decap_next
12945   (unformat_input_t * input, va_list * args)
12946 {
12947   u32 *result = va_arg (*args, u32 *);
12948   u32 tmp;
12949
12950   if (unformat (input, "l2"))
12951     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12952   else if (unformat (input, "%d", &tmp))
12953     *result = tmp;
12954   else
12955     return 0;
12956   return 1;
12957 }
12958
12959 static int
12960 api_geneve_add_del_tunnel (vat_main_t * vam)
12961 {
12962   unformat_input_t *line_input = vam->input;
12963   vl_api_geneve_add_del_tunnel_t *mp;
12964   ip46_address_t src, dst;
12965   u8 is_add = 1;
12966   u8 ipv4_set = 0, ipv6_set = 0;
12967   u8 src_set = 0;
12968   u8 dst_set = 0;
12969   u8 grp_set = 0;
12970   u32 mcast_sw_if_index = ~0;
12971   u32 encap_vrf_id = 0;
12972   u32 decap_next_index = ~0;
12973   u32 vni = 0;
12974   int ret;
12975
12976   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12977   clib_memset (&src, 0, sizeof src);
12978   clib_memset (&dst, 0, sizeof dst);
12979
12980   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12981     {
12982       if (unformat (line_input, "del"))
12983         is_add = 0;
12984       else
12985         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12986         {
12987           ipv4_set = 1;
12988           src_set = 1;
12989         }
12990       else
12991         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12992         {
12993           ipv4_set = 1;
12994           dst_set = 1;
12995         }
12996       else
12997         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12998         {
12999           ipv6_set = 1;
13000           src_set = 1;
13001         }
13002       else
13003         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13004         {
13005           ipv6_set = 1;
13006           dst_set = 1;
13007         }
13008       else if (unformat (line_input, "group %U %U",
13009                          unformat_ip4_address, &dst.ip4,
13010                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13011         {
13012           grp_set = dst_set = 1;
13013           ipv4_set = 1;
13014         }
13015       else if (unformat (line_input, "group %U",
13016                          unformat_ip4_address, &dst.ip4))
13017         {
13018           grp_set = dst_set = 1;
13019           ipv4_set = 1;
13020         }
13021       else if (unformat (line_input, "group %U %U",
13022                          unformat_ip6_address, &dst.ip6,
13023                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13024         {
13025           grp_set = dst_set = 1;
13026           ipv6_set = 1;
13027         }
13028       else if (unformat (line_input, "group %U",
13029                          unformat_ip6_address, &dst.ip6))
13030         {
13031           grp_set = dst_set = 1;
13032           ipv6_set = 1;
13033         }
13034       else
13035         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13036         ;
13037       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13038         ;
13039       else if (unformat (line_input, "decap-next %U",
13040                          unformat_geneve_decap_next, &decap_next_index))
13041         ;
13042       else if (unformat (line_input, "vni %d", &vni))
13043         ;
13044       else
13045         {
13046           errmsg ("parse error '%U'", format_unformat_error, line_input);
13047           return -99;
13048         }
13049     }
13050
13051   if (src_set == 0)
13052     {
13053       errmsg ("tunnel src address not specified");
13054       return -99;
13055     }
13056   if (dst_set == 0)
13057     {
13058       errmsg ("tunnel dst address not specified");
13059       return -99;
13060     }
13061
13062   if (grp_set && !ip46_address_is_multicast (&dst))
13063     {
13064       errmsg ("tunnel group address not multicast");
13065       return -99;
13066     }
13067   if (grp_set && mcast_sw_if_index == ~0)
13068     {
13069       errmsg ("tunnel nonexistent multicast device");
13070       return -99;
13071     }
13072   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13073     {
13074       errmsg ("tunnel dst address must be unicast");
13075       return -99;
13076     }
13077
13078
13079   if (ipv4_set && ipv6_set)
13080     {
13081       errmsg ("both IPv4 and IPv6 addresses specified");
13082       return -99;
13083     }
13084
13085   if ((vni == 0) || (vni >> 24))
13086     {
13087       errmsg ("vni not specified or out of range");
13088       return -99;
13089     }
13090
13091   M (GENEVE_ADD_DEL_TUNNEL, mp);
13092
13093   if (ipv6_set)
13094     {
13095       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13096       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13097     }
13098   else
13099     {
13100       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13101       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13102     }
13103   mp->encap_vrf_id = ntohl (encap_vrf_id);
13104   mp->decap_next_index = ntohl (decap_next_index);
13105   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13106   mp->vni = ntohl (vni);
13107   mp->is_add = is_add;
13108   mp->is_ipv6 = ipv6_set;
13109
13110   S (mp);
13111   W (ret);
13112   return ret;
13113 }
13114
13115 static void vl_api_geneve_tunnel_details_t_handler
13116   (vl_api_geneve_tunnel_details_t * mp)
13117 {
13118   vat_main_t *vam = &vat_main;
13119   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13120   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13121
13122   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13123          ntohl (mp->sw_if_index),
13124          format_ip46_address, &src, IP46_TYPE_ANY,
13125          format_ip46_address, &dst, IP46_TYPE_ANY,
13126          ntohl (mp->encap_vrf_id),
13127          ntohl (mp->decap_next_index), ntohl (mp->vni),
13128          ntohl (mp->mcast_sw_if_index));
13129 }
13130
13131 static void vl_api_geneve_tunnel_details_t_handler_json
13132   (vl_api_geneve_tunnel_details_t * mp)
13133 {
13134   vat_main_t *vam = &vat_main;
13135   vat_json_node_t *node = NULL;
13136
13137   if (VAT_JSON_ARRAY != vam->json_tree.type)
13138     {
13139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13140       vat_json_init_array (&vam->json_tree);
13141     }
13142   node = vat_json_array_add (&vam->json_tree);
13143
13144   vat_json_init_object (node);
13145   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13146   if (mp->is_ipv6)
13147     {
13148       struct in6_addr ip6;
13149
13150       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13151       vat_json_object_add_ip6 (node, "src_address", ip6);
13152       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13153       vat_json_object_add_ip6 (node, "dst_address", ip6);
13154     }
13155   else
13156     {
13157       struct in_addr ip4;
13158
13159       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13160       vat_json_object_add_ip4 (node, "src_address", ip4);
13161       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13162       vat_json_object_add_ip4 (node, "dst_address", ip4);
13163     }
13164   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13165   vat_json_object_add_uint (node, "decap_next_index",
13166                             ntohl (mp->decap_next_index));
13167   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13168   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13169   vat_json_object_add_uint (node, "mcast_sw_if_index",
13170                             ntohl (mp->mcast_sw_if_index));
13171 }
13172
13173 static int
13174 api_geneve_tunnel_dump (vat_main_t * vam)
13175 {
13176   unformat_input_t *i = vam->input;
13177   vl_api_geneve_tunnel_dump_t *mp;
13178   vl_api_control_ping_t *mp_ping;
13179   u32 sw_if_index;
13180   u8 sw_if_index_set = 0;
13181   int ret;
13182
13183   /* Parse args required to build the message */
13184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13185     {
13186       if (unformat (i, "sw_if_index %d", &sw_if_index))
13187         sw_if_index_set = 1;
13188       else
13189         break;
13190     }
13191
13192   if (sw_if_index_set == 0)
13193     {
13194       sw_if_index = ~0;
13195     }
13196
13197   if (!vam->json_output)
13198     {
13199       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13200              "sw_if_index", "local_address", "remote_address",
13201              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13202     }
13203
13204   /* Get list of geneve-tunnel interfaces */
13205   M (GENEVE_TUNNEL_DUMP, mp);
13206
13207   mp->sw_if_index = htonl (sw_if_index);
13208
13209   S (mp);
13210
13211   /* Use a control ping for synchronization */
13212   M (CONTROL_PING, mp_ping);
13213   S (mp_ping);
13214
13215   W (ret);
13216   return ret;
13217 }
13218
13219 static int
13220 api_gre_tunnel_add_del (vat_main_t * vam)
13221 {
13222   unformat_input_t *line_input = vam->input;
13223   vl_api_address_t src = { }, dst =
13224   {
13225   };
13226   vl_api_gre_tunnel_add_del_t *mp;
13227   vl_api_gre_tunnel_type_t t_type;
13228   u8 is_add = 1;
13229   u8 src_set = 0;
13230   u8 dst_set = 0;
13231   u32 outer_fib_id = 0;
13232   u32 session_id = 0;
13233   u32 instance = ~0;
13234   int ret;
13235
13236   t_type = GRE_API_TUNNEL_TYPE_L3;
13237
13238   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (line_input, "del"))
13241         is_add = 0;
13242       else if (unformat (line_input, "instance %d", &instance))
13243         ;
13244       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13245         {
13246           src_set = 1;
13247         }
13248       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13249         {
13250           dst_set = 1;
13251         }
13252       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13253         ;
13254       else if (unformat (line_input, "teb"))
13255         t_type = GRE_API_TUNNEL_TYPE_TEB;
13256       else if (unformat (line_input, "erspan %d", &session_id))
13257         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13258       else
13259         {
13260           errmsg ("parse error '%U'", format_unformat_error, line_input);
13261           return -99;
13262         }
13263     }
13264
13265   if (src_set == 0)
13266     {
13267       errmsg ("tunnel src address not specified");
13268       return -99;
13269     }
13270   if (dst_set == 0)
13271     {
13272       errmsg ("tunnel dst address not specified");
13273       return -99;
13274     }
13275
13276   M (GRE_TUNNEL_ADD_DEL, mp);
13277
13278   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13279   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13280
13281   mp->tunnel.instance = htonl (instance);
13282   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13283   mp->is_add = is_add;
13284   mp->tunnel.session_id = htons ((u16) session_id);
13285   mp->tunnel.type = htonl (t_type);
13286
13287   S (mp);
13288   W (ret);
13289   return ret;
13290 }
13291
13292 static void vl_api_gre_tunnel_details_t_handler
13293   (vl_api_gre_tunnel_details_t * mp)
13294 {
13295   vat_main_t *vam = &vat_main;
13296
13297   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13298          ntohl (mp->tunnel.sw_if_index),
13299          ntohl (mp->tunnel.instance),
13300          format_vl_api_address, &mp->tunnel.src,
13301          format_vl_api_address, &mp->tunnel.dst,
13302          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13303          ntohl (mp->tunnel.session_id));
13304 }
13305
13306 static void
13307 vat_json_object_add_address (vat_json_node_t * node,
13308                              const char *str, const vl_api_address_t * addr)
13309 {
13310   if (ADDRESS_IP6 == addr->af)
13311     {
13312       struct in6_addr ip6;
13313
13314       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13315       vat_json_object_add_ip6 (node, str, ip6);
13316     }
13317   else
13318     {
13319       struct in_addr ip4;
13320
13321       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13322       vat_json_object_add_ip4 (node, str, ip4);
13323     }
13324 }
13325
13326 static void vl_api_gre_tunnel_details_t_handler_json
13327   (vl_api_gre_tunnel_details_t * mp)
13328 {
13329   vat_main_t *vam = &vat_main;
13330   vat_json_node_t *node = NULL;
13331
13332   if (VAT_JSON_ARRAY != vam->json_tree.type)
13333     {
13334       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13335       vat_json_init_array (&vam->json_tree);
13336     }
13337   node = vat_json_array_add (&vam->json_tree);
13338
13339   vat_json_init_object (node);
13340   vat_json_object_add_uint (node, "sw_if_index",
13341                             ntohl (mp->tunnel.sw_if_index));
13342   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13343
13344   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13345   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13346   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13347   vat_json_object_add_uint (node, "outer_fib_id",
13348                             ntohl (mp->tunnel.outer_fib_id));
13349   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13350 }
13351
13352 static int
13353 api_gre_tunnel_dump (vat_main_t * vam)
13354 {
13355   unformat_input_t *i = vam->input;
13356   vl_api_gre_tunnel_dump_t *mp;
13357   vl_api_control_ping_t *mp_ping;
13358   u32 sw_if_index;
13359   u8 sw_if_index_set = 0;
13360   int ret;
13361
13362   /* Parse args required to build the message */
13363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13364     {
13365       if (unformat (i, "sw_if_index %d", &sw_if_index))
13366         sw_if_index_set = 1;
13367       else
13368         break;
13369     }
13370
13371   if (sw_if_index_set == 0)
13372     {
13373       sw_if_index = ~0;
13374     }
13375
13376   if (!vam->json_output)
13377     {
13378       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13379              "sw_if_index", "instance", "src_address", "dst_address",
13380              "tunnel_type", "outer_fib_id", "session_id");
13381     }
13382
13383   /* Get list of gre-tunnel interfaces */
13384   M (GRE_TUNNEL_DUMP, mp);
13385
13386   mp->sw_if_index = htonl (sw_if_index);
13387
13388   S (mp);
13389
13390   /* Use a control ping for synchronization */
13391   MPING (CONTROL_PING, mp_ping);
13392   S (mp_ping);
13393
13394   W (ret);
13395   return ret;
13396 }
13397
13398 static int
13399 api_l2_fib_clear_table (vat_main_t * vam)
13400 {
13401 //  unformat_input_t * i = vam->input;
13402   vl_api_l2_fib_clear_table_t *mp;
13403   int ret;
13404
13405   M (L2_FIB_CLEAR_TABLE, mp);
13406
13407   S (mp);
13408   W (ret);
13409   return ret;
13410 }
13411
13412 static int
13413 api_l2_interface_efp_filter (vat_main_t * vam)
13414 {
13415   unformat_input_t *i = vam->input;
13416   vl_api_l2_interface_efp_filter_t *mp;
13417   u32 sw_if_index;
13418   u8 enable = 1;
13419   u8 sw_if_index_set = 0;
13420   int ret;
13421
13422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13423     {
13424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13425         sw_if_index_set = 1;
13426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13427         sw_if_index_set = 1;
13428       else if (unformat (i, "enable"))
13429         enable = 1;
13430       else if (unformat (i, "disable"))
13431         enable = 0;
13432       else
13433         {
13434           clib_warning ("parse error '%U'", format_unformat_error, i);
13435           return -99;
13436         }
13437     }
13438
13439   if (sw_if_index_set == 0)
13440     {
13441       errmsg ("missing sw_if_index");
13442       return -99;
13443     }
13444
13445   M (L2_INTERFACE_EFP_FILTER, mp);
13446
13447   mp->sw_if_index = ntohl (sw_if_index);
13448   mp->enable_disable = enable;
13449
13450   S (mp);
13451   W (ret);
13452   return ret;
13453 }
13454
13455 #define foreach_vtr_op                          \
13456 _("disable",  L2_VTR_DISABLED)                  \
13457 _("push-1",  L2_VTR_PUSH_1)                     \
13458 _("push-2",  L2_VTR_PUSH_2)                     \
13459 _("pop-1",  L2_VTR_POP_1)                       \
13460 _("pop-2",  L2_VTR_POP_2)                       \
13461 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13462 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13463 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13464 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13465
13466 static int
13467 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13468 {
13469   unformat_input_t *i = vam->input;
13470   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13471   u32 sw_if_index;
13472   u8 sw_if_index_set = 0;
13473   u8 vtr_op_set = 0;
13474   u32 vtr_op = 0;
13475   u32 push_dot1q = 1;
13476   u32 tag1 = ~0;
13477   u32 tag2 = ~0;
13478   int ret;
13479
13480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13481     {
13482       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13483         sw_if_index_set = 1;
13484       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13485         sw_if_index_set = 1;
13486       else if (unformat (i, "vtr_op %d", &vtr_op))
13487         vtr_op_set = 1;
13488 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13489       foreach_vtr_op
13490 #undef _
13491         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13492         ;
13493       else if (unformat (i, "tag1 %d", &tag1))
13494         ;
13495       else if (unformat (i, "tag2 %d", &tag2))
13496         ;
13497       else
13498         {
13499           clib_warning ("parse error '%U'", format_unformat_error, i);
13500           return -99;
13501         }
13502     }
13503
13504   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13505     {
13506       errmsg ("missing vtr operation or sw_if_index");
13507       return -99;
13508     }
13509
13510   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13511   mp->sw_if_index = ntohl (sw_if_index);
13512   mp->vtr_op = ntohl (vtr_op);
13513   mp->push_dot1q = ntohl (push_dot1q);
13514   mp->tag1 = ntohl (tag1);
13515   mp->tag2 = ntohl (tag2);
13516
13517   S (mp);
13518   W (ret);
13519   return ret;
13520 }
13521
13522 static int
13523 api_create_vhost_user_if (vat_main_t * vam)
13524 {
13525   unformat_input_t *i = vam->input;
13526   vl_api_create_vhost_user_if_t *mp;
13527   u8 *file_name;
13528   u8 is_server = 0;
13529   u8 file_name_set = 0;
13530   u32 custom_dev_instance = ~0;
13531   u8 hwaddr[6];
13532   u8 use_custom_mac = 0;
13533   u8 disable_mrg_rxbuf = 0;
13534   u8 disable_indirect_desc = 0;
13535   u8 *tag = 0;
13536   int ret;
13537
13538   /* Shut up coverity */
13539   clib_memset (hwaddr, 0, sizeof (hwaddr));
13540
13541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13542     {
13543       if (unformat (i, "socket %s", &file_name))
13544         {
13545           file_name_set = 1;
13546         }
13547       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13548         ;
13549       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13550         use_custom_mac = 1;
13551       else if (unformat (i, "server"))
13552         is_server = 1;
13553       else if (unformat (i, "disable_mrg_rxbuf"))
13554         disable_mrg_rxbuf = 1;
13555       else if (unformat (i, "disable_indirect_desc"))
13556         disable_indirect_desc = 1;
13557       else if (unformat (i, "tag %s", &tag))
13558         ;
13559       else
13560         break;
13561     }
13562
13563   if (file_name_set == 0)
13564     {
13565       errmsg ("missing socket file name");
13566       return -99;
13567     }
13568
13569   if (vec_len (file_name) > 255)
13570     {
13571       errmsg ("socket file name too long");
13572       return -99;
13573     }
13574   vec_add1 (file_name, 0);
13575
13576   M (CREATE_VHOST_USER_IF, mp);
13577
13578   mp->is_server = is_server;
13579   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13580   mp->disable_indirect_desc = disable_indirect_desc;
13581   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13582   vec_free (file_name);
13583   if (custom_dev_instance != ~0)
13584     {
13585       mp->renumber = 1;
13586       mp->custom_dev_instance = ntohl (custom_dev_instance);
13587     }
13588
13589   mp->use_custom_mac = use_custom_mac;
13590   clib_memcpy (mp->mac_address, hwaddr, 6);
13591   if (tag)
13592     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13593   vec_free (tag);
13594
13595   S (mp);
13596   W (ret);
13597   return ret;
13598 }
13599
13600 static int
13601 api_modify_vhost_user_if (vat_main_t * vam)
13602 {
13603   unformat_input_t *i = vam->input;
13604   vl_api_modify_vhost_user_if_t *mp;
13605   u8 *file_name;
13606   u8 is_server = 0;
13607   u8 file_name_set = 0;
13608   u32 custom_dev_instance = ~0;
13609   u8 sw_if_index_set = 0;
13610   u32 sw_if_index = (u32) ~ 0;
13611   int ret;
13612
13613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13614     {
13615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13616         sw_if_index_set = 1;
13617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13618         sw_if_index_set = 1;
13619       else if (unformat (i, "socket %s", &file_name))
13620         {
13621           file_name_set = 1;
13622         }
13623       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13624         ;
13625       else if (unformat (i, "server"))
13626         is_server = 1;
13627       else
13628         break;
13629     }
13630
13631   if (sw_if_index_set == 0)
13632     {
13633       errmsg ("missing sw_if_index or interface name");
13634       return -99;
13635     }
13636
13637   if (file_name_set == 0)
13638     {
13639       errmsg ("missing socket file name");
13640       return -99;
13641     }
13642
13643   if (vec_len (file_name) > 255)
13644     {
13645       errmsg ("socket file name too long");
13646       return -99;
13647     }
13648   vec_add1 (file_name, 0);
13649
13650   M (MODIFY_VHOST_USER_IF, mp);
13651
13652   mp->sw_if_index = ntohl (sw_if_index);
13653   mp->is_server = is_server;
13654   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13655   vec_free (file_name);
13656   if (custom_dev_instance != ~0)
13657     {
13658       mp->renumber = 1;
13659       mp->custom_dev_instance = ntohl (custom_dev_instance);
13660     }
13661
13662   S (mp);
13663   W (ret);
13664   return ret;
13665 }
13666
13667 static int
13668 api_delete_vhost_user_if (vat_main_t * vam)
13669 {
13670   unformat_input_t *i = vam->input;
13671   vl_api_delete_vhost_user_if_t *mp;
13672   u32 sw_if_index = ~0;
13673   u8 sw_if_index_set = 0;
13674   int ret;
13675
13676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13677     {
13678       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13679         sw_if_index_set = 1;
13680       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13681         sw_if_index_set = 1;
13682       else
13683         break;
13684     }
13685
13686   if (sw_if_index_set == 0)
13687     {
13688       errmsg ("missing sw_if_index or interface name");
13689       return -99;
13690     }
13691
13692
13693   M (DELETE_VHOST_USER_IF, mp);
13694
13695   mp->sw_if_index = ntohl (sw_if_index);
13696
13697   S (mp);
13698   W (ret);
13699   return ret;
13700 }
13701
13702 static void vl_api_sw_interface_vhost_user_details_t_handler
13703   (vl_api_sw_interface_vhost_user_details_t * mp)
13704 {
13705   vat_main_t *vam = &vat_main;
13706
13707   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13708          (char *) mp->interface_name,
13709          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13710          clib_net_to_host_u64 (mp->features), mp->is_server,
13711          ntohl (mp->num_regions), (char *) mp->sock_filename);
13712   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13713 }
13714
13715 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13716   (vl_api_sw_interface_vhost_user_details_t * mp)
13717 {
13718   vat_main_t *vam = &vat_main;
13719   vat_json_node_t *node = NULL;
13720
13721   if (VAT_JSON_ARRAY != vam->json_tree.type)
13722     {
13723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13724       vat_json_init_array (&vam->json_tree);
13725     }
13726   node = vat_json_array_add (&vam->json_tree);
13727
13728   vat_json_init_object (node);
13729   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13730   vat_json_object_add_string_copy (node, "interface_name",
13731                                    mp->interface_name);
13732   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13733                             ntohl (mp->virtio_net_hdr_sz));
13734   vat_json_object_add_uint (node, "features",
13735                             clib_net_to_host_u64 (mp->features));
13736   vat_json_object_add_uint (node, "is_server", mp->is_server);
13737   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13738   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13739   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13740 }
13741
13742 static int
13743 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13744 {
13745   vl_api_sw_interface_vhost_user_dump_t *mp;
13746   vl_api_control_ping_t *mp_ping;
13747   int ret;
13748   print (vam->ofp,
13749          "Interface name            idx hdr_sz features server regions filename");
13750
13751   /* Get list of vhost-user interfaces */
13752   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13753   S (mp);
13754
13755   /* Use a control ping for synchronization */
13756   MPING (CONTROL_PING, mp_ping);
13757   S (mp_ping);
13758
13759   W (ret);
13760   return ret;
13761 }
13762
13763 static int
13764 api_show_version (vat_main_t * vam)
13765 {
13766   vl_api_show_version_t *mp;
13767   int ret;
13768
13769   M (SHOW_VERSION, mp);
13770
13771   S (mp);
13772   W (ret);
13773   return ret;
13774 }
13775
13776
13777 static int
13778 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13779 {
13780   unformat_input_t *line_input = vam->input;
13781   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13782   ip4_address_t local4, remote4;
13783   ip6_address_t local6, remote6;
13784   u8 is_add = 1;
13785   u8 ipv4_set = 0, ipv6_set = 0;
13786   u8 local_set = 0;
13787   u8 remote_set = 0;
13788   u8 grp_set = 0;
13789   u32 mcast_sw_if_index = ~0;
13790   u32 encap_vrf_id = 0;
13791   u32 decap_vrf_id = 0;
13792   u8 protocol = ~0;
13793   u32 vni;
13794   u8 vni_set = 0;
13795   int ret;
13796
13797   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13798   clib_memset (&local4, 0, sizeof local4);
13799   clib_memset (&remote4, 0, sizeof remote4);
13800   clib_memset (&local6, 0, sizeof local6);
13801   clib_memset (&remote6, 0, sizeof remote6);
13802
13803   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13804     {
13805       if (unformat (line_input, "del"))
13806         is_add = 0;
13807       else if (unformat (line_input, "local %U",
13808                          unformat_ip4_address, &local4))
13809         {
13810           local_set = 1;
13811           ipv4_set = 1;
13812         }
13813       else if (unformat (line_input, "remote %U",
13814                          unformat_ip4_address, &remote4))
13815         {
13816           remote_set = 1;
13817           ipv4_set = 1;
13818         }
13819       else if (unformat (line_input, "local %U",
13820                          unformat_ip6_address, &local6))
13821         {
13822           local_set = 1;
13823           ipv6_set = 1;
13824         }
13825       else if (unformat (line_input, "remote %U",
13826                          unformat_ip6_address, &remote6))
13827         {
13828           remote_set = 1;
13829           ipv6_set = 1;
13830         }
13831       else if (unformat (line_input, "group %U %U",
13832                          unformat_ip4_address, &remote4,
13833                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13834         {
13835           grp_set = remote_set = 1;
13836           ipv4_set = 1;
13837         }
13838       else if (unformat (line_input, "group %U",
13839                          unformat_ip4_address, &remote4))
13840         {
13841           grp_set = remote_set = 1;
13842           ipv4_set = 1;
13843         }
13844       else if (unformat (line_input, "group %U %U",
13845                          unformat_ip6_address, &remote6,
13846                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13847         {
13848           grp_set = remote_set = 1;
13849           ipv6_set = 1;
13850         }
13851       else if (unformat (line_input, "group %U",
13852                          unformat_ip6_address, &remote6))
13853         {
13854           grp_set = remote_set = 1;
13855           ipv6_set = 1;
13856         }
13857       else
13858         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13859         ;
13860       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13861         ;
13862       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13863         ;
13864       else if (unformat (line_input, "vni %d", &vni))
13865         vni_set = 1;
13866       else if (unformat (line_input, "next-ip4"))
13867         protocol = 1;
13868       else if (unformat (line_input, "next-ip6"))
13869         protocol = 2;
13870       else if (unformat (line_input, "next-ethernet"))
13871         protocol = 3;
13872       else if (unformat (line_input, "next-nsh"))
13873         protocol = 4;
13874       else
13875         {
13876           errmsg ("parse error '%U'", format_unformat_error, line_input);
13877           return -99;
13878         }
13879     }
13880
13881   if (local_set == 0)
13882     {
13883       errmsg ("tunnel local address not specified");
13884       return -99;
13885     }
13886   if (remote_set == 0)
13887     {
13888       errmsg ("tunnel remote address not specified");
13889       return -99;
13890     }
13891   if (grp_set && mcast_sw_if_index == ~0)
13892     {
13893       errmsg ("tunnel nonexistent multicast device");
13894       return -99;
13895     }
13896   if (ipv4_set && ipv6_set)
13897     {
13898       errmsg ("both IPv4 and IPv6 addresses specified");
13899       return -99;
13900     }
13901
13902   if (vni_set == 0)
13903     {
13904       errmsg ("vni not specified");
13905       return -99;
13906     }
13907
13908   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13909
13910
13911   if (ipv6_set)
13912     {
13913       clib_memcpy (&mp->local, &local6, sizeof (local6));
13914       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13915     }
13916   else
13917     {
13918       clib_memcpy (&mp->local, &local4, sizeof (local4));
13919       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13920     }
13921
13922   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13923   mp->encap_vrf_id = ntohl (encap_vrf_id);
13924   mp->decap_vrf_id = ntohl (decap_vrf_id);
13925   mp->protocol = protocol;
13926   mp->vni = ntohl (vni);
13927   mp->is_add = is_add;
13928   mp->is_ipv6 = ipv6_set;
13929
13930   S (mp);
13931   W (ret);
13932   return ret;
13933 }
13934
13935 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13936   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13937 {
13938   vat_main_t *vam = &vat_main;
13939   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13940   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13941
13942   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13943          ntohl (mp->sw_if_index),
13944          format_ip46_address, &local, IP46_TYPE_ANY,
13945          format_ip46_address, &remote, IP46_TYPE_ANY,
13946          ntohl (mp->vni), mp->protocol,
13947          ntohl (mp->mcast_sw_if_index),
13948          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13949 }
13950
13951
13952 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13953   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13954 {
13955   vat_main_t *vam = &vat_main;
13956   vat_json_node_t *node = NULL;
13957   struct in_addr ip4;
13958   struct in6_addr ip6;
13959
13960   if (VAT_JSON_ARRAY != vam->json_tree.type)
13961     {
13962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13963       vat_json_init_array (&vam->json_tree);
13964     }
13965   node = vat_json_array_add (&vam->json_tree);
13966
13967   vat_json_init_object (node);
13968   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13969   if (mp->is_ipv6)
13970     {
13971       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13972       vat_json_object_add_ip6 (node, "local", ip6);
13973       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13974       vat_json_object_add_ip6 (node, "remote", ip6);
13975     }
13976   else
13977     {
13978       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13979       vat_json_object_add_ip4 (node, "local", ip4);
13980       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13981       vat_json_object_add_ip4 (node, "remote", ip4);
13982     }
13983   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13984   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13985   vat_json_object_add_uint (node, "mcast_sw_if_index",
13986                             ntohl (mp->mcast_sw_if_index));
13987   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13988   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13989   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13990 }
13991
13992 static int
13993 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13994 {
13995   unformat_input_t *i = vam->input;
13996   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13997   vl_api_control_ping_t *mp_ping;
13998   u32 sw_if_index;
13999   u8 sw_if_index_set = 0;
14000   int ret;
14001
14002   /* Parse args required to build the message */
14003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14004     {
14005       if (unformat (i, "sw_if_index %d", &sw_if_index))
14006         sw_if_index_set = 1;
14007       else
14008         break;
14009     }
14010
14011   if (sw_if_index_set == 0)
14012     {
14013       sw_if_index = ~0;
14014     }
14015
14016   if (!vam->json_output)
14017     {
14018       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14019              "sw_if_index", "local", "remote", "vni",
14020              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14021     }
14022
14023   /* Get list of vxlan-tunnel interfaces */
14024   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14025
14026   mp->sw_if_index = htonl (sw_if_index);
14027
14028   S (mp);
14029
14030   /* Use a control ping for synchronization */
14031   MPING (CONTROL_PING, mp_ping);
14032   S (mp_ping);
14033
14034   W (ret);
14035   return ret;
14036 }
14037
14038 static void vl_api_l2_fib_table_details_t_handler
14039   (vl_api_l2_fib_table_details_t * mp)
14040 {
14041   vat_main_t *vam = &vat_main;
14042
14043   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14044          "       %d       %d     %d",
14045          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14046          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14047          mp->bvi_mac);
14048 }
14049
14050 static void vl_api_l2_fib_table_details_t_handler_json
14051   (vl_api_l2_fib_table_details_t * mp)
14052 {
14053   vat_main_t *vam = &vat_main;
14054   vat_json_node_t *node = NULL;
14055
14056   if (VAT_JSON_ARRAY != vam->json_tree.type)
14057     {
14058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14059       vat_json_init_array (&vam->json_tree);
14060     }
14061   node = vat_json_array_add (&vam->json_tree);
14062
14063   vat_json_init_object (node);
14064   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14065   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14066   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14067   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14068   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14069   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14070 }
14071
14072 static int
14073 api_l2_fib_table_dump (vat_main_t * vam)
14074 {
14075   unformat_input_t *i = vam->input;
14076   vl_api_l2_fib_table_dump_t *mp;
14077   vl_api_control_ping_t *mp_ping;
14078   u32 bd_id;
14079   u8 bd_id_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, "bd_id %d", &bd_id))
14086         bd_id_set = 1;
14087       else
14088         break;
14089     }
14090
14091   if (bd_id_set == 0)
14092     {
14093       errmsg ("missing bridge domain");
14094       return -99;
14095     }
14096
14097   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14098
14099   /* Get list of l2 fib entries */
14100   M (L2_FIB_TABLE_DUMP, mp);
14101
14102   mp->bd_id = ntohl (bd_id);
14103   S (mp);
14104
14105   /* Use a control ping for synchronization */
14106   MPING (CONTROL_PING, mp_ping);
14107   S (mp_ping);
14108
14109   W (ret);
14110   return ret;
14111 }
14112
14113
14114 static int
14115 api_interface_name_renumber (vat_main_t * vam)
14116 {
14117   unformat_input_t *line_input = vam->input;
14118   vl_api_interface_name_renumber_t *mp;
14119   u32 sw_if_index = ~0;
14120   u32 new_show_dev_instance = ~0;
14121   int ret;
14122
14123   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14124     {
14125       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14126                     &sw_if_index))
14127         ;
14128       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14129         ;
14130       else if (unformat (line_input, "new_show_dev_instance %d",
14131                          &new_show_dev_instance))
14132         ;
14133       else
14134         break;
14135     }
14136
14137   if (sw_if_index == ~0)
14138     {
14139       errmsg ("missing interface name or sw_if_index");
14140       return -99;
14141     }
14142
14143   if (new_show_dev_instance == ~0)
14144     {
14145       errmsg ("missing new_show_dev_instance");
14146       return -99;
14147     }
14148
14149   M (INTERFACE_NAME_RENUMBER, mp);
14150
14151   mp->sw_if_index = ntohl (sw_if_index);
14152   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14153
14154   S (mp);
14155   W (ret);
14156   return ret;
14157 }
14158
14159 static int
14160 api_ip_probe_neighbor (vat_main_t * vam)
14161 {
14162   unformat_input_t *i = vam->input;
14163   vl_api_ip_probe_neighbor_t *mp;
14164   vl_api_address_t dst_adr = { };
14165   u8 int_set = 0;
14166   u8 adr_set = 0;
14167   u32 sw_if_index;
14168   int ret;
14169
14170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14171     {
14172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14173         int_set = 1;
14174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14175         int_set = 1;
14176       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
14177         adr_set = 1;
14178       else
14179         break;
14180     }
14181
14182   if (int_set == 0)
14183     {
14184       errmsg ("missing interface");
14185       return -99;
14186     }
14187
14188   if (adr_set == 0)
14189     {
14190       errmsg ("missing addresses");
14191       return -99;
14192     }
14193
14194   M (IP_PROBE_NEIGHBOR, mp);
14195
14196   mp->sw_if_index = ntohl (sw_if_index);
14197   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14198
14199   S (mp);
14200   W (ret);
14201   return ret;
14202 }
14203
14204 static int
14205 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14206 {
14207   unformat_input_t *i = vam->input;
14208   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14209   u8 mode = IP_SCAN_V46_NEIGHBORS;
14210   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14211   int ret;
14212
14213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14214     {
14215       if (unformat (i, "ip4"))
14216         mode = IP_SCAN_V4_NEIGHBORS;
14217       else if (unformat (i, "ip6"))
14218         mode = IP_SCAN_V6_NEIGHBORS;
14219       if (unformat (i, "both"))
14220         mode = IP_SCAN_V46_NEIGHBORS;
14221       else if (unformat (i, "disable"))
14222         mode = IP_SCAN_DISABLED;
14223       else if (unformat (i, "interval %d", &interval))
14224         ;
14225       else if (unformat (i, "max-time %d", &time))
14226         ;
14227       else if (unformat (i, "max-update %d", &update))
14228         ;
14229       else if (unformat (i, "delay %d", &delay))
14230         ;
14231       else if (unformat (i, "stale %d", &stale))
14232         ;
14233       else
14234         break;
14235     }
14236
14237   if (interval > 255)
14238     {
14239       errmsg ("interval cannot exceed 255 minutes.");
14240       return -99;
14241     }
14242   if (time > 255)
14243     {
14244       errmsg ("max-time cannot exceed 255 usec.");
14245       return -99;
14246     }
14247   if (update > 255)
14248     {
14249       errmsg ("max-update cannot exceed 255.");
14250       return -99;
14251     }
14252   if (delay > 255)
14253     {
14254       errmsg ("delay cannot exceed 255 msec.");
14255       return -99;
14256     }
14257   if (stale > 255)
14258     {
14259       errmsg ("stale cannot exceed 255 minutes.");
14260       return -99;
14261     }
14262
14263   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14264   mp->mode = mode;
14265   mp->scan_interval = interval;
14266   mp->max_proc_time = time;
14267   mp->max_update = update;
14268   mp->scan_int_delay = delay;
14269   mp->stale_threshold = stale;
14270
14271   S (mp);
14272   W (ret);
14273   return ret;
14274 }
14275
14276 static int
14277 api_want_ip4_arp_events (vat_main_t * vam)
14278 {
14279   unformat_input_t *line_input = vam->input;
14280   vl_api_want_ip4_arp_events_t *mp;
14281   ip4_address_t address;
14282   int address_set = 0;
14283   u32 enable_disable = 1;
14284   int ret;
14285
14286   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14287     {
14288       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14289         address_set = 1;
14290       else if (unformat (line_input, "del"))
14291         enable_disable = 0;
14292       else
14293         break;
14294     }
14295
14296   if (address_set == 0)
14297     {
14298       errmsg ("missing addresses");
14299       return -99;
14300     }
14301
14302   M (WANT_IP4_ARP_EVENTS, mp);
14303   mp->enable_disable = enable_disable;
14304   mp->pid = htonl (getpid ());
14305   clib_memcpy (mp->ip, &address, sizeof (address));
14306
14307   S (mp);
14308   W (ret);
14309   return ret;
14310 }
14311
14312 static int
14313 api_want_ip6_nd_events (vat_main_t * vam)
14314 {
14315   unformat_input_t *line_input = vam->input;
14316   vl_api_want_ip6_nd_events_t *mp;
14317   vl_api_ip6_address_t address;
14318   int address_set = 0;
14319   u32 enable_disable = 1;
14320   int ret;
14321
14322   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14323     {
14324       if (unformat
14325           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14326         address_set = 1;
14327       else if (unformat (line_input, "del"))
14328         enable_disable = 0;
14329       else
14330         break;
14331     }
14332
14333   if (address_set == 0)
14334     {
14335       errmsg ("missing addresses");
14336       return -99;
14337     }
14338
14339   M (WANT_IP6_ND_EVENTS, mp);
14340   mp->enable_disable = enable_disable;
14341   mp->pid = htonl (getpid ());
14342   clib_memcpy (&mp->ip, &address, sizeof (address));
14343
14344   S (mp);
14345   W (ret);
14346   return ret;
14347 }
14348
14349 static int
14350 api_want_l2_macs_events (vat_main_t * vam)
14351 {
14352   unformat_input_t *line_input = vam->input;
14353   vl_api_want_l2_macs_events_t *mp;
14354   u8 enable_disable = 1;
14355   u32 scan_delay = 0;
14356   u32 max_macs_in_event = 0;
14357   u32 learn_limit = 0;
14358   int ret;
14359
14360   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14361     {
14362       if (unformat (line_input, "learn-limit %d", &learn_limit))
14363         ;
14364       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14365         ;
14366       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14367         ;
14368       else if (unformat (line_input, "disable"))
14369         enable_disable = 0;
14370       else
14371         break;
14372     }
14373
14374   M (WANT_L2_MACS_EVENTS, mp);
14375   mp->enable_disable = enable_disable;
14376   mp->pid = htonl (getpid ());
14377   mp->learn_limit = htonl (learn_limit);
14378   mp->scan_delay = (u8) scan_delay;
14379   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14380   S (mp);
14381   W (ret);
14382   return ret;
14383 }
14384
14385 static int
14386 api_input_acl_set_interface (vat_main_t * vam)
14387 {
14388   unformat_input_t *i = vam->input;
14389   vl_api_input_acl_set_interface_t *mp;
14390   u32 sw_if_index;
14391   int sw_if_index_set;
14392   u32 ip4_table_index = ~0;
14393   u32 ip6_table_index = ~0;
14394   u32 l2_table_index = ~0;
14395   u8 is_add = 1;
14396   int ret;
14397
14398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14399     {
14400       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14401         sw_if_index_set = 1;
14402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14403         sw_if_index_set = 1;
14404       else if (unformat (i, "del"))
14405         is_add = 0;
14406       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14407         ;
14408       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14409         ;
14410       else if (unformat (i, "l2-table %d", &l2_table_index))
14411         ;
14412       else
14413         {
14414           clib_warning ("parse error '%U'", format_unformat_error, i);
14415           return -99;
14416         }
14417     }
14418
14419   if (sw_if_index_set == 0)
14420     {
14421       errmsg ("missing interface name or sw_if_index");
14422       return -99;
14423     }
14424
14425   M (INPUT_ACL_SET_INTERFACE, mp);
14426
14427   mp->sw_if_index = ntohl (sw_if_index);
14428   mp->ip4_table_index = ntohl (ip4_table_index);
14429   mp->ip6_table_index = ntohl (ip6_table_index);
14430   mp->l2_table_index = ntohl (l2_table_index);
14431   mp->is_add = is_add;
14432
14433   S (mp);
14434   W (ret);
14435   return ret;
14436 }
14437
14438 static int
14439 api_output_acl_set_interface (vat_main_t * vam)
14440 {
14441   unformat_input_t *i = vam->input;
14442   vl_api_output_acl_set_interface_t *mp;
14443   u32 sw_if_index;
14444   int sw_if_index_set;
14445   u32 ip4_table_index = ~0;
14446   u32 ip6_table_index = ~0;
14447   u32 l2_table_index = ~0;
14448   u8 is_add = 1;
14449   int ret;
14450
14451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14452     {
14453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14454         sw_if_index_set = 1;
14455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14456         sw_if_index_set = 1;
14457       else if (unformat (i, "del"))
14458         is_add = 0;
14459       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14460         ;
14461       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14462         ;
14463       else if (unformat (i, "l2-table %d", &l2_table_index))
14464         ;
14465       else
14466         {
14467           clib_warning ("parse error '%U'", format_unformat_error, i);
14468           return -99;
14469         }
14470     }
14471
14472   if (sw_if_index_set == 0)
14473     {
14474       errmsg ("missing interface name or sw_if_index");
14475       return -99;
14476     }
14477
14478   M (OUTPUT_ACL_SET_INTERFACE, mp);
14479
14480   mp->sw_if_index = ntohl (sw_if_index);
14481   mp->ip4_table_index = ntohl (ip4_table_index);
14482   mp->ip6_table_index = ntohl (ip6_table_index);
14483   mp->l2_table_index = ntohl (l2_table_index);
14484   mp->is_add = is_add;
14485
14486   S (mp);
14487   W (ret);
14488   return ret;
14489 }
14490
14491 static int
14492 api_ip_address_dump (vat_main_t * vam)
14493 {
14494   unformat_input_t *i = vam->input;
14495   vl_api_ip_address_dump_t *mp;
14496   vl_api_control_ping_t *mp_ping;
14497   u32 sw_if_index = ~0;
14498   u8 sw_if_index_set = 0;
14499   u8 ipv4_set = 0;
14500   u8 ipv6_set = 0;
14501   int ret;
14502
14503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14504     {
14505       if (unformat (i, "sw_if_index %d", &sw_if_index))
14506         sw_if_index_set = 1;
14507       else
14508         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14509         sw_if_index_set = 1;
14510       else if (unformat (i, "ipv4"))
14511         ipv4_set = 1;
14512       else if (unformat (i, "ipv6"))
14513         ipv6_set = 1;
14514       else
14515         break;
14516     }
14517
14518   if (ipv4_set && ipv6_set)
14519     {
14520       errmsg ("ipv4 and ipv6 flags cannot be both set");
14521       return -99;
14522     }
14523
14524   if ((!ipv4_set) && (!ipv6_set))
14525     {
14526       errmsg ("no ipv4 nor ipv6 flag set");
14527       return -99;
14528     }
14529
14530   if (sw_if_index_set == 0)
14531     {
14532       errmsg ("missing interface name or sw_if_index");
14533       return -99;
14534     }
14535
14536   vam->current_sw_if_index = sw_if_index;
14537   vam->is_ipv6 = ipv6_set;
14538
14539   M (IP_ADDRESS_DUMP, mp);
14540   mp->sw_if_index = ntohl (sw_if_index);
14541   mp->is_ipv6 = ipv6_set;
14542   S (mp);
14543
14544   /* Use a control ping for synchronization */
14545   MPING (CONTROL_PING, mp_ping);
14546   S (mp_ping);
14547
14548   W (ret);
14549   return ret;
14550 }
14551
14552 static int
14553 api_ip_dump (vat_main_t * vam)
14554 {
14555   vl_api_ip_dump_t *mp;
14556   vl_api_control_ping_t *mp_ping;
14557   unformat_input_t *in = vam->input;
14558   int ipv4_set = 0;
14559   int ipv6_set = 0;
14560   int is_ipv6;
14561   int i;
14562   int ret;
14563
14564   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14565     {
14566       if (unformat (in, "ipv4"))
14567         ipv4_set = 1;
14568       else if (unformat (in, "ipv6"))
14569         ipv6_set = 1;
14570       else
14571         break;
14572     }
14573
14574   if (ipv4_set && ipv6_set)
14575     {
14576       errmsg ("ipv4 and ipv6 flags cannot be both set");
14577       return -99;
14578     }
14579
14580   if ((!ipv4_set) && (!ipv6_set))
14581     {
14582       errmsg ("no ipv4 nor ipv6 flag set");
14583       return -99;
14584     }
14585
14586   is_ipv6 = ipv6_set;
14587   vam->is_ipv6 = is_ipv6;
14588
14589   /* free old data */
14590   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14591     {
14592       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14593     }
14594   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14595
14596   M (IP_DUMP, mp);
14597   mp->is_ipv6 = ipv6_set;
14598   S (mp);
14599
14600   /* Use a control ping for synchronization */
14601   MPING (CONTROL_PING, mp_ping);
14602   S (mp_ping);
14603
14604   W (ret);
14605   return ret;
14606 }
14607
14608 static int
14609 api_ipsec_spd_add_del (vat_main_t * vam)
14610 {
14611   unformat_input_t *i = vam->input;
14612   vl_api_ipsec_spd_add_del_t *mp;
14613   u32 spd_id = ~0;
14614   u8 is_add = 1;
14615   int ret;
14616
14617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14618     {
14619       if (unformat (i, "spd_id %d", &spd_id))
14620         ;
14621       else if (unformat (i, "del"))
14622         is_add = 0;
14623       else
14624         {
14625           clib_warning ("parse error '%U'", format_unformat_error, i);
14626           return -99;
14627         }
14628     }
14629   if (spd_id == ~0)
14630     {
14631       errmsg ("spd_id must be set");
14632       return -99;
14633     }
14634
14635   M (IPSEC_SPD_ADD_DEL, mp);
14636
14637   mp->spd_id = ntohl (spd_id);
14638   mp->is_add = is_add;
14639
14640   S (mp);
14641   W (ret);
14642   return ret;
14643 }
14644
14645 static int
14646 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14647 {
14648   unformat_input_t *i = vam->input;
14649   vl_api_ipsec_interface_add_del_spd_t *mp;
14650   u32 sw_if_index;
14651   u8 sw_if_index_set = 0;
14652   u32 spd_id = (u32) ~ 0;
14653   u8 is_add = 1;
14654   int ret;
14655
14656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14657     {
14658       if (unformat (i, "del"))
14659         is_add = 0;
14660       else if (unformat (i, "spd_id %d", &spd_id))
14661         ;
14662       else
14663         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14664         sw_if_index_set = 1;
14665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14666         sw_if_index_set = 1;
14667       else
14668         {
14669           clib_warning ("parse error '%U'", format_unformat_error, i);
14670           return -99;
14671         }
14672
14673     }
14674
14675   if (spd_id == (u32) ~ 0)
14676     {
14677       errmsg ("spd_id must be set");
14678       return -99;
14679     }
14680
14681   if (sw_if_index_set == 0)
14682     {
14683       errmsg ("missing interface name or sw_if_index");
14684       return -99;
14685     }
14686
14687   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14688
14689   mp->spd_id = ntohl (spd_id);
14690   mp->sw_if_index = ntohl (sw_if_index);
14691   mp->is_add = is_add;
14692
14693   S (mp);
14694   W (ret);
14695   return ret;
14696 }
14697
14698 static int
14699 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14700 {
14701   unformat_input_t *i = vam->input;
14702   vl_api_ipsec_spd_entry_add_del_t *mp;
14703   u8 is_add = 1, is_outbound = 0;
14704   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14705   i32 priority = 0;
14706   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14707   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14708   vl_api_address_t laddr_start = { }, laddr_stop =
14709   {
14710   }, raddr_start =
14711   {
14712   }, raddr_stop =
14713   {
14714   };
14715   int ret;
14716
14717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14718     {
14719       if (unformat (i, "del"))
14720         is_add = 0;
14721       if (unformat (i, "outbound"))
14722         is_outbound = 1;
14723       if (unformat (i, "inbound"))
14724         is_outbound = 0;
14725       else if (unformat (i, "spd_id %d", &spd_id))
14726         ;
14727       else if (unformat (i, "sa_id %d", &sa_id))
14728         ;
14729       else if (unformat (i, "priority %d", &priority))
14730         ;
14731       else if (unformat (i, "protocol %d", &protocol))
14732         ;
14733       else if (unformat (i, "lport_start %d", &lport_start))
14734         ;
14735       else if (unformat (i, "lport_stop %d", &lport_stop))
14736         ;
14737       else if (unformat (i, "rport_start %d", &rport_start))
14738         ;
14739       else if (unformat (i, "rport_stop %d", &rport_stop))
14740         ;
14741       else if (unformat (i, "laddr_start %U",
14742                          unformat_vl_api_address, &laddr_start))
14743         ;
14744       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14745                          &laddr_stop))
14746         ;
14747       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14748                          &raddr_start))
14749         ;
14750       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14751                          &raddr_stop))
14752         ;
14753       else
14754         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14755         {
14756           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14757             {
14758               clib_warning ("unsupported action: 'resolve'");
14759               return -99;
14760             }
14761         }
14762       else
14763         {
14764           clib_warning ("parse error '%U'", format_unformat_error, i);
14765           return -99;
14766         }
14767
14768     }
14769
14770   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14771
14772   mp->is_add = is_add;
14773
14774   mp->entry.spd_id = ntohl (spd_id);
14775   mp->entry.priority = ntohl (priority);
14776   mp->entry.is_outbound = is_outbound;
14777
14778   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14779                sizeof (vl_api_address_t));
14780   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14781                sizeof (vl_api_address_t));
14782   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14783                sizeof (vl_api_address_t));
14784   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14785                sizeof (vl_api_address_t));
14786
14787   mp->entry.protocol = (u8) protocol;
14788   mp->entry.local_port_start = ntohs ((u16) lport_start);
14789   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14790   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14791   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14792   mp->entry.policy = (u8) policy;
14793   mp->entry.sa_id = ntohl (sa_id);
14794
14795   S (mp);
14796   W (ret);
14797   return ret;
14798 }
14799
14800 static int
14801 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14802 {
14803   unformat_input_t *i = vam->input;
14804   vl_api_ipsec_sad_entry_add_del_t *mp;
14805   u32 sad_id = 0, spi = 0;
14806   u8 *ck = 0, *ik = 0;
14807   u8 is_add = 1;
14808
14809   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14810   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14811   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14812   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14813   vl_api_address_t tun_src, tun_dst;
14814   int ret;
14815
14816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14817     {
14818       if (unformat (i, "del"))
14819         is_add = 0;
14820       else if (unformat (i, "sad_id %d", &sad_id))
14821         ;
14822       else if (unformat (i, "spi %d", &spi))
14823         ;
14824       else if (unformat (i, "esp"))
14825         protocol = IPSEC_API_PROTO_ESP;
14826       else
14827         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14828         {
14829           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14830           if (ADDRESS_IP6 == tun_src.af)
14831             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14832         }
14833       else
14834         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14835         {
14836           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14837           if (ADDRESS_IP6 == tun_src.af)
14838             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14839         }
14840       else
14841         if (unformat (i, "crypto_alg %U",
14842                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14843         ;
14844       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14845         ;
14846       else if (unformat (i, "integ_alg %U",
14847                          unformat_ipsec_api_integ_alg, &integ_alg))
14848         ;
14849       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14850         ;
14851       else
14852         {
14853           clib_warning ("parse error '%U'", format_unformat_error, i);
14854           return -99;
14855         }
14856
14857     }
14858
14859   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14860
14861   mp->is_add = is_add;
14862   mp->entry.sad_id = ntohl (sad_id);
14863   mp->entry.protocol = protocol;
14864   mp->entry.spi = ntohl (spi);
14865   mp->entry.flags = flags;
14866
14867   mp->entry.crypto_algorithm = crypto_alg;
14868   mp->entry.integrity_algorithm = integ_alg;
14869   mp->entry.crypto_key.length = vec_len (ck);
14870   mp->entry.integrity_key.length = vec_len (ik);
14871
14872   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14873     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14874
14875   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14876     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14877
14878   if (ck)
14879     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14880   if (ik)
14881     clib_memcpy (mp->entry.integrity_key.data, ik,
14882                  mp->entry.integrity_key.length);
14883
14884   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14885     {
14886       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14887                    sizeof (mp->entry.tunnel_src));
14888       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14889                    sizeof (mp->entry.tunnel_dst));
14890     }
14891
14892   S (mp);
14893   W (ret);
14894   return ret;
14895 }
14896
14897 static int
14898 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14899 {
14900   unformat_input_t *i = vam->input;
14901   vl_api_ipsec_tunnel_if_add_del_t *mp;
14902   u32 local_spi = 0, remote_spi = 0;
14903   u32 crypto_alg = 0, integ_alg = 0;
14904   u8 *lck = NULL, *rck = NULL;
14905   u8 *lik = NULL, *rik = NULL;
14906   vl_api_address_t local_ip = { 0 };
14907   vl_api_address_t remote_ip = { 0 };
14908   f64 before = 0;
14909   u8 is_add = 1;
14910   u8 esn = 0;
14911   u8 anti_replay = 0;
14912   u8 renumber = 0;
14913   u32 instance = ~0;
14914   u32 count = 1, jj;
14915   int ret = -1;
14916
14917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14918     {
14919       if (unformat (i, "del"))
14920         is_add = 0;
14921       else if (unformat (i, "esn"))
14922         esn = 1;
14923       else if (unformat (i, "anti-replay"))
14924         anti_replay = 1;
14925       else if (unformat (i, "count %d", &count))
14926         ;
14927       else if (unformat (i, "local_spi %d", &local_spi))
14928         ;
14929       else if (unformat (i, "remote_spi %d", &remote_spi))
14930         ;
14931       else
14932         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14933         ;
14934       else
14935         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14936         ;
14937       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14938         ;
14939       else
14940         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14941         ;
14942       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14943         ;
14944       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14945         ;
14946       else
14947         if (unformat
14948             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14949         {
14950           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14951             {
14952               errmsg ("unsupported crypto-alg: '%U'\n",
14953                       format_ipsec_crypto_alg, crypto_alg);
14954               return -99;
14955             }
14956         }
14957       else
14958         if (unformat
14959             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14960         {
14961           if (integ_alg >= IPSEC_INTEG_N_ALG)
14962             {
14963               errmsg ("unsupported integ-alg: '%U'\n",
14964                       format_ipsec_integ_alg, integ_alg);
14965               return -99;
14966             }
14967         }
14968       else if (unformat (i, "instance %u", &instance))
14969         renumber = 1;
14970       else
14971         {
14972           errmsg ("parse error '%U'\n", format_unformat_error, i);
14973           return -99;
14974         }
14975     }
14976
14977   if (count > 1)
14978     {
14979       /* Turn on async mode */
14980       vam->async_mode = 1;
14981       vam->async_errors = 0;
14982       before = vat_time_now (vam);
14983     }
14984
14985   for (jj = 0; jj < count; jj++)
14986     {
14987       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14988
14989       mp->is_add = is_add;
14990       mp->esn = esn;
14991       mp->anti_replay = anti_replay;
14992
14993       if (jj > 0)
14994         increment_vl_address (&remote_ip);
14995
14996       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14997       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14998
14999       mp->local_spi = htonl (local_spi + jj);
15000       mp->remote_spi = htonl (remote_spi + jj);
15001       mp->crypto_alg = (u8) crypto_alg;
15002
15003       mp->local_crypto_key_len = 0;
15004       if (lck)
15005         {
15006           mp->local_crypto_key_len = vec_len (lck);
15007           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15008             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15009           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15010         }
15011
15012       mp->remote_crypto_key_len = 0;
15013       if (rck)
15014         {
15015           mp->remote_crypto_key_len = vec_len (rck);
15016           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15017             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15018           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15019         }
15020
15021       mp->integ_alg = (u8) integ_alg;
15022
15023       mp->local_integ_key_len = 0;
15024       if (lik)
15025         {
15026           mp->local_integ_key_len = vec_len (lik);
15027           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15028             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15029           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15030         }
15031
15032       mp->remote_integ_key_len = 0;
15033       if (rik)
15034         {
15035           mp->remote_integ_key_len = vec_len (rik);
15036           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15037             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15038           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15039         }
15040
15041       if (renumber)
15042         {
15043           mp->renumber = renumber;
15044           mp->show_instance = ntohl (instance);
15045         }
15046       S (mp);
15047     }
15048
15049   /* When testing multiple add/del ops, use a control-ping to sync */
15050   if (count > 1)
15051     {
15052       vl_api_control_ping_t *mp_ping;
15053       f64 after;
15054       f64 timeout;
15055
15056       /* Shut off async mode */
15057       vam->async_mode = 0;
15058
15059       MPING (CONTROL_PING, mp_ping);
15060       S (mp_ping);
15061
15062       timeout = vat_time_now (vam) + 1.0;
15063       while (vat_time_now (vam) < timeout)
15064         if (vam->result_ready == 1)
15065           goto out;
15066       vam->retval = -99;
15067
15068     out:
15069       if (vam->retval == -99)
15070         errmsg ("timeout");
15071
15072       if (vam->async_errors > 0)
15073         {
15074           errmsg ("%d asynchronous errors", vam->async_errors);
15075           vam->retval = -98;
15076         }
15077       vam->async_errors = 0;
15078       after = vat_time_now (vam);
15079
15080       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15081       if (jj > 0)
15082         count = jj;
15083
15084       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15085              count, after - before, count / (after - before));
15086     }
15087   else
15088     {
15089       /* Wait for a reply... */
15090       W (ret);
15091       return ret;
15092     }
15093
15094   return ret;
15095 }
15096
15097 static void
15098 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15099 {
15100   vat_main_t *vam = &vat_main;
15101
15102   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15103          "crypto_key %U integ_alg %u integ_key %U flags %x "
15104          "tunnel_src_addr %U tunnel_dst_addr %U "
15105          "salt %u seq_outbound %lu last_seq_inbound %lu "
15106          "replay_window %lu\n",
15107          ntohl (mp->entry.sad_id),
15108          ntohl (mp->sw_if_index),
15109          ntohl (mp->entry.spi),
15110          ntohl (mp->entry.protocol),
15111          ntohl (mp->entry.crypto_algorithm),
15112          format_hex_bytes, mp->entry.crypto_key.data,
15113          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15114          format_hex_bytes, mp->entry.integrity_key.data,
15115          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15116          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15117          &mp->entry.tunnel_dst, ntohl (mp->salt),
15118          clib_net_to_host_u64 (mp->seq_outbound),
15119          clib_net_to_host_u64 (mp->last_seq_inbound),
15120          clib_net_to_host_u64 (mp->replay_window));
15121 }
15122
15123 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15124 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15125
15126 static void vl_api_ipsec_sa_details_t_handler_json
15127   (vl_api_ipsec_sa_details_t * mp)
15128 {
15129   vat_main_t *vam = &vat_main;
15130   vat_json_node_t *node = NULL;
15131   vl_api_ipsec_sad_flags_t flags;
15132
15133   if (VAT_JSON_ARRAY != vam->json_tree.type)
15134     {
15135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15136       vat_json_init_array (&vam->json_tree);
15137     }
15138   node = vat_json_array_add (&vam->json_tree);
15139
15140   vat_json_init_object (node);
15141   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15142   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15143   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15144   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15145   vat_json_object_add_uint (node, "crypto_alg",
15146                             ntohl (mp->entry.crypto_algorithm));
15147   vat_json_object_add_uint (node, "integ_alg",
15148                             ntohl (mp->entry.integrity_algorithm));
15149   flags = ntohl (mp->entry.flags);
15150   vat_json_object_add_uint (node, "use_esn",
15151                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15152   vat_json_object_add_uint (node, "use_anti_replay",
15153                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15154   vat_json_object_add_uint (node, "is_tunnel",
15155                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15156   vat_json_object_add_uint (node, "is_tunnel_ip6",
15157                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15158   vat_json_object_add_uint (node, "udp_encap",
15159                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15160   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15161                              mp->entry.crypto_key.length);
15162   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15163                              mp->entry.integrity_key.length);
15164   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15165   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15166   vat_json_object_add_uint (node, "replay_window",
15167                             clib_net_to_host_u64 (mp->replay_window));
15168 }
15169
15170 static int
15171 api_ipsec_sa_dump (vat_main_t * vam)
15172 {
15173   unformat_input_t *i = vam->input;
15174   vl_api_ipsec_sa_dump_t *mp;
15175   vl_api_control_ping_t *mp_ping;
15176   u32 sa_id = ~0;
15177   int ret;
15178
15179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15180     {
15181       if (unformat (i, "sa_id %d", &sa_id))
15182         ;
15183       else
15184         {
15185           clib_warning ("parse error '%U'", format_unformat_error, i);
15186           return -99;
15187         }
15188     }
15189
15190   M (IPSEC_SA_DUMP, mp);
15191
15192   mp->sa_id = ntohl (sa_id);
15193
15194   S (mp);
15195
15196   /* Use a control ping for synchronization */
15197   M (CONTROL_PING, mp_ping);
15198   S (mp_ping);
15199
15200   W (ret);
15201   return ret;
15202 }
15203
15204 static int
15205 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15206 {
15207   unformat_input_t *i = vam->input;
15208   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15209   u32 sw_if_index = ~0;
15210   u32 sa_id = ~0;
15211   u8 is_outbound = (u8) ~ 0;
15212   int ret;
15213
15214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15215     {
15216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15217         ;
15218       else if (unformat (i, "sa_id %d", &sa_id))
15219         ;
15220       else if (unformat (i, "outbound"))
15221         is_outbound = 1;
15222       else if (unformat (i, "inbound"))
15223         is_outbound = 0;
15224       else
15225         {
15226           clib_warning ("parse error '%U'", format_unformat_error, i);
15227           return -99;
15228         }
15229     }
15230
15231   if (sw_if_index == ~0)
15232     {
15233       errmsg ("interface must be specified");
15234       return -99;
15235     }
15236
15237   if (sa_id == ~0)
15238     {
15239       errmsg ("SA ID must be specified");
15240       return -99;
15241     }
15242
15243   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15244
15245   mp->sw_if_index = htonl (sw_if_index);
15246   mp->sa_id = htonl (sa_id);
15247   mp->is_outbound = is_outbound;
15248
15249   S (mp);
15250   W (ret);
15251
15252   return ret;
15253 }
15254
15255 static int
15256 api_get_first_msg_id (vat_main_t * vam)
15257 {
15258   vl_api_get_first_msg_id_t *mp;
15259   unformat_input_t *i = vam->input;
15260   u8 *name;
15261   u8 name_set = 0;
15262   int ret;
15263
15264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15265     {
15266       if (unformat (i, "client %s", &name))
15267         name_set = 1;
15268       else
15269         break;
15270     }
15271
15272   if (name_set == 0)
15273     {
15274       errmsg ("missing client name");
15275       return -99;
15276     }
15277   vec_add1 (name, 0);
15278
15279   if (vec_len (name) > 63)
15280     {
15281       errmsg ("client name too long");
15282       return -99;
15283     }
15284
15285   M (GET_FIRST_MSG_ID, mp);
15286   clib_memcpy (mp->name, name, vec_len (name));
15287   S (mp);
15288   W (ret);
15289   return ret;
15290 }
15291
15292 static int
15293 api_cop_interface_enable_disable (vat_main_t * vam)
15294 {
15295   unformat_input_t *line_input = vam->input;
15296   vl_api_cop_interface_enable_disable_t *mp;
15297   u32 sw_if_index = ~0;
15298   u8 enable_disable = 1;
15299   int ret;
15300
15301   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15302     {
15303       if (unformat (line_input, "disable"))
15304         enable_disable = 0;
15305       if (unformat (line_input, "enable"))
15306         enable_disable = 1;
15307       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15308                          vam, &sw_if_index))
15309         ;
15310       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15311         ;
15312       else
15313         break;
15314     }
15315
15316   if (sw_if_index == ~0)
15317     {
15318       errmsg ("missing interface name or sw_if_index");
15319       return -99;
15320     }
15321
15322   /* Construct the API message */
15323   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15324   mp->sw_if_index = ntohl (sw_if_index);
15325   mp->enable_disable = enable_disable;
15326
15327   /* send it... */
15328   S (mp);
15329   /* Wait for the reply */
15330   W (ret);
15331   return ret;
15332 }
15333
15334 static int
15335 api_cop_whitelist_enable_disable (vat_main_t * vam)
15336 {
15337   unformat_input_t *line_input = vam->input;
15338   vl_api_cop_whitelist_enable_disable_t *mp;
15339   u32 sw_if_index = ~0;
15340   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15341   u32 fib_id = 0;
15342   int ret;
15343
15344   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15345     {
15346       if (unformat (line_input, "ip4"))
15347         ip4 = 1;
15348       else if (unformat (line_input, "ip6"))
15349         ip6 = 1;
15350       else if (unformat (line_input, "default"))
15351         default_cop = 1;
15352       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15353                          vam, &sw_if_index))
15354         ;
15355       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15356         ;
15357       else if (unformat (line_input, "fib-id %d", &fib_id))
15358         ;
15359       else
15360         break;
15361     }
15362
15363   if (sw_if_index == ~0)
15364     {
15365       errmsg ("missing interface name or sw_if_index");
15366       return -99;
15367     }
15368
15369   /* Construct the API message */
15370   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15371   mp->sw_if_index = ntohl (sw_if_index);
15372   mp->fib_id = ntohl (fib_id);
15373   mp->ip4 = ip4;
15374   mp->ip6 = ip6;
15375   mp->default_cop = default_cop;
15376
15377   /* send it... */
15378   S (mp);
15379   /* Wait for the reply */
15380   W (ret);
15381   return ret;
15382 }
15383
15384 static int
15385 api_get_node_graph (vat_main_t * vam)
15386 {
15387   vl_api_get_node_graph_t *mp;
15388   int ret;
15389
15390   M (GET_NODE_GRAPH, mp);
15391
15392   /* send it... */
15393   S (mp);
15394   /* Wait for the reply */
15395   W (ret);
15396   return ret;
15397 }
15398
15399 /* *INDENT-OFF* */
15400 /** Used for parsing LISP eids */
15401 typedef CLIB_PACKED(struct{
15402   u8 addr[16];   /**< eid address */
15403   u32 len;       /**< prefix length if IP */
15404   u8 type;      /**< type of eid */
15405 }) lisp_eid_vat_t;
15406 /* *INDENT-ON* */
15407
15408 static uword
15409 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15410 {
15411   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15412
15413   clib_memset (a, 0, sizeof (a[0]));
15414
15415   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15416     {
15417       a->type = 0;              /* ipv4 type */
15418     }
15419   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15420     {
15421       a->type = 1;              /* ipv6 type */
15422     }
15423   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15424     {
15425       a->type = 2;              /* mac type */
15426     }
15427   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15428     {
15429       a->type = 3;              /* NSH type */
15430       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15431       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15432     }
15433   else
15434     {
15435       return 0;
15436     }
15437
15438   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15439     {
15440       return 0;
15441     }
15442
15443   return 1;
15444 }
15445
15446 static int
15447 lisp_eid_size_vat (u8 type)
15448 {
15449   switch (type)
15450     {
15451     case 0:
15452       return 4;
15453     case 1:
15454       return 16;
15455     case 2:
15456       return 6;
15457     case 3:
15458       return 5;
15459     }
15460   return 0;
15461 }
15462
15463 static void
15464 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15465 {
15466   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15467 }
15468
15469 static int
15470 api_one_add_del_locator_set (vat_main_t * vam)
15471 {
15472   unformat_input_t *input = vam->input;
15473   vl_api_one_add_del_locator_set_t *mp;
15474   u8 is_add = 1;
15475   u8 *locator_set_name = NULL;
15476   u8 locator_set_name_set = 0;
15477   vl_api_local_locator_t locator, *locators = 0;
15478   u32 sw_if_index, priority, weight;
15479   u32 data_len = 0;
15480
15481   int ret;
15482   /* Parse args required to build the message */
15483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15484     {
15485       if (unformat (input, "del"))
15486         {
15487           is_add = 0;
15488         }
15489       else if (unformat (input, "locator-set %s", &locator_set_name))
15490         {
15491           locator_set_name_set = 1;
15492         }
15493       else if (unformat (input, "sw_if_index %u p %u w %u",
15494                          &sw_if_index, &priority, &weight))
15495         {
15496           locator.sw_if_index = htonl (sw_if_index);
15497           locator.priority = priority;
15498           locator.weight = weight;
15499           vec_add1 (locators, locator);
15500         }
15501       else
15502         if (unformat
15503             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15504              &sw_if_index, &priority, &weight))
15505         {
15506           locator.sw_if_index = htonl (sw_if_index);
15507           locator.priority = priority;
15508           locator.weight = weight;
15509           vec_add1 (locators, locator);
15510         }
15511       else
15512         break;
15513     }
15514
15515   if (locator_set_name_set == 0)
15516     {
15517       errmsg ("missing locator-set name");
15518       vec_free (locators);
15519       return -99;
15520     }
15521
15522   if (vec_len (locator_set_name) > 64)
15523     {
15524       errmsg ("locator-set name too long");
15525       vec_free (locator_set_name);
15526       vec_free (locators);
15527       return -99;
15528     }
15529   vec_add1 (locator_set_name, 0);
15530
15531   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15532
15533   /* Construct the API message */
15534   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15535
15536   mp->is_add = is_add;
15537   clib_memcpy (mp->locator_set_name, locator_set_name,
15538                vec_len (locator_set_name));
15539   vec_free (locator_set_name);
15540
15541   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15542   if (locators)
15543     clib_memcpy (mp->locators, locators, data_len);
15544   vec_free (locators);
15545
15546   /* send it... */
15547   S (mp);
15548
15549   /* Wait for a reply... */
15550   W (ret);
15551   return ret;
15552 }
15553
15554 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15555
15556 static int
15557 api_one_add_del_locator (vat_main_t * vam)
15558 {
15559   unformat_input_t *input = vam->input;
15560   vl_api_one_add_del_locator_t *mp;
15561   u32 tmp_if_index = ~0;
15562   u32 sw_if_index = ~0;
15563   u8 sw_if_index_set = 0;
15564   u8 sw_if_index_if_name_set = 0;
15565   u32 priority = ~0;
15566   u8 priority_set = 0;
15567   u32 weight = ~0;
15568   u8 weight_set = 0;
15569   u8 is_add = 1;
15570   u8 *locator_set_name = NULL;
15571   u8 locator_set_name_set = 0;
15572   int ret;
15573
15574   /* Parse args required to build the message */
15575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15576     {
15577       if (unformat (input, "del"))
15578         {
15579           is_add = 0;
15580         }
15581       else if (unformat (input, "locator-set %s", &locator_set_name))
15582         {
15583           locator_set_name_set = 1;
15584         }
15585       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15586                          &tmp_if_index))
15587         {
15588           sw_if_index_if_name_set = 1;
15589           sw_if_index = tmp_if_index;
15590         }
15591       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15592         {
15593           sw_if_index_set = 1;
15594           sw_if_index = tmp_if_index;
15595         }
15596       else if (unformat (input, "p %d", &priority))
15597         {
15598           priority_set = 1;
15599         }
15600       else if (unformat (input, "w %d", &weight))
15601         {
15602           weight_set = 1;
15603         }
15604       else
15605         break;
15606     }
15607
15608   if (locator_set_name_set == 0)
15609     {
15610       errmsg ("missing locator-set name");
15611       return -99;
15612     }
15613
15614   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15615     {
15616       errmsg ("missing sw_if_index");
15617       vec_free (locator_set_name);
15618       return -99;
15619     }
15620
15621   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15622     {
15623       errmsg ("cannot use both params interface name and sw_if_index");
15624       vec_free (locator_set_name);
15625       return -99;
15626     }
15627
15628   if (priority_set == 0)
15629     {
15630       errmsg ("missing locator-set priority");
15631       vec_free (locator_set_name);
15632       return -99;
15633     }
15634
15635   if (weight_set == 0)
15636     {
15637       errmsg ("missing locator-set weight");
15638       vec_free (locator_set_name);
15639       return -99;
15640     }
15641
15642   if (vec_len (locator_set_name) > 64)
15643     {
15644       errmsg ("locator-set name too long");
15645       vec_free (locator_set_name);
15646       return -99;
15647     }
15648   vec_add1 (locator_set_name, 0);
15649
15650   /* Construct the API message */
15651   M (ONE_ADD_DEL_LOCATOR, mp);
15652
15653   mp->is_add = is_add;
15654   mp->sw_if_index = ntohl (sw_if_index);
15655   mp->priority = priority;
15656   mp->weight = weight;
15657   clib_memcpy (mp->locator_set_name, locator_set_name,
15658                vec_len (locator_set_name));
15659   vec_free (locator_set_name);
15660
15661   /* send it... */
15662   S (mp);
15663
15664   /* Wait for a reply... */
15665   W (ret);
15666   return ret;
15667 }
15668
15669 #define api_lisp_add_del_locator api_one_add_del_locator
15670
15671 uword
15672 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15673 {
15674   u32 *key_id = va_arg (*args, u32 *);
15675   u8 *s = 0;
15676
15677   if (unformat (input, "%s", &s))
15678     {
15679       if (!strcmp ((char *) s, "sha1"))
15680         key_id[0] = HMAC_SHA_1_96;
15681       else if (!strcmp ((char *) s, "sha256"))
15682         key_id[0] = HMAC_SHA_256_128;
15683       else
15684         {
15685           clib_warning ("invalid key_id: '%s'", s);
15686           key_id[0] = HMAC_NO_KEY;
15687         }
15688     }
15689   else
15690     return 0;
15691
15692   vec_free (s);
15693   return 1;
15694 }
15695
15696 static int
15697 api_one_add_del_local_eid (vat_main_t * vam)
15698 {
15699   unformat_input_t *input = vam->input;
15700   vl_api_one_add_del_local_eid_t *mp;
15701   u8 is_add = 1;
15702   u8 eid_set = 0;
15703   lisp_eid_vat_t _eid, *eid = &_eid;
15704   u8 *locator_set_name = 0;
15705   u8 locator_set_name_set = 0;
15706   u32 vni = 0;
15707   u16 key_id = 0;
15708   u8 *key = 0;
15709   int ret;
15710
15711   /* Parse args required to build the message */
15712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15713     {
15714       if (unformat (input, "del"))
15715         {
15716           is_add = 0;
15717         }
15718       else if (unformat (input, "vni %d", &vni))
15719         {
15720           ;
15721         }
15722       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15723         {
15724           eid_set = 1;
15725         }
15726       else if (unformat (input, "locator-set %s", &locator_set_name))
15727         {
15728           locator_set_name_set = 1;
15729         }
15730       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15731         ;
15732       else if (unformat (input, "secret-key %_%v%_", &key))
15733         ;
15734       else
15735         break;
15736     }
15737
15738   if (locator_set_name_set == 0)
15739     {
15740       errmsg ("missing locator-set name");
15741       return -99;
15742     }
15743
15744   if (0 == eid_set)
15745     {
15746       errmsg ("EID address not set!");
15747       vec_free (locator_set_name);
15748       return -99;
15749     }
15750
15751   if (key && (0 == key_id))
15752     {
15753       errmsg ("invalid key_id!");
15754       return -99;
15755     }
15756
15757   if (vec_len (key) > 64)
15758     {
15759       errmsg ("key too long");
15760       vec_free (key);
15761       return -99;
15762     }
15763
15764   if (vec_len (locator_set_name) > 64)
15765     {
15766       errmsg ("locator-set name too long");
15767       vec_free (locator_set_name);
15768       return -99;
15769     }
15770   vec_add1 (locator_set_name, 0);
15771
15772   /* Construct the API message */
15773   M (ONE_ADD_DEL_LOCAL_EID, mp);
15774
15775   mp->is_add = is_add;
15776   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15777   mp->eid_type = eid->type;
15778   mp->prefix_len = eid->len;
15779   mp->vni = clib_host_to_net_u32 (vni);
15780   mp->key_id = clib_host_to_net_u16 (key_id);
15781   clib_memcpy (mp->locator_set_name, locator_set_name,
15782                vec_len (locator_set_name));
15783   clib_memcpy (mp->key, key, vec_len (key));
15784
15785   vec_free (locator_set_name);
15786   vec_free (key);
15787
15788   /* send it... */
15789   S (mp);
15790
15791   /* Wait for a reply... */
15792   W (ret);
15793   return ret;
15794 }
15795
15796 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15797
15798 static int
15799 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15800 {
15801   u32 dp_table = 0, vni = 0;;
15802   unformat_input_t *input = vam->input;
15803   vl_api_gpe_add_del_fwd_entry_t *mp;
15804   u8 is_add = 1;
15805   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15806   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15807   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15808   u32 action = ~0, w;
15809   ip4_address_t rmt_rloc4, lcl_rloc4;
15810   ip6_address_t rmt_rloc6, lcl_rloc6;
15811   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15812   int ret;
15813
15814   clib_memset (&rloc, 0, sizeof (rloc));
15815
15816   /* Parse args required to build the message */
15817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15818     {
15819       if (unformat (input, "del"))
15820         is_add = 0;
15821       else if (unformat (input, "add"))
15822         is_add = 1;
15823       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15824         {
15825           rmt_eid_set = 1;
15826         }
15827       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15828         {
15829           lcl_eid_set = 1;
15830         }
15831       else if (unformat (input, "vrf %d", &dp_table))
15832         ;
15833       else if (unformat (input, "bd %d", &dp_table))
15834         ;
15835       else if (unformat (input, "vni %d", &vni))
15836         ;
15837       else if (unformat (input, "w %d", &w))
15838         {
15839           if (!curr_rloc)
15840             {
15841               errmsg ("No RLOC configured for setting priority/weight!");
15842               return -99;
15843             }
15844           curr_rloc->weight = w;
15845         }
15846       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15847                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15848         {
15849           rloc.is_ip4 = 1;
15850
15851           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15852           rloc.weight = 0;
15853           vec_add1 (lcl_locs, rloc);
15854
15855           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15856           vec_add1 (rmt_locs, rloc);
15857           /* weight saved in rmt loc */
15858           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15859         }
15860       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15861                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15862         {
15863           rloc.is_ip4 = 0;
15864           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15865           rloc.weight = 0;
15866           vec_add1 (lcl_locs, rloc);
15867
15868           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15869           vec_add1 (rmt_locs, rloc);
15870           /* weight saved in rmt loc */
15871           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15872         }
15873       else if (unformat (input, "action %d", &action))
15874         {
15875           ;
15876         }
15877       else
15878         {
15879           clib_warning ("parse error '%U'", format_unformat_error, input);
15880           return -99;
15881         }
15882     }
15883
15884   if (!rmt_eid_set)
15885     {
15886       errmsg ("remote eid addresses not set");
15887       return -99;
15888     }
15889
15890   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15891     {
15892       errmsg ("eid types don't match");
15893       return -99;
15894     }
15895
15896   if (0 == rmt_locs && (u32) ~ 0 == action)
15897     {
15898       errmsg ("action not set for negative mapping");
15899       return -99;
15900     }
15901
15902   /* Construct the API message */
15903   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15904       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15905
15906   mp->is_add = is_add;
15907   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15908   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15909   mp->eid_type = rmt_eid->type;
15910   mp->dp_table = clib_host_to_net_u32 (dp_table);
15911   mp->vni = clib_host_to_net_u32 (vni);
15912   mp->rmt_len = rmt_eid->len;
15913   mp->lcl_len = lcl_eid->len;
15914   mp->action = action;
15915
15916   if (0 != rmt_locs && 0 != lcl_locs)
15917     {
15918       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15919       clib_memcpy (mp->locs, lcl_locs,
15920                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15921
15922       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15923       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15924                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15925     }
15926   vec_free (lcl_locs);
15927   vec_free (rmt_locs);
15928
15929   /* send it... */
15930   S (mp);
15931
15932   /* Wait for a reply... */
15933   W (ret);
15934   return ret;
15935 }
15936
15937 static int
15938 api_one_add_del_map_server (vat_main_t * vam)
15939 {
15940   unformat_input_t *input = vam->input;
15941   vl_api_one_add_del_map_server_t *mp;
15942   u8 is_add = 1;
15943   u8 ipv4_set = 0;
15944   u8 ipv6_set = 0;
15945   ip4_address_t ipv4;
15946   ip6_address_t ipv6;
15947   int ret;
15948
15949   /* Parse args required to build the message */
15950   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (unformat (input, "del"))
15953         {
15954           is_add = 0;
15955         }
15956       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15957         {
15958           ipv4_set = 1;
15959         }
15960       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15961         {
15962           ipv6_set = 1;
15963         }
15964       else
15965         break;
15966     }
15967
15968   if (ipv4_set && ipv6_set)
15969     {
15970       errmsg ("both eid v4 and v6 addresses set");
15971       return -99;
15972     }
15973
15974   if (!ipv4_set && !ipv6_set)
15975     {
15976       errmsg ("eid addresses not set");
15977       return -99;
15978     }
15979
15980   /* Construct the API message */
15981   M (ONE_ADD_DEL_MAP_SERVER, mp);
15982
15983   mp->is_add = is_add;
15984   if (ipv6_set)
15985     {
15986       mp->is_ipv6 = 1;
15987       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15988     }
15989   else
15990     {
15991       mp->is_ipv6 = 0;
15992       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15993     }
15994
15995   /* send it... */
15996   S (mp);
15997
15998   /* Wait for a reply... */
15999   W (ret);
16000   return ret;
16001 }
16002
16003 #define api_lisp_add_del_map_server api_one_add_del_map_server
16004
16005 static int
16006 api_one_add_del_map_resolver (vat_main_t * vam)
16007 {
16008   unformat_input_t *input = vam->input;
16009   vl_api_one_add_del_map_resolver_t *mp;
16010   u8 is_add = 1;
16011   u8 ipv4_set = 0;
16012   u8 ipv6_set = 0;
16013   ip4_address_t ipv4;
16014   ip6_address_t ipv6;
16015   int ret;
16016
16017   /* Parse args required to build the message */
16018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16019     {
16020       if (unformat (input, "del"))
16021         {
16022           is_add = 0;
16023         }
16024       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16025         {
16026           ipv4_set = 1;
16027         }
16028       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16029         {
16030           ipv6_set = 1;
16031         }
16032       else
16033         break;
16034     }
16035
16036   if (ipv4_set && ipv6_set)
16037     {
16038       errmsg ("both eid v4 and v6 addresses set");
16039       return -99;
16040     }
16041
16042   if (!ipv4_set && !ipv6_set)
16043     {
16044       errmsg ("eid addresses not set");
16045       return -99;
16046     }
16047
16048   /* Construct the API message */
16049   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16050
16051   mp->is_add = is_add;
16052   if (ipv6_set)
16053     {
16054       mp->is_ipv6 = 1;
16055       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16056     }
16057   else
16058     {
16059       mp->is_ipv6 = 0;
16060       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16061     }
16062
16063   /* send it... */
16064   S (mp);
16065
16066   /* Wait for a reply... */
16067   W (ret);
16068   return ret;
16069 }
16070
16071 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16072
16073 static int
16074 api_lisp_gpe_enable_disable (vat_main_t * vam)
16075 {
16076   unformat_input_t *input = vam->input;
16077   vl_api_gpe_enable_disable_t *mp;
16078   u8 is_set = 0;
16079   u8 is_en = 1;
16080   int ret;
16081
16082   /* Parse args required to build the message */
16083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16084     {
16085       if (unformat (input, "enable"))
16086         {
16087           is_set = 1;
16088           is_en = 1;
16089         }
16090       else if (unformat (input, "disable"))
16091         {
16092           is_set = 1;
16093           is_en = 0;
16094         }
16095       else
16096         break;
16097     }
16098
16099   if (is_set == 0)
16100     {
16101       errmsg ("Value not set");
16102       return -99;
16103     }
16104
16105   /* Construct the API message */
16106   M (GPE_ENABLE_DISABLE, mp);
16107
16108   mp->is_en = is_en;
16109
16110   /* send it... */
16111   S (mp);
16112
16113   /* Wait for a reply... */
16114   W (ret);
16115   return ret;
16116 }
16117
16118 static int
16119 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16120 {
16121   unformat_input_t *input = vam->input;
16122   vl_api_one_rloc_probe_enable_disable_t *mp;
16123   u8 is_set = 0;
16124   u8 is_en = 0;
16125   int ret;
16126
16127   /* Parse args required to build the message */
16128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16129     {
16130       if (unformat (input, "enable"))
16131         {
16132           is_set = 1;
16133           is_en = 1;
16134         }
16135       else if (unformat (input, "disable"))
16136         is_set = 1;
16137       else
16138         break;
16139     }
16140
16141   if (!is_set)
16142     {
16143       errmsg ("Value not set");
16144       return -99;
16145     }
16146
16147   /* Construct the API message */
16148   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16149
16150   mp->is_enabled = is_en;
16151
16152   /* send it... */
16153   S (mp);
16154
16155   /* Wait for a reply... */
16156   W (ret);
16157   return ret;
16158 }
16159
16160 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16161
16162 static int
16163 api_one_map_register_enable_disable (vat_main_t * vam)
16164 {
16165   unformat_input_t *input = vam->input;
16166   vl_api_one_map_register_enable_disable_t *mp;
16167   u8 is_set = 0;
16168   u8 is_en = 0;
16169   int ret;
16170
16171   /* Parse args required to build the message */
16172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16173     {
16174       if (unformat (input, "enable"))
16175         {
16176           is_set = 1;
16177           is_en = 1;
16178         }
16179       else if (unformat (input, "disable"))
16180         is_set = 1;
16181       else
16182         break;
16183     }
16184
16185   if (!is_set)
16186     {
16187       errmsg ("Value not set");
16188       return -99;
16189     }
16190
16191   /* Construct the API message */
16192   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16193
16194   mp->is_enabled = is_en;
16195
16196   /* send it... */
16197   S (mp);
16198
16199   /* Wait for a reply... */
16200   W (ret);
16201   return ret;
16202 }
16203
16204 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16205
16206 static int
16207 api_one_enable_disable (vat_main_t * vam)
16208 {
16209   unformat_input_t *input = vam->input;
16210   vl_api_one_enable_disable_t *mp;
16211   u8 is_set = 0;
16212   u8 is_en = 0;
16213   int ret;
16214
16215   /* Parse args required to build the message */
16216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16217     {
16218       if (unformat (input, "enable"))
16219         {
16220           is_set = 1;
16221           is_en = 1;
16222         }
16223       else if (unformat (input, "disable"))
16224         {
16225           is_set = 1;
16226         }
16227       else
16228         break;
16229     }
16230
16231   if (!is_set)
16232     {
16233       errmsg ("Value not set");
16234       return -99;
16235     }
16236
16237   /* Construct the API message */
16238   M (ONE_ENABLE_DISABLE, mp);
16239
16240   mp->is_en = is_en;
16241
16242   /* send it... */
16243   S (mp);
16244
16245   /* Wait for a reply... */
16246   W (ret);
16247   return ret;
16248 }
16249
16250 #define api_lisp_enable_disable api_one_enable_disable
16251
16252 static int
16253 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16254 {
16255   unformat_input_t *input = vam->input;
16256   vl_api_one_enable_disable_xtr_mode_t *mp;
16257   u8 is_set = 0;
16258   u8 is_en = 0;
16259   int ret;
16260
16261   /* Parse args required to build the message */
16262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263     {
16264       if (unformat (input, "enable"))
16265         {
16266           is_set = 1;
16267           is_en = 1;
16268         }
16269       else if (unformat (input, "disable"))
16270         {
16271           is_set = 1;
16272         }
16273       else
16274         break;
16275     }
16276
16277   if (!is_set)
16278     {
16279       errmsg ("Value not set");
16280       return -99;
16281     }
16282
16283   /* Construct the API message */
16284   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16285
16286   mp->is_en = is_en;
16287
16288   /* send it... */
16289   S (mp);
16290
16291   /* Wait for a reply... */
16292   W (ret);
16293   return ret;
16294 }
16295
16296 static int
16297 api_one_show_xtr_mode (vat_main_t * vam)
16298 {
16299   vl_api_one_show_xtr_mode_t *mp;
16300   int ret;
16301
16302   /* Construct the API message */
16303   M (ONE_SHOW_XTR_MODE, mp);
16304
16305   /* send it... */
16306   S (mp);
16307
16308   /* Wait for a reply... */
16309   W (ret);
16310   return ret;
16311 }
16312
16313 static int
16314 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16315 {
16316   unformat_input_t *input = vam->input;
16317   vl_api_one_enable_disable_pitr_mode_t *mp;
16318   u8 is_set = 0;
16319   u8 is_en = 0;
16320   int ret;
16321
16322   /* Parse args required to build the message */
16323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16324     {
16325       if (unformat (input, "enable"))
16326         {
16327           is_set = 1;
16328           is_en = 1;
16329         }
16330       else if (unformat (input, "disable"))
16331         {
16332           is_set = 1;
16333         }
16334       else
16335         break;
16336     }
16337
16338   if (!is_set)
16339     {
16340       errmsg ("Value not set");
16341       return -99;
16342     }
16343
16344   /* Construct the API message */
16345   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16346
16347   mp->is_en = is_en;
16348
16349   /* send it... */
16350   S (mp);
16351
16352   /* Wait for a reply... */
16353   W (ret);
16354   return ret;
16355 }
16356
16357 static int
16358 api_one_show_pitr_mode (vat_main_t * vam)
16359 {
16360   vl_api_one_show_pitr_mode_t *mp;
16361   int ret;
16362
16363   /* Construct the API message */
16364   M (ONE_SHOW_PITR_MODE, mp);
16365
16366   /* send it... */
16367   S (mp);
16368
16369   /* Wait for a reply... */
16370   W (ret);
16371   return ret;
16372 }
16373
16374 static int
16375 api_one_enable_disable_petr_mode (vat_main_t * vam)
16376 {
16377   unformat_input_t *input = vam->input;
16378   vl_api_one_enable_disable_petr_mode_t *mp;
16379   u8 is_set = 0;
16380   u8 is_en = 0;
16381   int ret;
16382
16383   /* Parse args required to build the message */
16384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16385     {
16386       if (unformat (input, "enable"))
16387         {
16388           is_set = 1;
16389           is_en = 1;
16390         }
16391       else if (unformat (input, "disable"))
16392         {
16393           is_set = 1;
16394         }
16395       else
16396         break;
16397     }
16398
16399   if (!is_set)
16400     {
16401       errmsg ("Value not set");
16402       return -99;
16403     }
16404
16405   /* Construct the API message */
16406   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16407
16408   mp->is_en = is_en;
16409
16410   /* send it... */
16411   S (mp);
16412
16413   /* Wait for a reply... */
16414   W (ret);
16415   return ret;
16416 }
16417
16418 static int
16419 api_one_show_petr_mode (vat_main_t * vam)
16420 {
16421   vl_api_one_show_petr_mode_t *mp;
16422   int ret;
16423
16424   /* Construct the API message */
16425   M (ONE_SHOW_PETR_MODE, mp);
16426
16427   /* send it... */
16428   S (mp);
16429
16430   /* Wait for a reply... */
16431   W (ret);
16432   return ret;
16433 }
16434
16435 static int
16436 api_show_one_map_register_state (vat_main_t * vam)
16437 {
16438   vl_api_show_one_map_register_state_t *mp;
16439   int ret;
16440
16441   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16442
16443   /* send */
16444   S (mp);
16445
16446   /* wait for reply */
16447   W (ret);
16448   return ret;
16449 }
16450
16451 #define api_show_lisp_map_register_state api_show_one_map_register_state
16452
16453 static int
16454 api_show_one_rloc_probe_state (vat_main_t * vam)
16455 {
16456   vl_api_show_one_rloc_probe_state_t *mp;
16457   int ret;
16458
16459   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16460
16461   /* send */
16462   S (mp);
16463
16464   /* wait for reply */
16465   W (ret);
16466   return ret;
16467 }
16468
16469 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16470
16471 static int
16472 api_one_add_del_ndp_entry (vat_main_t * vam)
16473 {
16474   vl_api_one_add_del_ndp_entry_t *mp;
16475   unformat_input_t *input = vam->input;
16476   u8 is_add = 1;
16477   u8 mac_set = 0;
16478   u8 bd_set = 0;
16479   u8 ip_set = 0;
16480   u8 mac[6] = { 0, };
16481   u8 ip6[16] = { 0, };
16482   u32 bd = ~0;
16483   int ret;
16484
16485   /* Parse args required to build the message */
16486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16487     {
16488       if (unformat (input, "del"))
16489         is_add = 0;
16490       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16491         mac_set = 1;
16492       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16493         ip_set = 1;
16494       else if (unformat (input, "bd %d", &bd))
16495         bd_set = 1;
16496       else
16497         {
16498           errmsg ("parse error '%U'", format_unformat_error, input);
16499           return -99;
16500         }
16501     }
16502
16503   if (!bd_set || !ip_set || (!mac_set && is_add))
16504     {
16505       errmsg ("Missing BD, IP or MAC!");
16506       return -99;
16507     }
16508
16509   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16510   mp->is_add = is_add;
16511   clib_memcpy (mp->mac, mac, 6);
16512   mp->bd = clib_host_to_net_u32 (bd);
16513   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16514
16515   /* send */
16516   S (mp);
16517
16518   /* wait for reply */
16519   W (ret);
16520   return ret;
16521 }
16522
16523 static int
16524 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16525 {
16526   vl_api_one_add_del_l2_arp_entry_t *mp;
16527   unformat_input_t *input = vam->input;
16528   u8 is_add = 1;
16529   u8 mac_set = 0;
16530   u8 bd_set = 0;
16531   u8 ip_set = 0;
16532   u8 mac[6] = { 0, };
16533   u32 ip4 = 0, bd = ~0;
16534   int ret;
16535
16536   /* Parse args required to build the message */
16537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16538     {
16539       if (unformat (input, "del"))
16540         is_add = 0;
16541       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16542         mac_set = 1;
16543       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16544         ip_set = 1;
16545       else if (unformat (input, "bd %d", &bd))
16546         bd_set = 1;
16547       else
16548         {
16549           errmsg ("parse error '%U'", format_unformat_error, input);
16550           return -99;
16551         }
16552     }
16553
16554   if (!bd_set || !ip_set || (!mac_set && is_add))
16555     {
16556       errmsg ("Missing BD, IP or MAC!");
16557       return -99;
16558     }
16559
16560   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16561   mp->is_add = is_add;
16562   clib_memcpy (mp->mac, mac, 6);
16563   mp->bd = clib_host_to_net_u32 (bd);
16564   mp->ip4 = ip4;
16565
16566   /* send */
16567   S (mp);
16568
16569   /* wait for reply */
16570   W (ret);
16571   return ret;
16572 }
16573
16574 static int
16575 api_one_ndp_bd_get (vat_main_t * vam)
16576 {
16577   vl_api_one_ndp_bd_get_t *mp;
16578   int ret;
16579
16580   M (ONE_NDP_BD_GET, mp);
16581
16582   /* send */
16583   S (mp);
16584
16585   /* wait for reply */
16586   W (ret);
16587   return ret;
16588 }
16589
16590 static int
16591 api_one_ndp_entries_get (vat_main_t * vam)
16592 {
16593   vl_api_one_ndp_entries_get_t *mp;
16594   unformat_input_t *input = vam->input;
16595   u8 bd_set = 0;
16596   u32 bd = ~0;
16597   int ret;
16598
16599   /* Parse args required to build the message */
16600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16601     {
16602       if (unformat (input, "bd %d", &bd))
16603         bd_set = 1;
16604       else
16605         {
16606           errmsg ("parse error '%U'", format_unformat_error, input);
16607           return -99;
16608         }
16609     }
16610
16611   if (!bd_set)
16612     {
16613       errmsg ("Expected bridge domain!");
16614       return -99;
16615     }
16616
16617   M (ONE_NDP_ENTRIES_GET, mp);
16618   mp->bd = clib_host_to_net_u32 (bd);
16619
16620   /* send */
16621   S (mp);
16622
16623   /* wait for reply */
16624   W (ret);
16625   return ret;
16626 }
16627
16628 static int
16629 api_one_l2_arp_bd_get (vat_main_t * vam)
16630 {
16631   vl_api_one_l2_arp_bd_get_t *mp;
16632   int ret;
16633
16634   M (ONE_L2_ARP_BD_GET, mp);
16635
16636   /* send */
16637   S (mp);
16638
16639   /* wait for reply */
16640   W (ret);
16641   return ret;
16642 }
16643
16644 static int
16645 api_one_l2_arp_entries_get (vat_main_t * vam)
16646 {
16647   vl_api_one_l2_arp_entries_get_t *mp;
16648   unformat_input_t *input = vam->input;
16649   u8 bd_set = 0;
16650   u32 bd = ~0;
16651   int ret;
16652
16653   /* Parse args required to build the message */
16654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16655     {
16656       if (unformat (input, "bd %d", &bd))
16657         bd_set = 1;
16658       else
16659         {
16660           errmsg ("parse error '%U'", format_unformat_error, input);
16661           return -99;
16662         }
16663     }
16664
16665   if (!bd_set)
16666     {
16667       errmsg ("Expected bridge domain!");
16668       return -99;
16669     }
16670
16671   M (ONE_L2_ARP_ENTRIES_GET, mp);
16672   mp->bd = clib_host_to_net_u32 (bd);
16673
16674   /* send */
16675   S (mp);
16676
16677   /* wait for reply */
16678   W (ret);
16679   return ret;
16680 }
16681
16682 static int
16683 api_one_stats_enable_disable (vat_main_t * vam)
16684 {
16685   vl_api_one_stats_enable_disable_t *mp;
16686   unformat_input_t *input = vam->input;
16687   u8 is_set = 0;
16688   u8 is_en = 0;
16689   int ret;
16690
16691   /* Parse args required to build the message */
16692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16693     {
16694       if (unformat (input, "enable"))
16695         {
16696           is_set = 1;
16697           is_en = 1;
16698         }
16699       else if (unformat (input, "disable"))
16700         {
16701           is_set = 1;
16702         }
16703       else
16704         break;
16705     }
16706
16707   if (!is_set)
16708     {
16709       errmsg ("Value not set");
16710       return -99;
16711     }
16712
16713   M (ONE_STATS_ENABLE_DISABLE, mp);
16714   mp->is_en = is_en;
16715
16716   /* send */
16717   S (mp);
16718
16719   /* wait for reply */
16720   W (ret);
16721   return ret;
16722 }
16723
16724 static int
16725 api_show_one_stats_enable_disable (vat_main_t * vam)
16726 {
16727   vl_api_show_one_stats_enable_disable_t *mp;
16728   int ret;
16729
16730   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16731
16732   /* send */
16733   S (mp);
16734
16735   /* wait for reply */
16736   W (ret);
16737   return ret;
16738 }
16739
16740 static int
16741 api_show_one_map_request_mode (vat_main_t * vam)
16742 {
16743   vl_api_show_one_map_request_mode_t *mp;
16744   int ret;
16745
16746   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16747
16748   /* send */
16749   S (mp);
16750
16751   /* wait for reply */
16752   W (ret);
16753   return ret;
16754 }
16755
16756 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16757
16758 static int
16759 api_one_map_request_mode (vat_main_t * vam)
16760 {
16761   unformat_input_t *input = vam->input;
16762   vl_api_one_map_request_mode_t *mp;
16763   u8 mode = 0;
16764   int ret;
16765
16766   /* Parse args required to build the message */
16767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16768     {
16769       if (unformat (input, "dst-only"))
16770         mode = 0;
16771       else if (unformat (input, "src-dst"))
16772         mode = 1;
16773       else
16774         {
16775           errmsg ("parse error '%U'", format_unformat_error, input);
16776           return -99;
16777         }
16778     }
16779
16780   M (ONE_MAP_REQUEST_MODE, mp);
16781
16782   mp->mode = mode;
16783
16784   /* send */
16785   S (mp);
16786
16787   /* wait for reply */
16788   W (ret);
16789   return ret;
16790 }
16791
16792 #define api_lisp_map_request_mode api_one_map_request_mode
16793
16794 /**
16795  * Enable/disable ONE proxy ITR.
16796  *
16797  * @param vam vpp API test context
16798  * @return return code
16799  */
16800 static int
16801 api_one_pitr_set_locator_set (vat_main_t * vam)
16802 {
16803   u8 ls_name_set = 0;
16804   unformat_input_t *input = vam->input;
16805   vl_api_one_pitr_set_locator_set_t *mp;
16806   u8 is_add = 1;
16807   u8 *ls_name = 0;
16808   int ret;
16809
16810   /* Parse args required to build the message */
16811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16812     {
16813       if (unformat (input, "del"))
16814         is_add = 0;
16815       else if (unformat (input, "locator-set %s", &ls_name))
16816         ls_name_set = 1;
16817       else
16818         {
16819           errmsg ("parse error '%U'", format_unformat_error, input);
16820           return -99;
16821         }
16822     }
16823
16824   if (!ls_name_set)
16825     {
16826       errmsg ("locator-set name not set!");
16827       return -99;
16828     }
16829
16830   M (ONE_PITR_SET_LOCATOR_SET, mp);
16831
16832   mp->is_add = is_add;
16833   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16834   vec_free (ls_name);
16835
16836   /* send */
16837   S (mp);
16838
16839   /* wait for reply */
16840   W (ret);
16841   return ret;
16842 }
16843
16844 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16845
16846 static int
16847 api_one_nsh_set_locator_set (vat_main_t * vam)
16848 {
16849   u8 ls_name_set = 0;
16850   unformat_input_t *input = vam->input;
16851   vl_api_one_nsh_set_locator_set_t *mp;
16852   u8 is_add = 1;
16853   u8 *ls_name = 0;
16854   int ret;
16855
16856   /* Parse args required to build the message */
16857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16858     {
16859       if (unformat (input, "del"))
16860         is_add = 0;
16861       else if (unformat (input, "ls %s", &ls_name))
16862         ls_name_set = 1;
16863       else
16864         {
16865           errmsg ("parse error '%U'", format_unformat_error, input);
16866           return -99;
16867         }
16868     }
16869
16870   if (!ls_name_set && is_add)
16871     {
16872       errmsg ("locator-set name not set!");
16873       return -99;
16874     }
16875
16876   M (ONE_NSH_SET_LOCATOR_SET, mp);
16877
16878   mp->is_add = is_add;
16879   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16880   vec_free (ls_name);
16881
16882   /* send */
16883   S (mp);
16884
16885   /* wait for reply */
16886   W (ret);
16887   return ret;
16888 }
16889
16890 static int
16891 api_show_one_pitr (vat_main_t * vam)
16892 {
16893   vl_api_show_one_pitr_t *mp;
16894   int ret;
16895
16896   if (!vam->json_output)
16897     {
16898       print (vam->ofp, "%=20s", "lisp status:");
16899     }
16900
16901   M (SHOW_ONE_PITR, mp);
16902   /* send it... */
16903   S (mp);
16904
16905   /* Wait for a reply... */
16906   W (ret);
16907   return ret;
16908 }
16909
16910 #define api_show_lisp_pitr api_show_one_pitr
16911
16912 static int
16913 api_one_use_petr (vat_main_t * vam)
16914 {
16915   unformat_input_t *input = vam->input;
16916   vl_api_one_use_petr_t *mp;
16917   u8 is_add = 0;
16918   ip_address_t ip;
16919   int ret;
16920
16921   clib_memset (&ip, 0, sizeof (ip));
16922
16923   /* Parse args required to build the message */
16924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16925     {
16926       if (unformat (input, "disable"))
16927         is_add = 0;
16928       else
16929         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16930         {
16931           is_add = 1;
16932           ip_addr_version (&ip) = IP4;
16933         }
16934       else
16935         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16936         {
16937           is_add = 1;
16938           ip_addr_version (&ip) = IP6;
16939         }
16940       else
16941         {
16942           errmsg ("parse error '%U'", format_unformat_error, input);
16943           return -99;
16944         }
16945     }
16946
16947   M (ONE_USE_PETR, mp);
16948
16949   mp->is_add = is_add;
16950   if (is_add)
16951     {
16952       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16953       if (mp->is_ip4)
16954         clib_memcpy (mp->address, &ip, 4);
16955       else
16956         clib_memcpy (mp->address, &ip, 16);
16957     }
16958
16959   /* send */
16960   S (mp);
16961
16962   /* wait for reply */
16963   W (ret);
16964   return ret;
16965 }
16966
16967 #define api_lisp_use_petr api_one_use_petr
16968
16969 static int
16970 api_show_one_nsh_mapping (vat_main_t * vam)
16971 {
16972   vl_api_show_one_use_petr_t *mp;
16973   int ret;
16974
16975   if (!vam->json_output)
16976     {
16977       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16978     }
16979
16980   M (SHOW_ONE_NSH_MAPPING, mp);
16981   /* send it... */
16982   S (mp);
16983
16984   /* Wait for a reply... */
16985   W (ret);
16986   return ret;
16987 }
16988
16989 static int
16990 api_show_one_use_petr (vat_main_t * vam)
16991 {
16992   vl_api_show_one_use_petr_t *mp;
16993   int ret;
16994
16995   if (!vam->json_output)
16996     {
16997       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16998     }
16999
17000   M (SHOW_ONE_USE_PETR, mp);
17001   /* send it... */
17002   S (mp);
17003
17004   /* Wait for a reply... */
17005   W (ret);
17006   return ret;
17007 }
17008
17009 #define api_show_lisp_use_petr api_show_one_use_petr
17010
17011 /**
17012  * Add/delete mapping between vni and vrf
17013  */
17014 static int
17015 api_one_eid_table_add_del_map (vat_main_t * vam)
17016 {
17017   unformat_input_t *input = vam->input;
17018   vl_api_one_eid_table_add_del_map_t *mp;
17019   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17020   u32 vni, vrf, bd_index;
17021   int ret;
17022
17023   /* Parse args required to build the message */
17024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17025     {
17026       if (unformat (input, "del"))
17027         is_add = 0;
17028       else if (unformat (input, "vrf %d", &vrf))
17029         vrf_set = 1;
17030       else if (unformat (input, "bd_index %d", &bd_index))
17031         bd_index_set = 1;
17032       else if (unformat (input, "vni %d", &vni))
17033         vni_set = 1;
17034       else
17035         break;
17036     }
17037
17038   if (!vni_set || (!vrf_set && !bd_index_set))
17039     {
17040       errmsg ("missing arguments!");
17041       return -99;
17042     }
17043
17044   if (vrf_set && bd_index_set)
17045     {
17046       errmsg ("error: both vrf and bd entered!");
17047       return -99;
17048     }
17049
17050   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17051
17052   mp->is_add = is_add;
17053   mp->vni = htonl (vni);
17054   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17055   mp->is_l2 = bd_index_set;
17056
17057   /* send */
17058   S (mp);
17059
17060   /* wait for reply */
17061   W (ret);
17062   return ret;
17063 }
17064
17065 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17066
17067 uword
17068 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17069 {
17070   u32 *action = va_arg (*args, u32 *);
17071   u8 *s = 0;
17072
17073   if (unformat (input, "%s", &s))
17074     {
17075       if (!strcmp ((char *) s, "no-action"))
17076         action[0] = 0;
17077       else if (!strcmp ((char *) s, "natively-forward"))
17078         action[0] = 1;
17079       else if (!strcmp ((char *) s, "send-map-request"))
17080         action[0] = 2;
17081       else if (!strcmp ((char *) s, "drop"))
17082         action[0] = 3;
17083       else
17084         {
17085           clib_warning ("invalid action: '%s'", s);
17086           action[0] = 3;
17087         }
17088     }
17089   else
17090     return 0;
17091
17092   vec_free (s);
17093   return 1;
17094 }
17095
17096 /**
17097  * Add/del remote mapping to/from ONE control plane
17098  *
17099  * @param vam vpp API test context
17100  * @return return code
17101  */
17102 static int
17103 api_one_add_del_remote_mapping (vat_main_t * vam)
17104 {
17105   unformat_input_t *input = vam->input;
17106   vl_api_one_add_del_remote_mapping_t *mp;
17107   u32 vni = 0;
17108   lisp_eid_vat_t _eid, *eid = &_eid;
17109   lisp_eid_vat_t _seid, *seid = &_seid;
17110   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17111   u32 action = ~0, p, w, data_len;
17112   ip4_address_t rloc4;
17113   ip6_address_t rloc6;
17114   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17115   int ret;
17116
17117   clib_memset (&rloc, 0, sizeof (rloc));
17118
17119   /* Parse args required to build the message */
17120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17121     {
17122       if (unformat (input, "del-all"))
17123         {
17124           del_all = 1;
17125         }
17126       else if (unformat (input, "del"))
17127         {
17128           is_add = 0;
17129         }
17130       else if (unformat (input, "add"))
17131         {
17132           is_add = 1;
17133         }
17134       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17135         {
17136           eid_set = 1;
17137         }
17138       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17139         {
17140           seid_set = 1;
17141         }
17142       else if (unformat (input, "vni %d", &vni))
17143         {
17144           ;
17145         }
17146       else if (unformat (input, "p %d w %d", &p, &w))
17147         {
17148           if (!curr_rloc)
17149             {
17150               errmsg ("No RLOC configured for setting priority/weight!");
17151               return -99;
17152             }
17153           curr_rloc->priority = p;
17154           curr_rloc->weight = w;
17155         }
17156       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17157         {
17158           rloc.is_ip4 = 1;
17159           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17160           vec_add1 (rlocs, rloc);
17161           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17162         }
17163       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17164         {
17165           rloc.is_ip4 = 0;
17166           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17167           vec_add1 (rlocs, rloc);
17168           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17169         }
17170       else if (unformat (input, "action %U",
17171                          unformat_negative_mapping_action, &action))
17172         {
17173           ;
17174         }
17175       else
17176         {
17177           clib_warning ("parse error '%U'", format_unformat_error, input);
17178           return -99;
17179         }
17180     }
17181
17182   if (0 == eid_set)
17183     {
17184       errmsg ("missing params!");
17185       return -99;
17186     }
17187
17188   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17189     {
17190       errmsg ("no action set for negative map-reply!");
17191       return -99;
17192     }
17193
17194   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17195
17196   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17197   mp->is_add = is_add;
17198   mp->vni = htonl (vni);
17199   mp->action = (u8) action;
17200   mp->is_src_dst = seid_set;
17201   mp->eid_len = eid->len;
17202   mp->seid_len = seid->len;
17203   mp->del_all = del_all;
17204   mp->eid_type = eid->type;
17205   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17206   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17207
17208   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17209   clib_memcpy (mp->rlocs, rlocs, data_len);
17210   vec_free (rlocs);
17211
17212   /* send it... */
17213   S (mp);
17214
17215   /* Wait for a reply... */
17216   W (ret);
17217   return ret;
17218 }
17219
17220 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17221
17222 /**
17223  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17224  * forwarding entries in data-plane accordingly.
17225  *
17226  * @param vam vpp API test context
17227  * @return return code
17228  */
17229 static int
17230 api_one_add_del_adjacency (vat_main_t * vam)
17231 {
17232   unformat_input_t *input = vam->input;
17233   vl_api_one_add_del_adjacency_t *mp;
17234   u32 vni = 0;
17235   ip4_address_t leid4, reid4;
17236   ip6_address_t leid6, reid6;
17237   u8 reid_mac[6] = { 0 };
17238   u8 leid_mac[6] = { 0 };
17239   u8 reid_type, leid_type;
17240   u32 leid_len = 0, reid_len = 0, len;
17241   u8 is_add = 1;
17242   int ret;
17243
17244   leid_type = reid_type = (u8) ~ 0;
17245
17246   /* Parse args required to build the message */
17247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17248     {
17249       if (unformat (input, "del"))
17250         {
17251           is_add = 0;
17252         }
17253       else if (unformat (input, "add"))
17254         {
17255           is_add = 1;
17256         }
17257       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17258                          &reid4, &len))
17259         {
17260           reid_type = 0;        /* ipv4 */
17261           reid_len = len;
17262         }
17263       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17264                          &reid6, &len))
17265         {
17266           reid_type = 1;        /* ipv6 */
17267           reid_len = len;
17268         }
17269       else if (unformat (input, "reid %U", unformat_ethernet_address,
17270                          reid_mac))
17271         {
17272           reid_type = 2;        /* mac */
17273         }
17274       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17275                          &leid4, &len))
17276         {
17277           leid_type = 0;        /* ipv4 */
17278           leid_len = len;
17279         }
17280       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17281                          &leid6, &len))
17282         {
17283           leid_type = 1;        /* ipv6 */
17284           leid_len = len;
17285         }
17286       else if (unformat (input, "leid %U", unformat_ethernet_address,
17287                          leid_mac))
17288         {
17289           leid_type = 2;        /* mac */
17290         }
17291       else if (unformat (input, "vni %d", &vni))
17292         {
17293           ;
17294         }
17295       else
17296         {
17297           errmsg ("parse error '%U'", format_unformat_error, input);
17298           return -99;
17299         }
17300     }
17301
17302   if ((u8) ~ 0 == reid_type)
17303     {
17304       errmsg ("missing params!");
17305       return -99;
17306     }
17307
17308   if (leid_type != reid_type)
17309     {
17310       errmsg ("remote and local EIDs are of different types!");
17311       return -99;
17312     }
17313
17314   M (ONE_ADD_DEL_ADJACENCY, mp);
17315   mp->is_add = is_add;
17316   mp->vni = htonl (vni);
17317   mp->leid_len = leid_len;
17318   mp->reid_len = reid_len;
17319   mp->eid_type = reid_type;
17320
17321   switch (mp->eid_type)
17322     {
17323     case 0:
17324       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17325       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17326       break;
17327     case 1:
17328       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17329       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17330       break;
17331     case 2:
17332       clib_memcpy (mp->leid, leid_mac, 6);
17333       clib_memcpy (mp->reid, reid_mac, 6);
17334       break;
17335     default:
17336       errmsg ("unknown EID type %d!", mp->eid_type);
17337       return 0;
17338     }
17339
17340   /* send it... */
17341   S (mp);
17342
17343   /* Wait for a reply... */
17344   W (ret);
17345   return ret;
17346 }
17347
17348 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17349
17350 uword
17351 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17352 {
17353   u32 *mode = va_arg (*args, u32 *);
17354
17355   if (unformat (input, "lisp"))
17356     *mode = 0;
17357   else if (unformat (input, "vxlan"))
17358     *mode = 1;
17359   else
17360     return 0;
17361
17362   return 1;
17363 }
17364
17365 static int
17366 api_gpe_get_encap_mode (vat_main_t * vam)
17367 {
17368   vl_api_gpe_get_encap_mode_t *mp;
17369   int ret;
17370
17371   /* Construct the API message */
17372   M (GPE_GET_ENCAP_MODE, mp);
17373
17374   /* send it... */
17375   S (mp);
17376
17377   /* Wait for a reply... */
17378   W (ret);
17379   return ret;
17380 }
17381
17382 static int
17383 api_gpe_set_encap_mode (vat_main_t * vam)
17384 {
17385   unformat_input_t *input = vam->input;
17386   vl_api_gpe_set_encap_mode_t *mp;
17387   int ret;
17388   u32 mode = 0;
17389
17390   /* Parse args required to build the message */
17391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17392     {
17393       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17394         ;
17395       else
17396         break;
17397     }
17398
17399   /* Construct the API message */
17400   M (GPE_SET_ENCAP_MODE, mp);
17401
17402   mp->mode = mode;
17403
17404   /* send it... */
17405   S (mp);
17406
17407   /* Wait for a reply... */
17408   W (ret);
17409   return ret;
17410 }
17411
17412 static int
17413 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17414 {
17415   unformat_input_t *input = vam->input;
17416   vl_api_gpe_add_del_iface_t *mp;
17417   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17418   u32 dp_table = 0, vni = 0;
17419   int ret;
17420
17421   /* Parse args required to build the message */
17422   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17423     {
17424       if (unformat (input, "up"))
17425         {
17426           action_set = 1;
17427           is_add = 1;
17428         }
17429       else if (unformat (input, "down"))
17430         {
17431           action_set = 1;
17432           is_add = 0;
17433         }
17434       else if (unformat (input, "table_id %d", &dp_table))
17435         {
17436           dp_table_set = 1;
17437         }
17438       else if (unformat (input, "bd_id %d", &dp_table))
17439         {
17440           dp_table_set = 1;
17441           is_l2 = 1;
17442         }
17443       else if (unformat (input, "vni %d", &vni))
17444         {
17445           vni_set = 1;
17446         }
17447       else
17448         break;
17449     }
17450
17451   if (action_set == 0)
17452     {
17453       errmsg ("Action not set");
17454       return -99;
17455     }
17456   if (dp_table_set == 0 || vni_set == 0)
17457     {
17458       errmsg ("vni and dp_table must be set");
17459       return -99;
17460     }
17461
17462   /* Construct the API message */
17463   M (GPE_ADD_DEL_IFACE, mp);
17464
17465   mp->is_add = is_add;
17466   mp->dp_table = clib_host_to_net_u32 (dp_table);
17467   mp->is_l2 = is_l2;
17468   mp->vni = clib_host_to_net_u32 (vni);
17469
17470   /* send it... */
17471   S (mp);
17472
17473   /* Wait for a reply... */
17474   W (ret);
17475   return ret;
17476 }
17477
17478 static int
17479 api_one_map_register_fallback_threshold (vat_main_t * vam)
17480 {
17481   unformat_input_t *input = vam->input;
17482   vl_api_one_map_register_fallback_threshold_t *mp;
17483   u32 value = 0;
17484   u8 is_set = 0;
17485   int ret;
17486
17487   /* Parse args required to build the message */
17488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17489     {
17490       if (unformat (input, "%u", &value))
17491         is_set = 1;
17492       else
17493         {
17494           clib_warning ("parse error '%U'", format_unformat_error, input);
17495           return -99;
17496         }
17497     }
17498
17499   if (!is_set)
17500     {
17501       errmsg ("fallback threshold value is missing!");
17502       return -99;
17503     }
17504
17505   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17506   mp->value = clib_host_to_net_u32 (value);
17507
17508   /* send it... */
17509   S (mp);
17510
17511   /* Wait for a reply... */
17512   W (ret);
17513   return ret;
17514 }
17515
17516 static int
17517 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17518 {
17519   vl_api_show_one_map_register_fallback_threshold_t *mp;
17520   int ret;
17521
17522   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17523
17524   /* send it... */
17525   S (mp);
17526
17527   /* Wait for a reply... */
17528   W (ret);
17529   return ret;
17530 }
17531
17532 uword
17533 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17534 {
17535   u32 *proto = va_arg (*args, u32 *);
17536
17537   if (unformat (input, "udp"))
17538     *proto = 1;
17539   else if (unformat (input, "api"))
17540     *proto = 2;
17541   else
17542     return 0;
17543
17544   return 1;
17545 }
17546
17547 static int
17548 api_one_set_transport_protocol (vat_main_t * vam)
17549 {
17550   unformat_input_t *input = vam->input;
17551   vl_api_one_set_transport_protocol_t *mp;
17552   u8 is_set = 0;
17553   u32 protocol = 0;
17554   int ret;
17555
17556   /* Parse args required to build the message */
17557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17558     {
17559       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17560         is_set = 1;
17561       else
17562         {
17563           clib_warning ("parse error '%U'", format_unformat_error, input);
17564           return -99;
17565         }
17566     }
17567
17568   if (!is_set)
17569     {
17570       errmsg ("Transport protocol missing!");
17571       return -99;
17572     }
17573
17574   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17575   mp->protocol = (u8) protocol;
17576
17577   /* send it... */
17578   S (mp);
17579
17580   /* Wait for a reply... */
17581   W (ret);
17582   return ret;
17583 }
17584
17585 static int
17586 api_one_get_transport_protocol (vat_main_t * vam)
17587 {
17588   vl_api_one_get_transport_protocol_t *mp;
17589   int ret;
17590
17591   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17592
17593   /* send it... */
17594   S (mp);
17595
17596   /* Wait for a reply... */
17597   W (ret);
17598   return ret;
17599 }
17600
17601 static int
17602 api_one_map_register_set_ttl (vat_main_t * vam)
17603 {
17604   unformat_input_t *input = vam->input;
17605   vl_api_one_map_register_set_ttl_t *mp;
17606   u32 ttl = 0;
17607   u8 is_set = 0;
17608   int ret;
17609
17610   /* Parse args required to build the message */
17611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17612     {
17613       if (unformat (input, "%u", &ttl))
17614         is_set = 1;
17615       else
17616         {
17617           clib_warning ("parse error '%U'", format_unformat_error, input);
17618           return -99;
17619         }
17620     }
17621
17622   if (!is_set)
17623     {
17624       errmsg ("TTL value missing!");
17625       return -99;
17626     }
17627
17628   M (ONE_MAP_REGISTER_SET_TTL, mp);
17629   mp->ttl = clib_host_to_net_u32 (ttl);
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_show_one_map_register_ttl (vat_main_t * vam)
17641 {
17642   vl_api_show_one_map_register_ttl_t *mp;
17643   int ret;
17644
17645   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17646
17647   /* send it... */
17648   S (mp);
17649
17650   /* Wait for a reply... */
17651   W (ret);
17652   return ret;
17653 }
17654
17655 /**
17656  * Add/del map request itr rlocs from ONE control plane and updates
17657  *
17658  * @param vam vpp API test context
17659  * @return return code
17660  */
17661 static int
17662 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17663 {
17664   unformat_input_t *input = vam->input;
17665   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17666   u8 *locator_set_name = 0;
17667   u8 locator_set_name_set = 0;
17668   u8 is_add = 1;
17669   int ret;
17670
17671   /* Parse args required to build the message */
17672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17673     {
17674       if (unformat (input, "del"))
17675         {
17676           is_add = 0;
17677         }
17678       else if (unformat (input, "%_%v%_", &locator_set_name))
17679         {
17680           locator_set_name_set = 1;
17681         }
17682       else
17683         {
17684           clib_warning ("parse error '%U'", format_unformat_error, input);
17685           return -99;
17686         }
17687     }
17688
17689   if (is_add && !locator_set_name_set)
17690     {
17691       errmsg ("itr-rloc is not set!");
17692       return -99;
17693     }
17694
17695   if (is_add && vec_len (locator_set_name) > 64)
17696     {
17697       errmsg ("itr-rloc locator-set name too long");
17698       vec_free (locator_set_name);
17699       return -99;
17700     }
17701
17702   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17703   mp->is_add = is_add;
17704   if (is_add)
17705     {
17706       clib_memcpy (mp->locator_set_name, locator_set_name,
17707                    vec_len (locator_set_name));
17708     }
17709   else
17710     {
17711       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17712     }
17713   vec_free (locator_set_name);
17714
17715   /* send it... */
17716   S (mp);
17717
17718   /* Wait for a reply... */
17719   W (ret);
17720   return ret;
17721 }
17722
17723 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17724
17725 static int
17726 api_one_locator_dump (vat_main_t * vam)
17727 {
17728   unformat_input_t *input = vam->input;
17729   vl_api_one_locator_dump_t *mp;
17730   vl_api_control_ping_t *mp_ping;
17731   u8 is_index_set = 0, is_name_set = 0;
17732   u8 *ls_name = 0;
17733   u32 ls_index = ~0;
17734   int ret;
17735
17736   /* Parse args required to build the message */
17737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17738     {
17739       if (unformat (input, "ls_name %_%v%_", &ls_name))
17740         {
17741           is_name_set = 1;
17742         }
17743       else if (unformat (input, "ls_index %d", &ls_index))
17744         {
17745           is_index_set = 1;
17746         }
17747       else
17748         {
17749           errmsg ("parse error '%U'", format_unformat_error, input);
17750           return -99;
17751         }
17752     }
17753
17754   if (!is_index_set && !is_name_set)
17755     {
17756       errmsg ("error: expected one of index or name!");
17757       return -99;
17758     }
17759
17760   if (is_index_set && is_name_set)
17761     {
17762       errmsg ("error: only one param expected!");
17763       return -99;
17764     }
17765
17766   if (vec_len (ls_name) > 62)
17767     {
17768       errmsg ("error: locator set name too long!");
17769       return -99;
17770     }
17771
17772   if (!vam->json_output)
17773     {
17774       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17775     }
17776
17777   M (ONE_LOCATOR_DUMP, mp);
17778   mp->is_index_set = is_index_set;
17779
17780   if (is_index_set)
17781     mp->ls_index = clib_host_to_net_u32 (ls_index);
17782   else
17783     {
17784       vec_add1 (ls_name, 0);
17785       strncpy ((char *) mp->ls_name, (char *) ls_name,
17786                sizeof (mp->ls_name) - 1);
17787     }
17788
17789   /* send it... */
17790   S (mp);
17791
17792   /* Use a control ping for synchronization */
17793   MPING (CONTROL_PING, mp_ping);
17794   S (mp_ping);
17795
17796   /* Wait for a reply... */
17797   W (ret);
17798   return ret;
17799 }
17800
17801 #define api_lisp_locator_dump api_one_locator_dump
17802
17803 static int
17804 api_one_locator_set_dump (vat_main_t * vam)
17805 {
17806   vl_api_one_locator_set_dump_t *mp;
17807   vl_api_control_ping_t *mp_ping;
17808   unformat_input_t *input = vam->input;
17809   u8 filter = 0;
17810   int ret;
17811
17812   /* Parse args required to build the message */
17813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17814     {
17815       if (unformat (input, "local"))
17816         {
17817           filter = 1;
17818         }
17819       else if (unformat (input, "remote"))
17820         {
17821           filter = 2;
17822         }
17823       else
17824         {
17825           errmsg ("parse error '%U'", format_unformat_error, input);
17826           return -99;
17827         }
17828     }
17829
17830   if (!vam->json_output)
17831     {
17832       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17833     }
17834
17835   M (ONE_LOCATOR_SET_DUMP, mp);
17836
17837   mp->filter = filter;
17838
17839   /* send it... */
17840   S (mp);
17841
17842   /* Use a control ping for synchronization */
17843   MPING (CONTROL_PING, mp_ping);
17844   S (mp_ping);
17845
17846   /* Wait for a reply... */
17847   W (ret);
17848   return ret;
17849 }
17850
17851 #define api_lisp_locator_set_dump api_one_locator_set_dump
17852
17853 static int
17854 api_one_eid_table_map_dump (vat_main_t * vam)
17855 {
17856   u8 is_l2 = 0;
17857   u8 mode_set = 0;
17858   unformat_input_t *input = vam->input;
17859   vl_api_one_eid_table_map_dump_t *mp;
17860   vl_api_control_ping_t *mp_ping;
17861   int ret;
17862
17863   /* Parse args required to build the message */
17864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17865     {
17866       if (unformat (input, "l2"))
17867         {
17868           is_l2 = 1;
17869           mode_set = 1;
17870         }
17871       else if (unformat (input, "l3"))
17872         {
17873           is_l2 = 0;
17874           mode_set = 1;
17875         }
17876       else
17877         {
17878           errmsg ("parse error '%U'", format_unformat_error, input);
17879           return -99;
17880         }
17881     }
17882
17883   if (!mode_set)
17884     {
17885       errmsg ("expected one of 'l2' or 'l3' parameter!");
17886       return -99;
17887     }
17888
17889   if (!vam->json_output)
17890     {
17891       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17892     }
17893
17894   M (ONE_EID_TABLE_MAP_DUMP, mp);
17895   mp->is_l2 = is_l2;
17896
17897   /* send it... */
17898   S (mp);
17899
17900   /* Use a control ping for synchronization */
17901   MPING (CONTROL_PING, mp_ping);
17902   S (mp_ping);
17903
17904   /* Wait for a reply... */
17905   W (ret);
17906   return ret;
17907 }
17908
17909 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17910
17911 static int
17912 api_one_eid_table_vni_dump (vat_main_t * vam)
17913 {
17914   vl_api_one_eid_table_vni_dump_t *mp;
17915   vl_api_control_ping_t *mp_ping;
17916   int ret;
17917
17918   if (!vam->json_output)
17919     {
17920       print (vam->ofp, "VNI");
17921     }
17922
17923   M (ONE_EID_TABLE_VNI_DUMP, mp);
17924
17925   /* send it... */
17926   S (mp);
17927
17928   /* Use a control ping for synchronization */
17929   MPING (CONTROL_PING, mp_ping);
17930   S (mp_ping);
17931
17932   /* Wait for a reply... */
17933   W (ret);
17934   return ret;
17935 }
17936
17937 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17938
17939 static int
17940 api_one_eid_table_dump (vat_main_t * vam)
17941 {
17942   unformat_input_t *i = vam->input;
17943   vl_api_one_eid_table_dump_t *mp;
17944   vl_api_control_ping_t *mp_ping;
17945   struct in_addr ip4;
17946   struct in6_addr ip6;
17947   u8 mac[6];
17948   u8 eid_type = ~0, eid_set = 0;
17949   u32 prefix_length = ~0, t, vni = 0;
17950   u8 filter = 0;
17951   int ret;
17952   lisp_nsh_api_t nsh;
17953
17954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17955     {
17956       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17957         {
17958           eid_set = 1;
17959           eid_type = 0;
17960           prefix_length = t;
17961         }
17962       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17963         {
17964           eid_set = 1;
17965           eid_type = 1;
17966           prefix_length = t;
17967         }
17968       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17969         {
17970           eid_set = 1;
17971           eid_type = 2;
17972         }
17973       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17974         {
17975           eid_set = 1;
17976           eid_type = 3;
17977         }
17978       else if (unformat (i, "vni %d", &t))
17979         {
17980           vni = t;
17981         }
17982       else if (unformat (i, "local"))
17983         {
17984           filter = 1;
17985         }
17986       else if (unformat (i, "remote"))
17987         {
17988           filter = 2;
17989         }
17990       else
17991         {
17992           errmsg ("parse error '%U'", format_unformat_error, i);
17993           return -99;
17994         }
17995     }
17996
17997   if (!vam->json_output)
17998     {
17999       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18000              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18001     }
18002
18003   M (ONE_EID_TABLE_DUMP, mp);
18004
18005   mp->filter = filter;
18006   if (eid_set)
18007     {
18008       mp->eid_set = 1;
18009       mp->vni = htonl (vni);
18010       mp->eid_type = eid_type;
18011       switch (eid_type)
18012         {
18013         case 0:
18014           mp->prefix_length = prefix_length;
18015           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18016           break;
18017         case 1:
18018           mp->prefix_length = prefix_length;
18019           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18020           break;
18021         case 2:
18022           clib_memcpy (mp->eid, mac, sizeof (mac));
18023           break;
18024         case 3:
18025           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18026           break;
18027         default:
18028           errmsg ("unknown EID type %d!", eid_type);
18029           return -99;
18030         }
18031     }
18032
18033   /* send it... */
18034   S (mp);
18035
18036   /* Use a control ping for synchronization */
18037   MPING (CONTROL_PING, mp_ping);
18038   S (mp_ping);
18039
18040   /* Wait for a reply... */
18041   W (ret);
18042   return ret;
18043 }
18044
18045 #define api_lisp_eid_table_dump api_one_eid_table_dump
18046
18047 static int
18048 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18049 {
18050   unformat_input_t *i = vam->input;
18051   vl_api_gpe_fwd_entries_get_t *mp;
18052   u8 vni_set = 0;
18053   u32 vni = ~0;
18054   int ret;
18055
18056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18057     {
18058       if (unformat (i, "vni %d", &vni))
18059         {
18060           vni_set = 1;
18061         }
18062       else
18063         {
18064           errmsg ("parse error '%U'", format_unformat_error, i);
18065           return -99;
18066         }
18067     }
18068
18069   if (!vni_set)
18070     {
18071       errmsg ("vni not set!");
18072       return -99;
18073     }
18074
18075   if (!vam->json_output)
18076     {
18077       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18078              "leid", "reid");
18079     }
18080
18081   M (GPE_FWD_ENTRIES_GET, mp);
18082   mp->vni = clib_host_to_net_u32 (vni);
18083
18084   /* send it... */
18085   S (mp);
18086
18087   /* Wait for a reply... */
18088   W (ret);
18089   return ret;
18090 }
18091
18092 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18093 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18094 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18095 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18096 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18097 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18098 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18099 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18100
18101 static int
18102 api_one_adjacencies_get (vat_main_t * vam)
18103 {
18104   unformat_input_t *i = vam->input;
18105   vl_api_one_adjacencies_get_t *mp;
18106   u8 vni_set = 0;
18107   u32 vni = ~0;
18108   int ret;
18109
18110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18111     {
18112       if (unformat (i, "vni %d", &vni))
18113         {
18114           vni_set = 1;
18115         }
18116       else
18117         {
18118           errmsg ("parse error '%U'", format_unformat_error, i);
18119           return -99;
18120         }
18121     }
18122
18123   if (!vni_set)
18124     {
18125       errmsg ("vni not set!");
18126       return -99;
18127     }
18128
18129   if (!vam->json_output)
18130     {
18131       print (vam->ofp, "%s %40s", "leid", "reid");
18132     }
18133
18134   M (ONE_ADJACENCIES_GET, mp);
18135   mp->vni = clib_host_to_net_u32 (vni);
18136
18137   /* send it... */
18138   S (mp);
18139
18140   /* Wait for a reply... */
18141   W (ret);
18142   return ret;
18143 }
18144
18145 #define api_lisp_adjacencies_get api_one_adjacencies_get
18146
18147 static int
18148 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18149 {
18150   unformat_input_t *i = vam->input;
18151   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18152   int ret;
18153   u8 ip_family_set = 0, is_ip4 = 1;
18154
18155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18156     {
18157       if (unformat (i, "ip4"))
18158         {
18159           ip_family_set = 1;
18160           is_ip4 = 1;
18161         }
18162       else if (unformat (i, "ip6"))
18163         {
18164           ip_family_set = 1;
18165           is_ip4 = 0;
18166         }
18167       else
18168         {
18169           errmsg ("parse error '%U'", format_unformat_error, i);
18170           return -99;
18171         }
18172     }
18173
18174   if (!ip_family_set)
18175     {
18176       errmsg ("ip family not set!");
18177       return -99;
18178     }
18179
18180   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18181   mp->is_ip4 = is_ip4;
18182
18183   /* send it... */
18184   S (mp);
18185
18186   /* Wait for a reply... */
18187   W (ret);
18188   return ret;
18189 }
18190
18191 static int
18192 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18193 {
18194   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18195   int ret;
18196
18197   if (!vam->json_output)
18198     {
18199       print (vam->ofp, "VNIs");
18200     }
18201
18202   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18203
18204   /* send it... */
18205   S (mp);
18206
18207   /* Wait for a reply... */
18208   W (ret);
18209   return ret;
18210 }
18211
18212 static int
18213 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18214 {
18215   unformat_input_t *i = vam->input;
18216   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18217   int ret = 0;
18218   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18219   struct in_addr ip4;
18220   struct in6_addr ip6;
18221   u32 table_id = 0, nh_sw_if_index = ~0;
18222
18223   clib_memset (&ip4, 0, sizeof (ip4));
18224   clib_memset (&ip6, 0, sizeof (ip6));
18225
18226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18227     {
18228       if (unformat (i, "del"))
18229         is_add = 0;
18230       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18231                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18232         {
18233           ip_set = 1;
18234           is_ip4 = 1;
18235         }
18236       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18237                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18238         {
18239           ip_set = 1;
18240           is_ip4 = 0;
18241         }
18242       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18243         {
18244           ip_set = 1;
18245           is_ip4 = 1;
18246           nh_sw_if_index = ~0;
18247         }
18248       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18249         {
18250           ip_set = 1;
18251           is_ip4 = 0;
18252           nh_sw_if_index = ~0;
18253         }
18254       else if (unformat (i, "table %d", &table_id))
18255         ;
18256       else
18257         {
18258           errmsg ("parse error '%U'", format_unformat_error, i);
18259           return -99;
18260         }
18261     }
18262
18263   if (!ip_set)
18264     {
18265       errmsg ("nh addr not set!");
18266       return -99;
18267     }
18268
18269   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18270   mp->is_add = is_add;
18271   mp->table_id = clib_host_to_net_u32 (table_id);
18272   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18273   mp->is_ip4 = is_ip4;
18274   if (is_ip4)
18275     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18276   else
18277     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18278
18279   /* send it... */
18280   S (mp);
18281
18282   /* Wait for a reply... */
18283   W (ret);
18284   return ret;
18285 }
18286
18287 static int
18288 api_one_map_server_dump (vat_main_t * vam)
18289 {
18290   vl_api_one_map_server_dump_t *mp;
18291   vl_api_control_ping_t *mp_ping;
18292   int ret;
18293
18294   if (!vam->json_output)
18295     {
18296       print (vam->ofp, "%=20s", "Map server");
18297     }
18298
18299   M (ONE_MAP_SERVER_DUMP, mp);
18300   /* send it... */
18301   S (mp);
18302
18303   /* Use a control ping for synchronization */
18304   MPING (CONTROL_PING, mp_ping);
18305   S (mp_ping);
18306
18307   /* Wait for a reply... */
18308   W (ret);
18309   return ret;
18310 }
18311
18312 #define api_lisp_map_server_dump api_one_map_server_dump
18313
18314 static int
18315 api_one_map_resolver_dump (vat_main_t * vam)
18316 {
18317   vl_api_one_map_resolver_dump_t *mp;
18318   vl_api_control_ping_t *mp_ping;
18319   int ret;
18320
18321   if (!vam->json_output)
18322     {
18323       print (vam->ofp, "%=20s", "Map resolver");
18324     }
18325
18326   M (ONE_MAP_RESOLVER_DUMP, mp);
18327   /* send it... */
18328   S (mp);
18329
18330   /* Use a control ping for synchronization */
18331   MPING (CONTROL_PING, mp_ping);
18332   S (mp_ping);
18333
18334   /* Wait for a reply... */
18335   W (ret);
18336   return ret;
18337 }
18338
18339 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18340
18341 static int
18342 api_one_stats_flush (vat_main_t * vam)
18343 {
18344   vl_api_one_stats_flush_t *mp;
18345   int ret = 0;
18346
18347   M (ONE_STATS_FLUSH, mp);
18348   S (mp);
18349   W (ret);
18350   return ret;
18351 }
18352
18353 static int
18354 api_one_stats_dump (vat_main_t * vam)
18355 {
18356   vl_api_one_stats_dump_t *mp;
18357   vl_api_control_ping_t *mp_ping;
18358   int ret;
18359
18360   M (ONE_STATS_DUMP, mp);
18361   /* send it... */
18362   S (mp);
18363
18364   /* Use a control ping for synchronization */
18365   MPING (CONTROL_PING, mp_ping);
18366   S (mp_ping);
18367
18368   /* Wait for a reply... */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 static int
18374 api_show_one_status (vat_main_t * vam)
18375 {
18376   vl_api_show_one_status_t *mp;
18377   int ret;
18378
18379   if (!vam->json_output)
18380     {
18381       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18382     }
18383
18384   M (SHOW_ONE_STATUS, mp);
18385   /* send it... */
18386   S (mp);
18387   /* Wait for a reply... */
18388   W (ret);
18389   return ret;
18390 }
18391
18392 #define api_show_lisp_status api_show_one_status
18393
18394 static int
18395 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18396 {
18397   vl_api_gpe_fwd_entry_path_dump_t *mp;
18398   vl_api_control_ping_t *mp_ping;
18399   unformat_input_t *i = vam->input;
18400   u32 fwd_entry_index = ~0;
18401   int ret;
18402
18403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18404     {
18405       if (unformat (i, "index %d", &fwd_entry_index))
18406         ;
18407       else
18408         break;
18409     }
18410
18411   if (~0 == fwd_entry_index)
18412     {
18413       errmsg ("no index specified!");
18414       return -99;
18415     }
18416
18417   if (!vam->json_output)
18418     {
18419       print (vam->ofp, "first line");
18420     }
18421
18422   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18423
18424   /* send it... */
18425   S (mp);
18426   /* Use a control ping for synchronization */
18427   MPING (CONTROL_PING, mp_ping);
18428   S (mp_ping);
18429
18430   /* Wait for a reply... */
18431   W (ret);
18432   return ret;
18433 }
18434
18435 static int
18436 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18437 {
18438   vl_api_one_get_map_request_itr_rlocs_t *mp;
18439   int ret;
18440
18441   if (!vam->json_output)
18442     {
18443       print (vam->ofp, "%=20s", "itr-rlocs:");
18444     }
18445
18446   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18447   /* send it... */
18448   S (mp);
18449   /* Wait for a reply... */
18450   W (ret);
18451   return ret;
18452 }
18453
18454 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18455
18456 static int
18457 api_af_packet_create (vat_main_t * vam)
18458 {
18459   unformat_input_t *i = vam->input;
18460   vl_api_af_packet_create_t *mp;
18461   u8 *host_if_name = 0;
18462   u8 hw_addr[6];
18463   u8 random_hw_addr = 1;
18464   int ret;
18465
18466   clib_memset (hw_addr, 0, sizeof (hw_addr));
18467
18468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18469     {
18470       if (unformat (i, "name %s", &host_if_name))
18471         vec_add1 (host_if_name, 0);
18472       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18473         random_hw_addr = 0;
18474       else
18475         break;
18476     }
18477
18478   if (!vec_len (host_if_name))
18479     {
18480       errmsg ("host-interface name must be specified");
18481       return -99;
18482     }
18483
18484   if (vec_len (host_if_name) > 64)
18485     {
18486       errmsg ("host-interface name too long");
18487       return -99;
18488     }
18489
18490   M (AF_PACKET_CREATE, mp);
18491
18492   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18493   clib_memcpy (mp->hw_addr, hw_addr, 6);
18494   mp->use_random_hw_addr = random_hw_addr;
18495   vec_free (host_if_name);
18496
18497   S (mp);
18498
18499   /* *INDENT-OFF* */
18500   W2 (ret,
18501       ({
18502         if (ret == 0)
18503           fprintf (vam->ofp ? vam->ofp : stderr,
18504                    " new sw_if_index = %d\n", vam->sw_if_index);
18505       }));
18506   /* *INDENT-ON* */
18507   return ret;
18508 }
18509
18510 static int
18511 api_af_packet_delete (vat_main_t * vam)
18512 {
18513   unformat_input_t *i = vam->input;
18514   vl_api_af_packet_delete_t *mp;
18515   u8 *host_if_name = 0;
18516   int ret;
18517
18518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18519     {
18520       if (unformat (i, "name %s", &host_if_name))
18521         vec_add1 (host_if_name, 0);
18522       else
18523         break;
18524     }
18525
18526   if (!vec_len (host_if_name))
18527     {
18528       errmsg ("host-interface name must be specified");
18529       return -99;
18530     }
18531
18532   if (vec_len (host_if_name) > 64)
18533     {
18534       errmsg ("host-interface name too long");
18535       return -99;
18536     }
18537
18538   M (AF_PACKET_DELETE, mp);
18539
18540   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18541   vec_free (host_if_name);
18542
18543   S (mp);
18544   W (ret);
18545   return ret;
18546 }
18547
18548 static void vl_api_af_packet_details_t_handler
18549   (vl_api_af_packet_details_t * mp)
18550 {
18551   vat_main_t *vam = &vat_main;
18552
18553   print (vam->ofp, "%-16s %d",
18554          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18555 }
18556
18557 static void vl_api_af_packet_details_t_handler_json
18558   (vl_api_af_packet_details_t * mp)
18559 {
18560   vat_main_t *vam = &vat_main;
18561   vat_json_node_t *node = NULL;
18562
18563   if (VAT_JSON_ARRAY != vam->json_tree.type)
18564     {
18565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18566       vat_json_init_array (&vam->json_tree);
18567     }
18568   node = vat_json_array_add (&vam->json_tree);
18569
18570   vat_json_init_object (node);
18571   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18572   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18573 }
18574
18575 static int
18576 api_af_packet_dump (vat_main_t * vam)
18577 {
18578   vl_api_af_packet_dump_t *mp;
18579   vl_api_control_ping_t *mp_ping;
18580   int ret;
18581
18582   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18583   /* Get list of tap interfaces */
18584   M (AF_PACKET_DUMP, mp);
18585   S (mp);
18586
18587   /* Use a control ping for synchronization */
18588   MPING (CONTROL_PING, mp_ping);
18589   S (mp_ping);
18590
18591   W (ret);
18592   return ret;
18593 }
18594
18595 static int
18596 api_policer_add_del (vat_main_t * vam)
18597 {
18598   unformat_input_t *i = vam->input;
18599   vl_api_policer_add_del_t *mp;
18600   u8 is_add = 1;
18601   u8 *name = 0;
18602   u32 cir = 0;
18603   u32 eir = 0;
18604   u64 cb = 0;
18605   u64 eb = 0;
18606   u8 rate_type = 0;
18607   u8 round_type = 0;
18608   u8 type = 0;
18609   u8 color_aware = 0;
18610   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18611   int ret;
18612
18613   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18614   conform_action.dscp = 0;
18615   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18616   exceed_action.dscp = 0;
18617   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18618   violate_action.dscp = 0;
18619
18620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18621     {
18622       if (unformat (i, "del"))
18623         is_add = 0;
18624       else if (unformat (i, "name %s", &name))
18625         vec_add1 (name, 0);
18626       else if (unformat (i, "cir %u", &cir))
18627         ;
18628       else if (unformat (i, "eir %u", &eir))
18629         ;
18630       else if (unformat (i, "cb %u", &cb))
18631         ;
18632       else if (unformat (i, "eb %u", &eb))
18633         ;
18634       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18635                          &rate_type))
18636         ;
18637       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18638                          &round_type))
18639         ;
18640       else if (unformat (i, "type %U", unformat_policer_type, &type))
18641         ;
18642       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18643                          &conform_action))
18644         ;
18645       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18646                          &exceed_action))
18647         ;
18648       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18649                          &violate_action))
18650         ;
18651       else if (unformat (i, "color-aware"))
18652         color_aware = 1;
18653       else
18654         break;
18655     }
18656
18657   if (!vec_len (name))
18658     {
18659       errmsg ("policer name must be specified");
18660       return -99;
18661     }
18662
18663   if (vec_len (name) > 64)
18664     {
18665       errmsg ("policer name too long");
18666       return -99;
18667     }
18668
18669   M (POLICER_ADD_DEL, mp);
18670
18671   clib_memcpy (mp->name, name, vec_len (name));
18672   vec_free (name);
18673   mp->is_add = is_add;
18674   mp->cir = ntohl (cir);
18675   mp->eir = ntohl (eir);
18676   mp->cb = clib_net_to_host_u64 (cb);
18677   mp->eb = clib_net_to_host_u64 (eb);
18678   mp->rate_type = rate_type;
18679   mp->round_type = round_type;
18680   mp->type = type;
18681   mp->conform_action_type = conform_action.action_type;
18682   mp->conform_dscp = conform_action.dscp;
18683   mp->exceed_action_type = exceed_action.action_type;
18684   mp->exceed_dscp = exceed_action.dscp;
18685   mp->violate_action_type = violate_action.action_type;
18686   mp->violate_dscp = violate_action.dscp;
18687   mp->color_aware = color_aware;
18688
18689   S (mp);
18690   W (ret);
18691   return ret;
18692 }
18693
18694 static int
18695 api_policer_dump (vat_main_t * vam)
18696 {
18697   unformat_input_t *i = vam->input;
18698   vl_api_policer_dump_t *mp;
18699   vl_api_control_ping_t *mp_ping;
18700   u8 *match_name = 0;
18701   u8 match_name_valid = 0;
18702   int ret;
18703
18704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18705     {
18706       if (unformat (i, "name %s", &match_name))
18707         {
18708           vec_add1 (match_name, 0);
18709           match_name_valid = 1;
18710         }
18711       else
18712         break;
18713     }
18714
18715   M (POLICER_DUMP, mp);
18716   mp->match_name_valid = match_name_valid;
18717   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18718   vec_free (match_name);
18719   /* send it... */
18720   S (mp);
18721
18722   /* Use a control ping for synchronization */
18723   MPING (CONTROL_PING, mp_ping);
18724   S (mp_ping);
18725
18726   /* Wait for a reply... */
18727   W (ret);
18728   return ret;
18729 }
18730
18731 static int
18732 api_policer_classify_set_interface (vat_main_t * vam)
18733 {
18734   unformat_input_t *i = vam->input;
18735   vl_api_policer_classify_set_interface_t *mp;
18736   u32 sw_if_index;
18737   int sw_if_index_set;
18738   u32 ip4_table_index = ~0;
18739   u32 ip6_table_index = ~0;
18740   u32 l2_table_index = ~0;
18741   u8 is_add = 1;
18742   int ret;
18743
18744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18745     {
18746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18747         sw_if_index_set = 1;
18748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18749         sw_if_index_set = 1;
18750       else if (unformat (i, "del"))
18751         is_add = 0;
18752       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18753         ;
18754       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18755         ;
18756       else if (unformat (i, "l2-table %d", &l2_table_index))
18757         ;
18758       else
18759         {
18760           clib_warning ("parse error '%U'", format_unformat_error, i);
18761           return -99;
18762         }
18763     }
18764
18765   if (sw_if_index_set == 0)
18766     {
18767       errmsg ("missing interface name or sw_if_index");
18768       return -99;
18769     }
18770
18771   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18772
18773   mp->sw_if_index = ntohl (sw_if_index);
18774   mp->ip4_table_index = ntohl (ip4_table_index);
18775   mp->ip6_table_index = ntohl (ip6_table_index);
18776   mp->l2_table_index = ntohl (l2_table_index);
18777   mp->is_add = is_add;
18778
18779   S (mp);
18780   W (ret);
18781   return ret;
18782 }
18783
18784 static int
18785 api_policer_classify_dump (vat_main_t * vam)
18786 {
18787   unformat_input_t *i = vam->input;
18788   vl_api_policer_classify_dump_t *mp;
18789   vl_api_control_ping_t *mp_ping;
18790   u8 type = POLICER_CLASSIFY_N_TABLES;
18791   int ret;
18792
18793   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18794     ;
18795   else
18796     {
18797       errmsg ("classify table type must be specified");
18798       return -99;
18799     }
18800
18801   if (!vam->json_output)
18802     {
18803       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18804     }
18805
18806   M (POLICER_CLASSIFY_DUMP, mp);
18807   mp->type = type;
18808   /* send it... */
18809   S (mp);
18810
18811   /* Use a control ping for synchronization */
18812   MPING (CONTROL_PING, mp_ping);
18813   S (mp_ping);
18814
18815   /* Wait for a reply... */
18816   W (ret);
18817   return ret;
18818 }
18819
18820 static int
18821 api_netmap_create (vat_main_t * vam)
18822 {
18823   unformat_input_t *i = vam->input;
18824   vl_api_netmap_create_t *mp;
18825   u8 *if_name = 0;
18826   u8 hw_addr[6];
18827   u8 random_hw_addr = 1;
18828   u8 is_pipe = 0;
18829   u8 is_master = 0;
18830   int ret;
18831
18832   clib_memset (hw_addr, 0, sizeof (hw_addr));
18833
18834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18835     {
18836       if (unformat (i, "name %s", &if_name))
18837         vec_add1 (if_name, 0);
18838       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18839         random_hw_addr = 0;
18840       else if (unformat (i, "pipe"))
18841         is_pipe = 1;
18842       else if (unformat (i, "master"))
18843         is_master = 1;
18844       else if (unformat (i, "slave"))
18845         is_master = 0;
18846       else
18847         break;
18848     }
18849
18850   if (!vec_len (if_name))
18851     {
18852       errmsg ("interface name must be specified");
18853       return -99;
18854     }
18855
18856   if (vec_len (if_name) > 64)
18857     {
18858       errmsg ("interface name too long");
18859       return -99;
18860     }
18861
18862   M (NETMAP_CREATE, mp);
18863
18864   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18865   clib_memcpy (mp->hw_addr, hw_addr, 6);
18866   mp->use_random_hw_addr = random_hw_addr;
18867   mp->is_pipe = is_pipe;
18868   mp->is_master = is_master;
18869   vec_free (if_name);
18870
18871   S (mp);
18872   W (ret);
18873   return ret;
18874 }
18875
18876 static int
18877 api_netmap_delete (vat_main_t * vam)
18878 {
18879   unformat_input_t *i = vam->input;
18880   vl_api_netmap_delete_t *mp;
18881   u8 *if_name = 0;
18882   int ret;
18883
18884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18885     {
18886       if (unformat (i, "name %s", &if_name))
18887         vec_add1 (if_name, 0);
18888       else
18889         break;
18890     }
18891
18892   if (!vec_len (if_name))
18893     {
18894       errmsg ("interface name must be specified");
18895       return -99;
18896     }
18897
18898   if (vec_len (if_name) > 64)
18899     {
18900       errmsg ("interface name too long");
18901       return -99;
18902     }
18903
18904   M (NETMAP_DELETE, mp);
18905
18906   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18907   vec_free (if_name);
18908
18909   S (mp);
18910   W (ret);
18911   return ret;
18912 }
18913
18914 static void
18915 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18916 {
18917   if (fp->afi == IP46_TYPE_IP6)
18918     print (vam->ofp,
18919            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18920            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18921            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18922            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18923            format_ip6_address, fp->next_hop);
18924   else if (fp->afi == IP46_TYPE_IP4)
18925     print (vam->ofp,
18926            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18927            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18928            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18929            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18930            format_ip4_address, fp->next_hop);
18931 }
18932
18933 static void
18934 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18935                                  vl_api_fib_path_t * fp)
18936 {
18937   struct in_addr ip4;
18938   struct in6_addr ip6;
18939
18940   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18941   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18942   vat_json_object_add_uint (node, "is_local", fp->is_local);
18943   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18944   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18945   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18946   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18947   if (fp->afi == IP46_TYPE_IP4)
18948     {
18949       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18950       vat_json_object_add_ip4 (node, "next_hop", ip4);
18951     }
18952   else if (fp->afi == IP46_TYPE_IP6)
18953     {
18954       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18955       vat_json_object_add_ip6 (node, "next_hop", ip6);
18956     }
18957 }
18958
18959 static void
18960 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18961 {
18962   vat_main_t *vam = &vat_main;
18963   int count = ntohl (mp->mt_count);
18964   vl_api_fib_path_t *fp;
18965   i32 i;
18966
18967   print (vam->ofp, "[%d]: sw_if_index %d via:",
18968          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18969   fp = mp->mt_paths;
18970   for (i = 0; i < count; i++)
18971     {
18972       vl_api_mpls_fib_path_print (vam, fp);
18973       fp++;
18974     }
18975
18976   print (vam->ofp, "");
18977 }
18978
18979 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18980 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18981
18982 static void
18983 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18984 {
18985   vat_main_t *vam = &vat_main;
18986   vat_json_node_t *node = NULL;
18987   int count = ntohl (mp->mt_count);
18988   vl_api_fib_path_t *fp;
18989   i32 i;
18990
18991   if (VAT_JSON_ARRAY != vam->json_tree.type)
18992     {
18993       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18994       vat_json_init_array (&vam->json_tree);
18995     }
18996   node = vat_json_array_add (&vam->json_tree);
18997
18998   vat_json_init_object (node);
18999   vat_json_object_add_uint (node, "tunnel_index",
19000                             ntohl (mp->mt_tunnel_index));
19001   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19002
19003   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19004
19005   fp = mp->mt_paths;
19006   for (i = 0; i < count; i++)
19007     {
19008       vl_api_mpls_fib_path_json_print (node, fp);
19009       fp++;
19010     }
19011 }
19012
19013 static int
19014 api_mpls_tunnel_dump (vat_main_t * vam)
19015 {
19016   vl_api_mpls_tunnel_dump_t *mp;
19017   vl_api_control_ping_t *mp_ping;
19018   u32 sw_if_index = ~0;
19019   int ret;
19020
19021   /* Parse args required to build the message */
19022   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19023     {
19024       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19025         ;
19026     }
19027
19028   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19029
19030   M (MPLS_TUNNEL_DUMP, mp);
19031   mp->sw_if_index = htonl (sw_if_index);
19032   S (mp);
19033
19034   /* Use a control ping for synchronization */
19035   MPING (CONTROL_PING, mp_ping);
19036   S (mp_ping);
19037
19038   W (ret);
19039   return ret;
19040 }
19041
19042 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19043 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19044
19045
19046 static void
19047 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19048 {
19049   vat_main_t *vam = &vat_main;
19050   int count = ntohl (mp->count);
19051   vl_api_fib_path_t *fp;
19052   int i;
19053
19054   print (vam->ofp,
19055          "table-id %d, label %u, ess_bit %u",
19056          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19057   fp = mp->path;
19058   for (i = 0; i < count; i++)
19059     {
19060       vl_api_mpls_fib_path_print (vam, fp);
19061       fp++;
19062     }
19063 }
19064
19065 static void vl_api_mpls_fib_details_t_handler_json
19066   (vl_api_mpls_fib_details_t * mp)
19067 {
19068   vat_main_t *vam = &vat_main;
19069   int count = ntohl (mp->count);
19070   vat_json_node_t *node = NULL;
19071   vl_api_fib_path_t *fp;
19072   int i;
19073
19074   if (VAT_JSON_ARRAY != vam->json_tree.type)
19075     {
19076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19077       vat_json_init_array (&vam->json_tree);
19078     }
19079   node = vat_json_array_add (&vam->json_tree);
19080
19081   vat_json_init_object (node);
19082   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19083   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19084   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19085   vat_json_object_add_uint (node, "path_count", count);
19086   fp = mp->path;
19087   for (i = 0; i < count; i++)
19088     {
19089       vl_api_mpls_fib_path_json_print (node, fp);
19090       fp++;
19091     }
19092 }
19093
19094 static int
19095 api_mpls_fib_dump (vat_main_t * vam)
19096 {
19097   vl_api_mpls_fib_dump_t *mp;
19098   vl_api_control_ping_t *mp_ping;
19099   int ret;
19100
19101   M (MPLS_FIB_DUMP, mp);
19102   S (mp);
19103
19104   /* Use a control ping for synchronization */
19105   MPING (CONTROL_PING, mp_ping);
19106   S (mp_ping);
19107
19108   W (ret);
19109   return ret;
19110 }
19111
19112 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19113 #define vl_api_ip_fib_details_t_print vl_noop_handler
19114
19115 static void
19116 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19117 {
19118   vat_main_t *vam = &vat_main;
19119   int count = ntohl (mp->count);
19120   vl_api_fib_path_t *fp;
19121   int i;
19122
19123   print (vam->ofp,
19124          "table-id %d, prefix %U/%d stats-index %d",
19125          ntohl (mp->table_id), format_ip4_address, mp->address,
19126          mp->address_length, ntohl (mp->stats_index));
19127   fp = mp->path;
19128   for (i = 0; i < count; i++)
19129     {
19130       if (fp->afi == IP46_TYPE_IP6)
19131         print (vam->ofp,
19132                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19133                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19134                "next_hop_table %d",
19135                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19136                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19137                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19138       else if (fp->afi == IP46_TYPE_IP4)
19139         print (vam->ofp,
19140                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19141                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19142                "next_hop_table %d",
19143                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19144                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19145                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19146       fp++;
19147     }
19148 }
19149
19150 static void vl_api_ip_fib_details_t_handler_json
19151   (vl_api_ip_fib_details_t * mp)
19152 {
19153   vat_main_t *vam = &vat_main;
19154   int count = ntohl (mp->count);
19155   vat_json_node_t *node = NULL;
19156   struct in_addr ip4;
19157   struct in6_addr ip6;
19158   vl_api_fib_path_t *fp;
19159   int i;
19160
19161   if (VAT_JSON_ARRAY != vam->json_tree.type)
19162     {
19163       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19164       vat_json_init_array (&vam->json_tree);
19165     }
19166   node = vat_json_array_add (&vam->json_tree);
19167
19168   vat_json_init_object (node);
19169   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19170   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19171   vat_json_object_add_ip4 (node, "prefix", ip4);
19172   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19173   vat_json_object_add_uint (node, "path_count", count);
19174   fp = mp->path;
19175   for (i = 0; i < count; i++)
19176     {
19177       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19178       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19179       vat_json_object_add_uint (node, "is_local", fp->is_local);
19180       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19181       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19182       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19183       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19184       if (fp->afi == IP46_TYPE_IP4)
19185         {
19186           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19187           vat_json_object_add_ip4 (node, "next_hop", ip4);
19188         }
19189       else if (fp->afi == IP46_TYPE_IP6)
19190         {
19191           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19192           vat_json_object_add_ip6 (node, "next_hop", ip6);
19193         }
19194     }
19195 }
19196
19197 static int
19198 api_ip_fib_dump (vat_main_t * vam)
19199 {
19200   vl_api_ip_fib_dump_t *mp;
19201   vl_api_control_ping_t *mp_ping;
19202   int ret;
19203
19204   M (IP_FIB_DUMP, mp);
19205   S (mp);
19206
19207   /* Use a control ping for synchronization */
19208   MPING (CONTROL_PING, mp_ping);
19209   S (mp_ping);
19210
19211   W (ret);
19212   return ret;
19213 }
19214
19215 static int
19216 api_ip_mfib_dump (vat_main_t * vam)
19217 {
19218   vl_api_ip_mfib_dump_t *mp;
19219   vl_api_control_ping_t *mp_ping;
19220   int ret;
19221
19222   M (IP_MFIB_DUMP, mp);
19223   S (mp);
19224
19225   /* Use a control ping for synchronization */
19226   MPING (CONTROL_PING, mp_ping);
19227   S (mp_ping);
19228
19229   W (ret);
19230   return ret;
19231 }
19232
19233 static void vl_api_ip_neighbor_details_t_handler
19234   (vl_api_ip_neighbor_details_t * mp)
19235 {
19236   vat_main_t *vam = &vat_main;
19237
19238   print (vam->ofp, "%c %U %U",
19239          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19240          format_vl_api_mac_address, &mp->neighbor.mac_address,
19241          format_vl_api_address, &mp->neighbor.ip_address);
19242 }
19243
19244 static void vl_api_ip_neighbor_details_t_handler_json
19245   (vl_api_ip_neighbor_details_t * mp)
19246 {
19247
19248   vat_main_t *vam = &vat_main;
19249   vat_json_node_t *node;
19250
19251   if (VAT_JSON_ARRAY != vam->json_tree.type)
19252     {
19253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19254       vat_json_init_array (&vam->json_tree);
19255     }
19256   node = vat_json_array_add (&vam->json_tree);
19257
19258   vat_json_init_object (node);
19259   vat_json_object_add_string_copy
19260     (node, "flag",
19261      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19262       (u8 *) "static" : (u8 *) "dynamic"));
19263
19264   vat_json_object_add_string_copy (node, "link_layer",
19265                                    format (0, "%U", format_vl_api_mac_address,
19266                                            &mp->neighbor.mac_address));
19267   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19268 }
19269
19270 static int
19271 api_ip_neighbor_dump (vat_main_t * vam)
19272 {
19273   unformat_input_t *i = vam->input;
19274   vl_api_ip_neighbor_dump_t *mp;
19275   vl_api_control_ping_t *mp_ping;
19276   u8 is_ipv6 = 0;
19277   u32 sw_if_index = ~0;
19278   int ret;
19279
19280   /* Parse args required to build the message */
19281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19282     {
19283       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19284         ;
19285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19286         ;
19287       else if (unformat (i, "ip6"))
19288         is_ipv6 = 1;
19289       else
19290         break;
19291     }
19292
19293   if (sw_if_index == ~0)
19294     {
19295       errmsg ("missing interface name or sw_if_index");
19296       return -99;
19297     }
19298
19299   M (IP_NEIGHBOR_DUMP, mp);
19300   mp->is_ipv6 = (u8) is_ipv6;
19301   mp->sw_if_index = ntohl (sw_if_index);
19302   S (mp);
19303
19304   /* Use a control ping for synchronization */
19305   MPING (CONTROL_PING, mp_ping);
19306   S (mp_ping);
19307
19308   W (ret);
19309   return ret;
19310 }
19311
19312 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19313 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19314
19315 static void
19316 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19317 {
19318   vat_main_t *vam = &vat_main;
19319   int count = ntohl (mp->count);
19320   vl_api_fib_path_t *fp;
19321   int i;
19322
19323   print (vam->ofp,
19324          "table-id %d, prefix %U/%d stats-index %d",
19325          ntohl (mp->table_id), format_ip6_address, mp->address,
19326          mp->address_length, ntohl (mp->stats_index));
19327   fp = mp->path;
19328   for (i = 0; i < count; i++)
19329     {
19330       if (fp->afi == IP46_TYPE_IP6)
19331         print (vam->ofp,
19332                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19333                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19334                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19335                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19336                format_ip6_address, fp->next_hop);
19337       else if (fp->afi == IP46_TYPE_IP4)
19338         print (vam->ofp,
19339                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19340                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19341                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19342                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19343                format_ip4_address, fp->next_hop);
19344       fp++;
19345     }
19346 }
19347
19348 static void vl_api_ip6_fib_details_t_handler_json
19349   (vl_api_ip6_fib_details_t * mp)
19350 {
19351   vat_main_t *vam = &vat_main;
19352   int count = ntohl (mp->count);
19353   vat_json_node_t *node = NULL;
19354   struct in_addr ip4;
19355   struct in6_addr ip6;
19356   vl_api_fib_path_t *fp;
19357   int i;
19358
19359   if (VAT_JSON_ARRAY != vam->json_tree.type)
19360     {
19361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19362       vat_json_init_array (&vam->json_tree);
19363     }
19364   node = vat_json_array_add (&vam->json_tree);
19365
19366   vat_json_init_object (node);
19367   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19368   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19369   vat_json_object_add_ip6 (node, "prefix", ip6);
19370   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19371   vat_json_object_add_uint (node, "path_count", count);
19372   fp = mp->path;
19373   for (i = 0; i < count; i++)
19374     {
19375       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19376       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19377       vat_json_object_add_uint (node, "is_local", fp->is_local);
19378       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19379       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19380       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19381       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19382       if (fp->afi == IP46_TYPE_IP4)
19383         {
19384           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19385           vat_json_object_add_ip4 (node, "next_hop", ip4);
19386         }
19387       else if (fp->afi == IP46_TYPE_IP6)
19388         {
19389           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19390           vat_json_object_add_ip6 (node, "next_hop", ip6);
19391         }
19392     }
19393 }
19394
19395 static int
19396 api_ip6_fib_dump (vat_main_t * vam)
19397 {
19398   vl_api_ip6_fib_dump_t *mp;
19399   vl_api_control_ping_t *mp_ping;
19400   int ret;
19401
19402   M (IP6_FIB_DUMP, mp);
19403   S (mp);
19404
19405   /* Use a control ping for synchronization */
19406   MPING (CONTROL_PING, mp_ping);
19407   S (mp_ping);
19408
19409   W (ret);
19410   return ret;
19411 }
19412
19413 static int
19414 api_ip6_mfib_dump (vat_main_t * vam)
19415 {
19416   vl_api_ip6_mfib_dump_t *mp;
19417   vl_api_control_ping_t *mp_ping;
19418   int ret;
19419
19420   M (IP6_MFIB_DUMP, mp);
19421   S (mp);
19422
19423   /* Use a control ping for synchronization */
19424   MPING (CONTROL_PING, mp_ping);
19425   S (mp_ping);
19426
19427   W (ret);
19428   return ret;
19429 }
19430
19431 int
19432 api_classify_table_ids (vat_main_t * vam)
19433 {
19434   vl_api_classify_table_ids_t *mp;
19435   int ret;
19436
19437   /* Construct the API message */
19438   M (CLASSIFY_TABLE_IDS, mp);
19439   mp->context = 0;
19440
19441   S (mp);
19442   W (ret);
19443   return ret;
19444 }
19445
19446 int
19447 api_classify_table_by_interface (vat_main_t * vam)
19448 {
19449   unformat_input_t *input = vam->input;
19450   vl_api_classify_table_by_interface_t *mp;
19451
19452   u32 sw_if_index = ~0;
19453   int ret;
19454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19455     {
19456       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19457         ;
19458       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19459         ;
19460       else
19461         break;
19462     }
19463   if (sw_if_index == ~0)
19464     {
19465       errmsg ("missing interface name or sw_if_index");
19466       return -99;
19467     }
19468
19469   /* Construct the API message */
19470   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19471   mp->context = 0;
19472   mp->sw_if_index = ntohl (sw_if_index);
19473
19474   S (mp);
19475   W (ret);
19476   return ret;
19477 }
19478
19479 int
19480 api_classify_table_info (vat_main_t * vam)
19481 {
19482   unformat_input_t *input = vam->input;
19483   vl_api_classify_table_info_t *mp;
19484
19485   u32 table_id = ~0;
19486   int ret;
19487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19488     {
19489       if (unformat (input, "table_id %d", &table_id))
19490         ;
19491       else
19492         break;
19493     }
19494   if (table_id == ~0)
19495     {
19496       errmsg ("missing table id");
19497       return -99;
19498     }
19499
19500   /* Construct the API message */
19501   M (CLASSIFY_TABLE_INFO, mp);
19502   mp->context = 0;
19503   mp->table_id = ntohl (table_id);
19504
19505   S (mp);
19506   W (ret);
19507   return ret;
19508 }
19509
19510 int
19511 api_classify_session_dump (vat_main_t * vam)
19512 {
19513   unformat_input_t *input = vam->input;
19514   vl_api_classify_session_dump_t *mp;
19515   vl_api_control_ping_t *mp_ping;
19516
19517   u32 table_id = ~0;
19518   int ret;
19519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19520     {
19521       if (unformat (input, "table_id %d", &table_id))
19522         ;
19523       else
19524         break;
19525     }
19526   if (table_id == ~0)
19527     {
19528       errmsg ("missing table id");
19529       return -99;
19530     }
19531
19532   /* Construct the API message */
19533   M (CLASSIFY_SESSION_DUMP, mp);
19534   mp->context = 0;
19535   mp->table_id = ntohl (table_id);
19536   S (mp);
19537
19538   /* Use a control ping for synchronization */
19539   MPING (CONTROL_PING, mp_ping);
19540   S (mp_ping);
19541
19542   W (ret);
19543   return ret;
19544 }
19545
19546 static void
19547 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19548 {
19549   vat_main_t *vam = &vat_main;
19550
19551   print (vam->ofp, "collector_address %U, collector_port %d, "
19552          "src_address %U, vrf_id %d, path_mtu %u, "
19553          "template_interval %u, udp_checksum %d",
19554          format_ip4_address, mp->collector_address,
19555          ntohs (mp->collector_port),
19556          format_ip4_address, mp->src_address,
19557          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19558          ntohl (mp->template_interval), mp->udp_checksum);
19559
19560   vam->retval = 0;
19561   vam->result_ready = 1;
19562 }
19563
19564 static void
19565   vl_api_ipfix_exporter_details_t_handler_json
19566   (vl_api_ipfix_exporter_details_t * mp)
19567 {
19568   vat_main_t *vam = &vat_main;
19569   vat_json_node_t node;
19570   struct in_addr collector_address;
19571   struct in_addr src_address;
19572
19573   vat_json_init_object (&node);
19574   clib_memcpy (&collector_address, &mp->collector_address,
19575                sizeof (collector_address));
19576   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19577   vat_json_object_add_uint (&node, "collector_port",
19578                             ntohs (mp->collector_port));
19579   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19580   vat_json_object_add_ip4 (&node, "src_address", src_address);
19581   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19582   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19583   vat_json_object_add_uint (&node, "template_interval",
19584                             ntohl (mp->template_interval));
19585   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19586
19587   vat_json_print (vam->ofp, &node);
19588   vat_json_free (&node);
19589   vam->retval = 0;
19590   vam->result_ready = 1;
19591 }
19592
19593 int
19594 api_ipfix_exporter_dump (vat_main_t * vam)
19595 {
19596   vl_api_ipfix_exporter_dump_t *mp;
19597   int ret;
19598
19599   /* Construct the API message */
19600   M (IPFIX_EXPORTER_DUMP, mp);
19601   mp->context = 0;
19602
19603   S (mp);
19604   W (ret);
19605   return ret;
19606 }
19607
19608 static int
19609 api_ipfix_classify_stream_dump (vat_main_t * vam)
19610 {
19611   vl_api_ipfix_classify_stream_dump_t *mp;
19612   int ret;
19613
19614   /* Construct the API message */
19615   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19616   mp->context = 0;
19617
19618   S (mp);
19619   W (ret);
19620   return ret;
19621   /* NOTREACHED */
19622   return 0;
19623 }
19624
19625 static void
19626   vl_api_ipfix_classify_stream_details_t_handler
19627   (vl_api_ipfix_classify_stream_details_t * mp)
19628 {
19629   vat_main_t *vam = &vat_main;
19630   print (vam->ofp, "domain_id %d, src_port %d",
19631          ntohl (mp->domain_id), ntohs (mp->src_port));
19632   vam->retval = 0;
19633   vam->result_ready = 1;
19634 }
19635
19636 static void
19637   vl_api_ipfix_classify_stream_details_t_handler_json
19638   (vl_api_ipfix_classify_stream_details_t * mp)
19639 {
19640   vat_main_t *vam = &vat_main;
19641   vat_json_node_t node;
19642
19643   vat_json_init_object (&node);
19644   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19645   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19646
19647   vat_json_print (vam->ofp, &node);
19648   vat_json_free (&node);
19649   vam->retval = 0;
19650   vam->result_ready = 1;
19651 }
19652
19653 static int
19654 api_ipfix_classify_table_dump (vat_main_t * vam)
19655 {
19656   vl_api_ipfix_classify_table_dump_t *mp;
19657   vl_api_control_ping_t *mp_ping;
19658   int ret;
19659
19660   if (!vam->json_output)
19661     {
19662       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19663              "transport_protocol");
19664     }
19665
19666   /* Construct the API message */
19667   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19668
19669   /* send it... */
19670   S (mp);
19671
19672   /* Use a control ping for synchronization */
19673   MPING (CONTROL_PING, mp_ping);
19674   S (mp_ping);
19675
19676   W (ret);
19677   return ret;
19678 }
19679
19680 static void
19681   vl_api_ipfix_classify_table_details_t_handler
19682   (vl_api_ipfix_classify_table_details_t * mp)
19683 {
19684   vat_main_t *vam = &vat_main;
19685   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19686          mp->transport_protocol);
19687 }
19688
19689 static void
19690   vl_api_ipfix_classify_table_details_t_handler_json
19691   (vl_api_ipfix_classify_table_details_t * mp)
19692 {
19693   vat_json_node_t *node = NULL;
19694   vat_main_t *vam = &vat_main;
19695
19696   if (VAT_JSON_ARRAY != vam->json_tree.type)
19697     {
19698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19699       vat_json_init_array (&vam->json_tree);
19700     }
19701
19702   node = vat_json_array_add (&vam->json_tree);
19703   vat_json_init_object (node);
19704
19705   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19706   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19707   vat_json_object_add_uint (node, "transport_protocol",
19708                             mp->transport_protocol);
19709 }
19710
19711 static int
19712 api_sw_interface_span_enable_disable (vat_main_t * vam)
19713 {
19714   unformat_input_t *i = vam->input;
19715   vl_api_sw_interface_span_enable_disable_t *mp;
19716   u32 src_sw_if_index = ~0;
19717   u32 dst_sw_if_index = ~0;
19718   u8 state = 3;
19719   int ret;
19720   u8 is_l2 = 0;
19721
19722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19723     {
19724       if (unformat
19725           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19726         ;
19727       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19728         ;
19729       else
19730         if (unformat
19731             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19732         ;
19733       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19734         ;
19735       else if (unformat (i, "disable"))
19736         state = 0;
19737       else if (unformat (i, "rx"))
19738         state = 1;
19739       else if (unformat (i, "tx"))
19740         state = 2;
19741       else if (unformat (i, "both"))
19742         state = 3;
19743       else if (unformat (i, "l2"))
19744         is_l2 = 1;
19745       else
19746         break;
19747     }
19748
19749   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19750
19751   mp->sw_if_index_from = htonl (src_sw_if_index);
19752   mp->sw_if_index_to = htonl (dst_sw_if_index);
19753   mp->state = state;
19754   mp->is_l2 = is_l2;
19755
19756   S (mp);
19757   W (ret);
19758   return ret;
19759 }
19760
19761 static void
19762 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19763                                             * mp)
19764 {
19765   vat_main_t *vam = &vat_main;
19766   u8 *sw_if_from_name = 0;
19767   u8 *sw_if_to_name = 0;
19768   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19769   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19770   char *states[] = { "none", "rx", "tx", "both" };
19771   hash_pair_t *p;
19772
19773   /* *INDENT-OFF* */
19774   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19775   ({
19776     if ((u32) p->value[0] == sw_if_index_from)
19777       {
19778         sw_if_from_name = (u8 *)(p->key);
19779         if (sw_if_to_name)
19780           break;
19781       }
19782     if ((u32) p->value[0] == sw_if_index_to)
19783       {
19784         sw_if_to_name = (u8 *)(p->key);
19785         if (sw_if_from_name)
19786           break;
19787       }
19788   }));
19789   /* *INDENT-ON* */
19790   print (vam->ofp, "%20s => %20s (%s) %s",
19791          sw_if_from_name, sw_if_to_name, states[mp->state],
19792          mp->is_l2 ? "l2" : "device");
19793 }
19794
19795 static void
19796   vl_api_sw_interface_span_details_t_handler_json
19797   (vl_api_sw_interface_span_details_t * mp)
19798 {
19799   vat_main_t *vam = &vat_main;
19800   vat_json_node_t *node = NULL;
19801   u8 *sw_if_from_name = 0;
19802   u8 *sw_if_to_name = 0;
19803   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19804   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19805   hash_pair_t *p;
19806
19807   /* *INDENT-OFF* */
19808   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19809   ({
19810     if ((u32) p->value[0] == sw_if_index_from)
19811       {
19812         sw_if_from_name = (u8 *)(p->key);
19813         if (sw_if_to_name)
19814           break;
19815       }
19816     if ((u32) p->value[0] == sw_if_index_to)
19817       {
19818         sw_if_to_name = (u8 *)(p->key);
19819         if (sw_if_from_name)
19820           break;
19821       }
19822   }));
19823   /* *INDENT-ON* */
19824
19825   if (VAT_JSON_ARRAY != vam->json_tree.type)
19826     {
19827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19828       vat_json_init_array (&vam->json_tree);
19829     }
19830   node = vat_json_array_add (&vam->json_tree);
19831
19832   vat_json_init_object (node);
19833   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19834   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19835   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19836   if (0 != sw_if_to_name)
19837     {
19838       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19839     }
19840   vat_json_object_add_uint (node, "state", mp->state);
19841   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19842 }
19843
19844 static int
19845 api_sw_interface_span_dump (vat_main_t * vam)
19846 {
19847   unformat_input_t *input = vam->input;
19848   vl_api_sw_interface_span_dump_t *mp;
19849   vl_api_control_ping_t *mp_ping;
19850   u8 is_l2 = 0;
19851   int ret;
19852
19853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19854     {
19855       if (unformat (input, "l2"))
19856         is_l2 = 1;
19857       else
19858         break;
19859     }
19860
19861   M (SW_INTERFACE_SPAN_DUMP, mp);
19862   mp->is_l2 = is_l2;
19863   S (mp);
19864
19865   /* Use a control ping for synchronization */
19866   MPING (CONTROL_PING, mp_ping);
19867   S (mp_ping);
19868
19869   W (ret);
19870   return ret;
19871 }
19872
19873 int
19874 api_pg_create_interface (vat_main_t * vam)
19875 {
19876   unformat_input_t *input = vam->input;
19877   vl_api_pg_create_interface_t *mp;
19878
19879   u32 if_id = ~0;
19880   int ret;
19881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19882     {
19883       if (unformat (input, "if_id %d", &if_id))
19884         ;
19885       else
19886         break;
19887     }
19888   if (if_id == ~0)
19889     {
19890       errmsg ("missing pg interface index");
19891       return -99;
19892     }
19893
19894   /* Construct the API message */
19895   M (PG_CREATE_INTERFACE, mp);
19896   mp->context = 0;
19897   mp->interface_id = ntohl (if_id);
19898
19899   S (mp);
19900   W (ret);
19901   return ret;
19902 }
19903
19904 int
19905 api_pg_capture (vat_main_t * vam)
19906 {
19907   unformat_input_t *input = vam->input;
19908   vl_api_pg_capture_t *mp;
19909
19910   u32 if_id = ~0;
19911   u8 enable = 1;
19912   u32 count = 1;
19913   u8 pcap_file_set = 0;
19914   u8 *pcap_file = 0;
19915   int ret;
19916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19917     {
19918       if (unformat (input, "if_id %d", &if_id))
19919         ;
19920       else if (unformat (input, "pcap %s", &pcap_file))
19921         pcap_file_set = 1;
19922       else if (unformat (input, "count %d", &count))
19923         ;
19924       else if (unformat (input, "disable"))
19925         enable = 0;
19926       else
19927         break;
19928     }
19929   if (if_id == ~0)
19930     {
19931       errmsg ("missing pg interface index");
19932       return -99;
19933     }
19934   if (pcap_file_set > 0)
19935     {
19936       if (vec_len (pcap_file) > 255)
19937         {
19938           errmsg ("pcap file name is too long");
19939           return -99;
19940         }
19941     }
19942
19943   u32 name_len = vec_len (pcap_file);
19944   /* Construct the API message */
19945   M (PG_CAPTURE, mp);
19946   mp->context = 0;
19947   mp->interface_id = ntohl (if_id);
19948   mp->is_enabled = enable;
19949   mp->count = ntohl (count);
19950   mp->pcap_name_length = ntohl (name_len);
19951   if (pcap_file_set != 0)
19952     {
19953       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19954     }
19955   vec_free (pcap_file);
19956
19957   S (mp);
19958   W (ret);
19959   return ret;
19960 }
19961
19962 int
19963 api_pg_enable_disable (vat_main_t * vam)
19964 {
19965   unformat_input_t *input = vam->input;
19966   vl_api_pg_enable_disable_t *mp;
19967
19968   u8 enable = 1;
19969   u8 stream_name_set = 0;
19970   u8 *stream_name = 0;
19971   int ret;
19972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19973     {
19974       if (unformat (input, "stream %s", &stream_name))
19975         stream_name_set = 1;
19976       else if (unformat (input, "disable"))
19977         enable = 0;
19978       else
19979         break;
19980     }
19981
19982   if (stream_name_set > 0)
19983     {
19984       if (vec_len (stream_name) > 255)
19985         {
19986           errmsg ("stream name too long");
19987           return -99;
19988         }
19989     }
19990
19991   u32 name_len = vec_len (stream_name);
19992   /* Construct the API message */
19993   M (PG_ENABLE_DISABLE, mp);
19994   mp->context = 0;
19995   mp->is_enabled = enable;
19996   if (stream_name_set != 0)
19997     {
19998       mp->stream_name_length = ntohl (name_len);
19999       clib_memcpy (mp->stream_name, stream_name, name_len);
20000     }
20001   vec_free (stream_name);
20002
20003   S (mp);
20004   W (ret);
20005   return ret;
20006 }
20007
20008 int
20009 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20010 {
20011   unformat_input_t *input = vam->input;
20012   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20013
20014   u16 *low_ports = 0;
20015   u16 *high_ports = 0;
20016   u16 this_low;
20017   u16 this_hi;
20018   vl_api_prefix_t prefix;
20019   u32 tmp, tmp2;
20020   u8 prefix_set = 0;
20021   u32 vrf_id = ~0;
20022   u8 is_add = 1;
20023   int ret;
20024
20025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20026     {
20027       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20028         prefix_set = 1;
20029       else if (unformat (input, "vrf %d", &vrf_id))
20030         ;
20031       else if (unformat (input, "del"))
20032         is_add = 0;
20033       else if (unformat (input, "port %d", &tmp))
20034         {
20035           if (tmp == 0 || tmp > 65535)
20036             {
20037               errmsg ("port %d out of range", tmp);
20038               return -99;
20039             }
20040           this_low = tmp;
20041           this_hi = this_low + 1;
20042           vec_add1 (low_ports, this_low);
20043           vec_add1 (high_ports, this_hi);
20044         }
20045       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20046         {
20047           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20048             {
20049               errmsg ("incorrect range parameters");
20050               return -99;
20051             }
20052           this_low = tmp;
20053           /* Note: in debug CLI +1 is added to high before
20054              passing to real fn that does "the work"
20055              (ip_source_and_port_range_check_add_del).
20056              This fn is a wrapper around the binary API fn a
20057              control plane will call, which expects this increment
20058              to have occurred. Hence letting the binary API control
20059              plane fn do the increment for consistency between VAT
20060              and other control planes.
20061            */
20062           this_hi = tmp2;
20063           vec_add1 (low_ports, this_low);
20064           vec_add1 (high_ports, this_hi);
20065         }
20066       else
20067         break;
20068     }
20069
20070   if (prefix_set == 0)
20071     {
20072       errmsg ("<address>/<mask> not specified");
20073       return -99;
20074     }
20075
20076   if (vrf_id == ~0)
20077     {
20078       errmsg ("VRF ID required, not specified");
20079       return -99;
20080     }
20081
20082   if (vrf_id == 0)
20083     {
20084       errmsg
20085         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20086       return -99;
20087     }
20088
20089   if (vec_len (low_ports) == 0)
20090     {
20091       errmsg ("At least one port or port range required");
20092       return -99;
20093     }
20094
20095   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20096
20097   mp->is_add = is_add;
20098
20099   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20100
20101   mp->number_of_ranges = vec_len (low_ports);
20102
20103   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20104   vec_free (low_ports);
20105
20106   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20107   vec_free (high_ports);
20108
20109   mp->vrf_id = ntohl (vrf_id);
20110
20111   S (mp);
20112   W (ret);
20113   return ret;
20114 }
20115
20116 int
20117 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20118 {
20119   unformat_input_t *input = vam->input;
20120   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20121   u32 sw_if_index = ~0;
20122   int vrf_set = 0;
20123   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20124   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20125   u8 is_add = 1;
20126   int ret;
20127
20128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20129     {
20130       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20131         ;
20132       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20133         ;
20134       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20135         vrf_set = 1;
20136       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20137         vrf_set = 1;
20138       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20139         vrf_set = 1;
20140       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20141         vrf_set = 1;
20142       else if (unformat (input, "del"))
20143         is_add = 0;
20144       else
20145         break;
20146     }
20147
20148   if (sw_if_index == ~0)
20149     {
20150       errmsg ("Interface required but not specified");
20151       return -99;
20152     }
20153
20154   if (vrf_set == 0)
20155     {
20156       errmsg ("VRF ID required but not specified");
20157       return -99;
20158     }
20159
20160   if (tcp_out_vrf_id == 0
20161       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20162     {
20163       errmsg
20164         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20165       return -99;
20166     }
20167
20168   /* Construct the API message */
20169   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20170
20171   mp->sw_if_index = ntohl (sw_if_index);
20172   mp->is_add = is_add;
20173   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20174   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20175   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20176   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20177
20178   /* send it... */
20179   S (mp);
20180
20181   /* Wait for a reply... */
20182   W (ret);
20183   return ret;
20184 }
20185
20186 static int
20187 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20188 {
20189   unformat_input_t *i = vam->input;
20190   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20191   u32 local_sa_id = 0;
20192   u32 remote_sa_id = 0;
20193   vl_api_ip4_address_t src_address;
20194   vl_api_ip4_address_t dst_address;
20195   u8 is_add = 1;
20196   int ret;
20197
20198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20199     {
20200       if (unformat (i, "local_sa %d", &local_sa_id))
20201         ;
20202       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20203         ;
20204       else
20205         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20206         ;
20207       else
20208         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20209         ;
20210       else if (unformat (i, "del"))
20211         is_add = 0;
20212       else
20213         {
20214           clib_warning ("parse error '%U'", format_unformat_error, i);
20215           return -99;
20216         }
20217     }
20218
20219   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20220
20221   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20222   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20223   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20224   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20225   mp->is_add = is_add;
20226
20227   S (mp);
20228   W (ret);
20229   return ret;
20230 }
20231
20232 static int
20233 api_set_punt (vat_main_t * vam)
20234 {
20235   unformat_input_t *i = vam->input;
20236   vl_api_address_family_t af;
20237   vl_api_set_punt_t *mp;
20238   u32 protocol = ~0;
20239   u32 port = ~0;
20240   int is_add = 1;
20241   int ret;
20242
20243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20244     {
20245       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20246         ;
20247       else if (unformat (i, "protocol %d", &protocol))
20248         ;
20249       else if (unformat (i, "port %d", &port))
20250         ;
20251       else if (unformat (i, "del"))
20252         is_add = 0;
20253       else
20254         {
20255           clib_warning ("parse error '%U'", format_unformat_error, i);
20256           return -99;
20257         }
20258     }
20259
20260   M (SET_PUNT, mp);
20261
20262   mp->is_add = (u8) is_add;
20263   mp->punt.type = PUNT_API_TYPE_L4;
20264   mp->punt.punt.l4.af = af;
20265   mp->punt.punt.l4.protocol = (u8) protocol;
20266   mp->punt.punt.l4.port = htons ((u16) port);
20267
20268   S (mp);
20269   W (ret);
20270   return ret;
20271 }
20272
20273 static void vl_api_ipsec_gre_tunnel_details_t_handler
20274   (vl_api_ipsec_gre_tunnel_details_t * mp)
20275 {
20276   vat_main_t *vam = &vat_main;
20277
20278   print (vam->ofp, "%11d%15U%15U%14d%14d",
20279          ntohl (mp->tunnel.sw_if_index),
20280          format_vl_api_ip4_address, mp->tunnel.src,
20281          format_vl_api_ip4_address, mp->tunnel.dst,
20282          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20283 }
20284
20285 static void
20286 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20287                                 const char *name,
20288                                 const vl_api_ip4_address_t addr)
20289 {
20290   struct in_addr ip4;
20291
20292   clib_memcpy (&ip4, addr, sizeof (ip4));
20293   vat_json_object_add_ip4 (node, name, ip4);
20294 }
20295
20296 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20297   (vl_api_ipsec_gre_tunnel_details_t * mp)
20298 {
20299   vat_main_t *vam = &vat_main;
20300   vat_json_node_t *node = NULL;
20301
20302   if (VAT_JSON_ARRAY != vam->json_tree.type)
20303     {
20304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20305       vat_json_init_array (&vam->json_tree);
20306     }
20307   node = vat_json_array_add (&vam->json_tree);
20308
20309   vat_json_init_object (node);
20310   vat_json_object_add_uint (node, "sw_if_index",
20311                             ntohl (mp->tunnel.sw_if_index));
20312   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20313   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20314   vat_json_object_add_uint (node, "local_sa_id",
20315                             ntohl (mp->tunnel.local_sa_id));
20316   vat_json_object_add_uint (node, "remote_sa_id",
20317                             ntohl (mp->tunnel.remote_sa_id));
20318 }
20319
20320 static int
20321 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20322 {
20323   unformat_input_t *i = vam->input;
20324   vl_api_ipsec_gre_tunnel_dump_t *mp;
20325   vl_api_control_ping_t *mp_ping;
20326   u32 sw_if_index;
20327   u8 sw_if_index_set = 0;
20328   int ret;
20329
20330   /* Parse args required to build the message */
20331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20332     {
20333       if (unformat (i, "sw_if_index %d", &sw_if_index))
20334         sw_if_index_set = 1;
20335       else
20336         break;
20337     }
20338
20339   if (sw_if_index_set == 0)
20340     {
20341       sw_if_index = ~0;
20342     }
20343
20344   if (!vam->json_output)
20345     {
20346       print (vam->ofp, "%11s%15s%15s%14s%14s",
20347              "sw_if_index", "src_address", "dst_address",
20348              "local_sa_id", "remote_sa_id");
20349     }
20350
20351   /* Get list of gre-tunnel interfaces */
20352   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20353
20354   mp->sw_if_index = htonl (sw_if_index);
20355
20356   S (mp);
20357
20358   /* Use a control ping for synchronization */
20359   MPING (CONTROL_PING, mp_ping);
20360   S (mp_ping);
20361
20362   W (ret);
20363   return ret;
20364 }
20365
20366 static int
20367 api_delete_subif (vat_main_t * vam)
20368 {
20369   unformat_input_t *i = vam->input;
20370   vl_api_delete_subif_t *mp;
20371   u32 sw_if_index = ~0;
20372   int ret;
20373
20374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20375     {
20376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20377         ;
20378       if (unformat (i, "sw_if_index %d", &sw_if_index))
20379         ;
20380       else
20381         break;
20382     }
20383
20384   if (sw_if_index == ~0)
20385     {
20386       errmsg ("missing sw_if_index");
20387       return -99;
20388     }
20389
20390   /* Construct the API message */
20391   M (DELETE_SUBIF, mp);
20392   mp->sw_if_index = ntohl (sw_if_index);
20393
20394   S (mp);
20395   W (ret);
20396   return ret;
20397 }
20398
20399 #define foreach_pbb_vtr_op      \
20400 _("disable",  L2_VTR_DISABLED)  \
20401 _("pop",  L2_VTR_POP_2)         \
20402 _("push",  L2_VTR_PUSH_2)
20403
20404 static int
20405 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20406 {
20407   unformat_input_t *i = vam->input;
20408   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20409   u32 sw_if_index = ~0, vtr_op = ~0;
20410   u16 outer_tag = ~0;
20411   u8 dmac[6], smac[6];
20412   u8 dmac_set = 0, smac_set = 0;
20413   u16 vlanid = 0;
20414   u32 sid = ~0;
20415   u32 tmp;
20416   int ret;
20417
20418   /* Shut up coverity */
20419   clib_memset (dmac, 0, sizeof (dmac));
20420   clib_memset (smac, 0, sizeof (smac));
20421
20422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20423     {
20424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20425         ;
20426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20427         ;
20428       else if (unformat (i, "vtr_op %d", &vtr_op))
20429         ;
20430 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20431       foreach_pbb_vtr_op
20432 #undef _
20433         else if (unformat (i, "translate_pbb_stag"))
20434         {
20435           if (unformat (i, "%d", &tmp))
20436             {
20437               vtr_op = L2_VTR_TRANSLATE_2_1;
20438               outer_tag = tmp;
20439             }
20440           else
20441             {
20442               errmsg
20443                 ("translate_pbb_stag operation requires outer tag definition");
20444               return -99;
20445             }
20446         }
20447       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20448         dmac_set++;
20449       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20450         smac_set++;
20451       else if (unformat (i, "sid %d", &sid))
20452         ;
20453       else if (unformat (i, "vlanid %d", &tmp))
20454         vlanid = tmp;
20455       else
20456         {
20457           clib_warning ("parse error '%U'", format_unformat_error, i);
20458           return -99;
20459         }
20460     }
20461
20462   if ((sw_if_index == ~0) || (vtr_op == ~0))
20463     {
20464       errmsg ("missing sw_if_index or vtr operation");
20465       return -99;
20466     }
20467   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20468       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20469     {
20470       errmsg
20471         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20472       return -99;
20473     }
20474
20475   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20476   mp->sw_if_index = ntohl (sw_if_index);
20477   mp->vtr_op = ntohl (vtr_op);
20478   mp->outer_tag = ntohs (outer_tag);
20479   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20480   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20481   mp->b_vlanid = ntohs (vlanid);
20482   mp->i_sid = ntohl (sid);
20483
20484   S (mp);
20485   W (ret);
20486   return ret;
20487 }
20488
20489 static int
20490 api_flow_classify_set_interface (vat_main_t * vam)
20491 {
20492   unformat_input_t *i = vam->input;
20493   vl_api_flow_classify_set_interface_t *mp;
20494   u32 sw_if_index;
20495   int sw_if_index_set;
20496   u32 ip4_table_index = ~0;
20497   u32 ip6_table_index = ~0;
20498   u8 is_add = 1;
20499   int ret;
20500
20501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20502     {
20503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20504         sw_if_index_set = 1;
20505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20506         sw_if_index_set = 1;
20507       else if (unformat (i, "del"))
20508         is_add = 0;
20509       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20510         ;
20511       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20512         ;
20513       else
20514         {
20515           clib_warning ("parse error '%U'", format_unformat_error, i);
20516           return -99;
20517         }
20518     }
20519
20520   if (sw_if_index_set == 0)
20521     {
20522       errmsg ("missing interface name or sw_if_index");
20523       return -99;
20524     }
20525
20526   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20527
20528   mp->sw_if_index = ntohl (sw_if_index);
20529   mp->ip4_table_index = ntohl (ip4_table_index);
20530   mp->ip6_table_index = ntohl (ip6_table_index);
20531   mp->is_add = is_add;
20532
20533   S (mp);
20534   W (ret);
20535   return ret;
20536 }
20537
20538 static int
20539 api_flow_classify_dump (vat_main_t * vam)
20540 {
20541   unformat_input_t *i = vam->input;
20542   vl_api_flow_classify_dump_t *mp;
20543   vl_api_control_ping_t *mp_ping;
20544   u8 type = FLOW_CLASSIFY_N_TABLES;
20545   int ret;
20546
20547   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20548     ;
20549   else
20550     {
20551       errmsg ("classify table type must be specified");
20552       return -99;
20553     }
20554
20555   if (!vam->json_output)
20556     {
20557       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20558     }
20559
20560   M (FLOW_CLASSIFY_DUMP, mp);
20561   mp->type = type;
20562   /* send it... */
20563   S (mp);
20564
20565   /* Use a control ping for synchronization */
20566   MPING (CONTROL_PING, mp_ping);
20567   S (mp_ping);
20568
20569   /* Wait for a reply... */
20570   W (ret);
20571   return ret;
20572 }
20573
20574 static int
20575 api_feature_enable_disable (vat_main_t * vam)
20576 {
20577   unformat_input_t *i = vam->input;
20578   vl_api_feature_enable_disable_t *mp;
20579   u8 *arc_name = 0;
20580   u8 *feature_name = 0;
20581   u32 sw_if_index = ~0;
20582   u8 enable = 1;
20583   int ret;
20584
20585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20586     {
20587       if (unformat (i, "arc_name %s", &arc_name))
20588         ;
20589       else if (unformat (i, "feature_name %s", &feature_name))
20590         ;
20591       else
20592         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20593         ;
20594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20595         ;
20596       else if (unformat (i, "disable"))
20597         enable = 0;
20598       else
20599         break;
20600     }
20601
20602   if (arc_name == 0)
20603     {
20604       errmsg ("missing arc name");
20605       return -99;
20606     }
20607   if (vec_len (arc_name) > 63)
20608     {
20609       errmsg ("arc name too long");
20610     }
20611
20612   if (feature_name == 0)
20613     {
20614       errmsg ("missing feature name");
20615       return -99;
20616     }
20617   if (vec_len (feature_name) > 63)
20618     {
20619       errmsg ("feature name too long");
20620     }
20621
20622   if (sw_if_index == ~0)
20623     {
20624       errmsg ("missing interface name or sw_if_index");
20625       return -99;
20626     }
20627
20628   /* Construct the API message */
20629   M (FEATURE_ENABLE_DISABLE, mp);
20630   mp->sw_if_index = ntohl (sw_if_index);
20631   mp->enable = enable;
20632   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20633   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20634   vec_free (arc_name);
20635   vec_free (feature_name);
20636
20637   S (mp);
20638   W (ret);
20639   return ret;
20640 }
20641
20642 static int
20643 api_sw_interface_tag_add_del (vat_main_t * vam)
20644 {
20645   unformat_input_t *i = vam->input;
20646   vl_api_sw_interface_tag_add_del_t *mp;
20647   u32 sw_if_index = ~0;
20648   u8 *tag = 0;
20649   u8 enable = 1;
20650   int ret;
20651
20652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20653     {
20654       if (unformat (i, "tag %s", &tag))
20655         ;
20656       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20657         ;
20658       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20659         ;
20660       else if (unformat (i, "del"))
20661         enable = 0;
20662       else
20663         break;
20664     }
20665
20666   if (sw_if_index == ~0)
20667     {
20668       errmsg ("missing interface name or sw_if_index");
20669       return -99;
20670     }
20671
20672   if (enable && (tag == 0))
20673     {
20674       errmsg ("no tag specified");
20675       return -99;
20676     }
20677
20678   /* Construct the API message */
20679   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20680   mp->sw_if_index = ntohl (sw_if_index);
20681   mp->is_add = enable;
20682   if (enable)
20683     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20684   vec_free (tag);
20685
20686   S (mp);
20687   W (ret);
20688   return ret;
20689 }
20690
20691 static void vl_api_l2_xconnect_details_t_handler
20692   (vl_api_l2_xconnect_details_t * mp)
20693 {
20694   vat_main_t *vam = &vat_main;
20695
20696   print (vam->ofp, "%15d%15d",
20697          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20698 }
20699
20700 static void vl_api_l2_xconnect_details_t_handler_json
20701   (vl_api_l2_xconnect_details_t * mp)
20702 {
20703   vat_main_t *vam = &vat_main;
20704   vat_json_node_t *node = NULL;
20705
20706   if (VAT_JSON_ARRAY != vam->json_tree.type)
20707     {
20708       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20709       vat_json_init_array (&vam->json_tree);
20710     }
20711   node = vat_json_array_add (&vam->json_tree);
20712
20713   vat_json_init_object (node);
20714   vat_json_object_add_uint (node, "rx_sw_if_index",
20715                             ntohl (mp->rx_sw_if_index));
20716   vat_json_object_add_uint (node, "tx_sw_if_index",
20717                             ntohl (mp->tx_sw_if_index));
20718 }
20719
20720 static int
20721 api_l2_xconnect_dump (vat_main_t * vam)
20722 {
20723   vl_api_l2_xconnect_dump_t *mp;
20724   vl_api_control_ping_t *mp_ping;
20725   int ret;
20726
20727   if (!vam->json_output)
20728     {
20729       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20730     }
20731
20732   M (L2_XCONNECT_DUMP, mp);
20733
20734   S (mp);
20735
20736   /* Use a control ping for synchronization */
20737   MPING (CONTROL_PING, mp_ping);
20738   S (mp_ping);
20739
20740   W (ret);
20741   return ret;
20742 }
20743
20744 static int
20745 api_hw_interface_set_mtu (vat_main_t * vam)
20746 {
20747   unformat_input_t *i = vam->input;
20748   vl_api_hw_interface_set_mtu_t *mp;
20749   u32 sw_if_index = ~0;
20750   u32 mtu = 0;
20751   int ret;
20752
20753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20754     {
20755       if (unformat (i, "mtu %d", &mtu))
20756         ;
20757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20758         ;
20759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20760         ;
20761       else
20762         break;
20763     }
20764
20765   if (sw_if_index == ~0)
20766     {
20767       errmsg ("missing interface name or sw_if_index");
20768       return -99;
20769     }
20770
20771   if (mtu == 0)
20772     {
20773       errmsg ("no mtu specified");
20774       return -99;
20775     }
20776
20777   /* Construct the API message */
20778   M (HW_INTERFACE_SET_MTU, mp);
20779   mp->sw_if_index = ntohl (sw_if_index);
20780   mp->mtu = ntohs ((u16) mtu);
20781
20782   S (mp);
20783   W (ret);
20784   return ret;
20785 }
20786
20787 static int
20788 api_p2p_ethernet_add (vat_main_t * vam)
20789 {
20790   unformat_input_t *i = vam->input;
20791   vl_api_p2p_ethernet_add_t *mp;
20792   u32 parent_if_index = ~0;
20793   u32 sub_id = ~0;
20794   u8 remote_mac[6];
20795   u8 mac_set = 0;
20796   int ret;
20797
20798   clib_memset (remote_mac, 0, sizeof (remote_mac));
20799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20800     {
20801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20802         ;
20803       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20804         ;
20805       else
20806         if (unformat
20807             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20808         mac_set++;
20809       else if (unformat (i, "sub_id %d", &sub_id))
20810         ;
20811       else
20812         {
20813           clib_warning ("parse error '%U'", format_unformat_error, i);
20814           return -99;
20815         }
20816     }
20817
20818   if (parent_if_index == ~0)
20819     {
20820       errmsg ("missing interface name or sw_if_index");
20821       return -99;
20822     }
20823   if (mac_set == 0)
20824     {
20825       errmsg ("missing remote mac address");
20826       return -99;
20827     }
20828   if (sub_id == ~0)
20829     {
20830       errmsg ("missing sub-interface id");
20831       return -99;
20832     }
20833
20834   M (P2P_ETHERNET_ADD, mp);
20835   mp->parent_if_index = ntohl (parent_if_index);
20836   mp->subif_id = ntohl (sub_id);
20837   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20838
20839   S (mp);
20840   W (ret);
20841   return ret;
20842 }
20843
20844 static int
20845 api_p2p_ethernet_del (vat_main_t * vam)
20846 {
20847   unformat_input_t *i = vam->input;
20848   vl_api_p2p_ethernet_del_t *mp;
20849   u32 parent_if_index = ~0;
20850   u8 remote_mac[6];
20851   u8 mac_set = 0;
20852   int ret;
20853
20854   clib_memset (remote_mac, 0, sizeof (remote_mac));
20855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20856     {
20857       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20858         ;
20859       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20860         ;
20861       else
20862         if (unformat
20863             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20864         mac_set++;
20865       else
20866         {
20867           clib_warning ("parse error '%U'", format_unformat_error, i);
20868           return -99;
20869         }
20870     }
20871
20872   if (parent_if_index == ~0)
20873     {
20874       errmsg ("missing interface name or sw_if_index");
20875       return -99;
20876     }
20877   if (mac_set == 0)
20878     {
20879       errmsg ("missing remote mac address");
20880       return -99;
20881     }
20882
20883   M (P2P_ETHERNET_DEL, mp);
20884   mp->parent_if_index = ntohl (parent_if_index);
20885   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20886
20887   S (mp);
20888   W (ret);
20889   return ret;
20890 }
20891
20892 static int
20893 api_lldp_config (vat_main_t * vam)
20894 {
20895   unformat_input_t *i = vam->input;
20896   vl_api_lldp_config_t *mp;
20897   int tx_hold = 0;
20898   int tx_interval = 0;
20899   u8 *sys_name = NULL;
20900   int ret;
20901
20902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20903     {
20904       if (unformat (i, "system-name %s", &sys_name))
20905         ;
20906       else if (unformat (i, "tx-hold %d", &tx_hold))
20907         ;
20908       else if (unformat (i, "tx-interval %d", &tx_interval))
20909         ;
20910       else
20911         {
20912           clib_warning ("parse error '%U'", format_unformat_error, i);
20913           return -99;
20914         }
20915     }
20916
20917   vec_add1 (sys_name, 0);
20918
20919   M (LLDP_CONFIG, mp);
20920   mp->tx_hold = htonl (tx_hold);
20921   mp->tx_interval = htonl (tx_interval);
20922   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20923   vec_free (sys_name);
20924
20925   S (mp);
20926   W (ret);
20927   return ret;
20928 }
20929
20930 static int
20931 api_sw_interface_set_lldp (vat_main_t * vam)
20932 {
20933   unformat_input_t *i = vam->input;
20934   vl_api_sw_interface_set_lldp_t *mp;
20935   u32 sw_if_index = ~0;
20936   u32 enable = 1;
20937   u8 *port_desc = NULL, *mgmt_oid = NULL;
20938   ip4_address_t ip4_addr;
20939   ip6_address_t ip6_addr;
20940   int ret;
20941
20942   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20943   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20944
20945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20946     {
20947       if (unformat (i, "disable"))
20948         enable = 0;
20949       else
20950         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20951         ;
20952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20953         ;
20954       else if (unformat (i, "port-desc %s", &port_desc))
20955         ;
20956       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20957         ;
20958       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20959         ;
20960       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20961         ;
20962       else
20963         break;
20964     }
20965
20966   if (sw_if_index == ~0)
20967     {
20968       errmsg ("missing interface name or sw_if_index");
20969       return -99;
20970     }
20971
20972   /* Construct the API message */
20973   vec_add1 (port_desc, 0);
20974   vec_add1 (mgmt_oid, 0);
20975   M (SW_INTERFACE_SET_LLDP, mp);
20976   mp->sw_if_index = ntohl (sw_if_index);
20977   mp->enable = enable;
20978   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20979   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20980   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20981   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20982   vec_free (port_desc);
20983   vec_free (mgmt_oid);
20984
20985   S (mp);
20986   W (ret);
20987   return ret;
20988 }
20989
20990 static int
20991 api_tcp_configure_src_addresses (vat_main_t * vam)
20992 {
20993   vl_api_tcp_configure_src_addresses_t *mp;
20994   unformat_input_t *i = vam->input;
20995   ip4_address_t v4first, v4last;
20996   ip6_address_t v6first, v6last;
20997   u8 range_set = 0;
20998   u32 vrf_id = 0;
20999   int ret;
21000
21001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21002     {
21003       if (unformat (i, "%U - %U",
21004                     unformat_ip4_address, &v4first,
21005                     unformat_ip4_address, &v4last))
21006         {
21007           if (range_set)
21008             {
21009               errmsg ("one range per message (range already set)");
21010               return -99;
21011             }
21012           range_set = 1;
21013         }
21014       else if (unformat (i, "%U - %U",
21015                          unformat_ip6_address, &v6first,
21016                          unformat_ip6_address, &v6last))
21017         {
21018           if (range_set)
21019             {
21020               errmsg ("one range per message (range already set)");
21021               return -99;
21022             }
21023           range_set = 2;
21024         }
21025       else if (unformat (i, "vrf %d", &vrf_id))
21026         ;
21027       else
21028         break;
21029     }
21030
21031   if (range_set == 0)
21032     {
21033       errmsg ("address range not set");
21034       return -99;
21035     }
21036
21037   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21038   mp->vrf_id = ntohl (vrf_id);
21039   /* ipv6? */
21040   if (range_set == 2)
21041     {
21042       mp->is_ipv6 = 1;
21043       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21044       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21045     }
21046   else
21047     {
21048       mp->is_ipv6 = 0;
21049       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21050       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21051     }
21052   S (mp);
21053   W (ret);
21054   return ret;
21055 }
21056
21057 static void vl_api_app_namespace_add_del_reply_t_handler
21058   (vl_api_app_namespace_add_del_reply_t * mp)
21059 {
21060   vat_main_t *vam = &vat_main;
21061   i32 retval = ntohl (mp->retval);
21062   if (vam->async_mode)
21063     {
21064       vam->async_errors += (retval < 0);
21065     }
21066   else
21067     {
21068       vam->retval = retval;
21069       if (retval == 0)
21070         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21071       vam->result_ready = 1;
21072     }
21073 }
21074
21075 static void vl_api_app_namespace_add_del_reply_t_handler_json
21076   (vl_api_app_namespace_add_del_reply_t * mp)
21077 {
21078   vat_main_t *vam = &vat_main;
21079   vat_json_node_t node;
21080
21081   vat_json_init_object (&node);
21082   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21083   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21084
21085   vat_json_print (vam->ofp, &node);
21086   vat_json_free (&node);
21087
21088   vam->retval = ntohl (mp->retval);
21089   vam->result_ready = 1;
21090 }
21091
21092 static int
21093 api_app_namespace_add_del (vat_main_t * vam)
21094 {
21095   vl_api_app_namespace_add_del_t *mp;
21096   unformat_input_t *i = vam->input;
21097   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21098   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21099   u64 secret;
21100   int ret;
21101
21102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21103     {
21104       if (unformat (i, "id %_%v%_", &ns_id))
21105         ;
21106       else if (unformat (i, "secret %lu", &secret))
21107         secret_set = 1;
21108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21109         sw_if_index_set = 1;
21110       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21111         ;
21112       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21113         ;
21114       else
21115         break;
21116     }
21117   if (!ns_id || !secret_set || !sw_if_index_set)
21118     {
21119       errmsg ("namespace id, secret and sw_if_index must be set");
21120       return -99;
21121     }
21122   if (vec_len (ns_id) > 64)
21123     {
21124       errmsg ("namespace id too long");
21125       return -99;
21126     }
21127   M (APP_NAMESPACE_ADD_DEL, mp);
21128
21129   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21130   mp->namespace_id_len = vec_len (ns_id);
21131   mp->secret = clib_host_to_net_u64 (secret);
21132   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21133   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21134   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21135   vec_free (ns_id);
21136   S (mp);
21137   W (ret);
21138   return ret;
21139 }
21140
21141 static int
21142 api_sock_init_shm (vat_main_t * vam)
21143 {
21144 #if VPP_API_TEST_BUILTIN == 0
21145   unformat_input_t *i = vam->input;
21146   vl_api_shm_elem_config_t *config = 0;
21147   u64 size = 64 << 20;
21148   int rv;
21149
21150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21151     {
21152       if (unformat (i, "size %U", unformat_memory_size, &size))
21153         ;
21154       else
21155         break;
21156     }
21157
21158   /*
21159    * Canned custom ring allocator config.
21160    * Should probably parse all of this
21161    */
21162   vec_validate (config, 6);
21163   config[0].type = VL_API_VLIB_RING;
21164   config[0].size = 256;
21165   config[0].count = 32;
21166
21167   config[1].type = VL_API_VLIB_RING;
21168   config[1].size = 1024;
21169   config[1].count = 16;
21170
21171   config[2].type = VL_API_VLIB_RING;
21172   config[2].size = 4096;
21173   config[2].count = 2;
21174
21175   config[3].type = VL_API_CLIENT_RING;
21176   config[3].size = 256;
21177   config[3].count = 32;
21178
21179   config[4].type = VL_API_CLIENT_RING;
21180   config[4].size = 1024;
21181   config[4].count = 16;
21182
21183   config[5].type = VL_API_CLIENT_RING;
21184   config[5].size = 4096;
21185   config[5].count = 2;
21186
21187   config[6].type = VL_API_QUEUE;
21188   config[6].count = 128;
21189   config[6].size = sizeof (uword);
21190
21191   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21192   if (!rv)
21193     vam->client_index_invalid = 1;
21194   return rv;
21195 #else
21196   return -99;
21197 #endif
21198 }
21199
21200 static int
21201 api_dns_enable_disable (vat_main_t * vam)
21202 {
21203   unformat_input_t *line_input = vam->input;
21204   vl_api_dns_enable_disable_t *mp;
21205   u8 enable_disable = 1;
21206   int ret;
21207
21208   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21209     {
21210       if (unformat (line_input, "disable"))
21211         enable_disable = 0;
21212       if (unformat (line_input, "enable"))
21213         enable_disable = 1;
21214       else
21215         break;
21216     }
21217
21218   /* Construct the API message */
21219   M (DNS_ENABLE_DISABLE, mp);
21220   mp->enable = enable_disable;
21221
21222   /* send it... */
21223   S (mp);
21224   /* Wait for the reply */
21225   W (ret);
21226   return ret;
21227 }
21228
21229 static int
21230 api_dns_resolve_name (vat_main_t * vam)
21231 {
21232   unformat_input_t *line_input = vam->input;
21233   vl_api_dns_resolve_name_t *mp;
21234   u8 *name = 0;
21235   int ret;
21236
21237   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21238     {
21239       if (unformat (line_input, "%s", &name))
21240         ;
21241       else
21242         break;
21243     }
21244
21245   if (vec_len (name) > 127)
21246     {
21247       errmsg ("name too long");
21248       return -99;
21249     }
21250
21251   /* Construct the API message */
21252   M (DNS_RESOLVE_NAME, mp);
21253   memcpy (mp->name, name, vec_len (name));
21254   vec_free (name);
21255
21256   /* send it... */
21257   S (mp);
21258   /* Wait for the reply */
21259   W (ret);
21260   return ret;
21261 }
21262
21263 static int
21264 api_dns_resolve_ip (vat_main_t * vam)
21265 {
21266   unformat_input_t *line_input = vam->input;
21267   vl_api_dns_resolve_ip_t *mp;
21268   int is_ip6 = -1;
21269   ip4_address_t addr4;
21270   ip6_address_t addr6;
21271   int ret;
21272
21273   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21274     {
21275       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21276         is_ip6 = 1;
21277       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21278         is_ip6 = 0;
21279       else
21280         break;
21281     }
21282
21283   if (is_ip6 == -1)
21284     {
21285       errmsg ("missing address");
21286       return -99;
21287     }
21288
21289   /* Construct the API message */
21290   M (DNS_RESOLVE_IP, mp);
21291   mp->is_ip6 = is_ip6;
21292   if (is_ip6)
21293     memcpy (mp->address, &addr6, sizeof (addr6));
21294   else
21295     memcpy (mp->address, &addr4, sizeof (addr4));
21296
21297   /* send it... */
21298   S (mp);
21299   /* Wait for the reply */
21300   W (ret);
21301   return ret;
21302 }
21303
21304 static int
21305 api_dns_name_server_add_del (vat_main_t * vam)
21306 {
21307   unformat_input_t *i = vam->input;
21308   vl_api_dns_name_server_add_del_t *mp;
21309   u8 is_add = 1;
21310   ip6_address_t ip6_server;
21311   ip4_address_t ip4_server;
21312   int ip6_set = 0;
21313   int ip4_set = 0;
21314   int ret = 0;
21315
21316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21317     {
21318       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21319         ip6_set = 1;
21320       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21321         ip4_set = 1;
21322       else if (unformat (i, "del"))
21323         is_add = 0;
21324       else
21325         {
21326           clib_warning ("parse error '%U'", format_unformat_error, i);
21327           return -99;
21328         }
21329     }
21330
21331   if (ip4_set && ip6_set)
21332     {
21333       errmsg ("Only one server address allowed per message");
21334       return -99;
21335     }
21336   if ((ip4_set + ip6_set) == 0)
21337     {
21338       errmsg ("Server address required");
21339       return -99;
21340     }
21341
21342   /* Construct the API message */
21343   M (DNS_NAME_SERVER_ADD_DEL, mp);
21344
21345   if (ip6_set)
21346     {
21347       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21348       mp->is_ip6 = 1;
21349     }
21350   else
21351     {
21352       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21353       mp->is_ip6 = 0;
21354     }
21355
21356   mp->is_add = is_add;
21357
21358   /* send it... */
21359   S (mp);
21360
21361   /* Wait for a reply, return good/bad news  */
21362   W (ret);
21363   return ret;
21364 }
21365
21366 static void
21367 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21368 {
21369   vat_main_t *vam = &vat_main;
21370
21371   if (mp->is_ip4)
21372     {
21373       print (vam->ofp,
21374              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21375              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21376              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21377              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21378              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21379              clib_net_to_host_u32 (mp->action_index), mp->tag);
21380     }
21381   else
21382     {
21383       print (vam->ofp,
21384              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21385              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21386              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21387              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21388              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21389              clib_net_to_host_u32 (mp->action_index), mp->tag);
21390     }
21391 }
21392
21393 static void
21394 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21395                                              mp)
21396 {
21397   vat_main_t *vam = &vat_main;
21398   vat_json_node_t *node = NULL;
21399   struct in6_addr ip6;
21400   struct in_addr ip4;
21401
21402   if (VAT_JSON_ARRAY != vam->json_tree.type)
21403     {
21404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21405       vat_json_init_array (&vam->json_tree);
21406     }
21407   node = vat_json_array_add (&vam->json_tree);
21408   vat_json_init_object (node);
21409
21410   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21411   vat_json_object_add_uint (node, "appns_index",
21412                             clib_net_to_host_u32 (mp->appns_index));
21413   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21414   vat_json_object_add_uint (node, "scope", mp->scope);
21415   vat_json_object_add_uint (node, "action_index",
21416                             clib_net_to_host_u32 (mp->action_index));
21417   vat_json_object_add_uint (node, "lcl_port",
21418                             clib_net_to_host_u16 (mp->lcl_port));
21419   vat_json_object_add_uint (node, "rmt_port",
21420                             clib_net_to_host_u16 (mp->rmt_port));
21421   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21422   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21423   vat_json_object_add_string_copy (node, "tag", mp->tag);
21424   if (mp->is_ip4)
21425     {
21426       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21427       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21428       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21429       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21430     }
21431   else
21432     {
21433       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21434       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21435       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21436       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21437     }
21438 }
21439
21440 static int
21441 api_session_rule_add_del (vat_main_t * vam)
21442 {
21443   vl_api_session_rule_add_del_t *mp;
21444   unformat_input_t *i = vam->input;
21445   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21446   u32 appns_index = 0, scope = 0;
21447   ip4_address_t lcl_ip4, rmt_ip4;
21448   ip6_address_t lcl_ip6, rmt_ip6;
21449   u8 is_ip4 = 1, conn_set = 0;
21450   u8 is_add = 1, *tag = 0;
21451   int ret;
21452
21453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21454     {
21455       if (unformat (i, "del"))
21456         is_add = 0;
21457       else if (unformat (i, "add"))
21458         ;
21459       else if (unformat (i, "proto tcp"))
21460         proto = 0;
21461       else if (unformat (i, "proto udp"))
21462         proto = 1;
21463       else if (unformat (i, "appns %d", &appns_index))
21464         ;
21465       else if (unformat (i, "scope %d", &scope))
21466         ;
21467       else if (unformat (i, "tag %_%v%_", &tag))
21468         ;
21469       else
21470         if (unformat
21471             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21472              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21473              &rmt_port))
21474         {
21475           is_ip4 = 1;
21476           conn_set = 1;
21477         }
21478       else
21479         if (unformat
21480             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21481              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21482              &rmt_port))
21483         {
21484           is_ip4 = 0;
21485           conn_set = 1;
21486         }
21487       else if (unformat (i, "action %d", &action))
21488         ;
21489       else
21490         break;
21491     }
21492   if (proto == ~0 || !conn_set || action == ~0)
21493     {
21494       errmsg ("transport proto, connection and action must be set");
21495       return -99;
21496     }
21497
21498   if (scope > 3)
21499     {
21500       errmsg ("scope should be 0-3");
21501       return -99;
21502     }
21503
21504   M (SESSION_RULE_ADD_DEL, mp);
21505
21506   mp->is_ip4 = is_ip4;
21507   mp->transport_proto = proto;
21508   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21509   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21510   mp->lcl_plen = lcl_plen;
21511   mp->rmt_plen = rmt_plen;
21512   mp->action_index = clib_host_to_net_u32 (action);
21513   mp->appns_index = clib_host_to_net_u32 (appns_index);
21514   mp->scope = scope;
21515   mp->is_add = is_add;
21516   if (is_ip4)
21517     {
21518       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21519       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21520     }
21521   else
21522     {
21523       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21524       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21525     }
21526   if (tag)
21527     {
21528       clib_memcpy (mp->tag, tag, vec_len (tag));
21529       vec_free (tag);
21530     }
21531
21532   S (mp);
21533   W (ret);
21534   return ret;
21535 }
21536
21537 static int
21538 api_session_rules_dump (vat_main_t * vam)
21539 {
21540   vl_api_session_rules_dump_t *mp;
21541   vl_api_control_ping_t *mp_ping;
21542   int ret;
21543
21544   if (!vam->json_output)
21545     {
21546       print (vam->ofp, "%=20s", "Session Rules");
21547     }
21548
21549   M (SESSION_RULES_DUMP, mp);
21550   /* send it... */
21551   S (mp);
21552
21553   /* Use a control ping for synchronization */
21554   MPING (CONTROL_PING, mp_ping);
21555   S (mp_ping);
21556
21557   /* Wait for a reply... */
21558   W (ret);
21559   return ret;
21560 }
21561
21562 static int
21563 api_ip_container_proxy_add_del (vat_main_t * vam)
21564 {
21565   vl_api_ip_container_proxy_add_del_t *mp;
21566   unformat_input_t *i = vam->input;
21567   u32 sw_if_index = ~0;
21568   vl_api_prefix_t pfx = { };
21569   u8 is_add = 1;
21570   int ret;
21571
21572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21573     {
21574       if (unformat (i, "del"))
21575         is_add = 0;
21576       else if (unformat (i, "add"))
21577         ;
21578       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21579         ;
21580       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21581         ;
21582       else
21583         break;
21584     }
21585   if (sw_if_index == ~0 || pfx.address_length == 0)
21586     {
21587       errmsg ("address and sw_if_index must be set");
21588       return -99;
21589     }
21590
21591   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21592
21593   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21594   mp->is_add = is_add;
21595   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21596
21597   S (mp);
21598   W (ret);
21599   return ret;
21600 }
21601
21602 static int
21603 api_qos_record_enable_disable (vat_main_t * vam)
21604 {
21605   unformat_input_t *i = vam->input;
21606   vl_api_qos_record_enable_disable_t *mp;
21607   u32 sw_if_index, qs = 0xff;
21608   u8 sw_if_index_set = 0;
21609   u8 enable = 1;
21610   int ret;
21611
21612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21613     {
21614       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21615         sw_if_index_set = 1;
21616       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21617         sw_if_index_set = 1;
21618       else if (unformat (i, "%U", unformat_qos_source, &qs))
21619         ;
21620       else if (unformat (i, "disable"))
21621         enable = 0;
21622       else
21623         {
21624           clib_warning ("parse error '%U'", format_unformat_error, i);
21625           return -99;
21626         }
21627     }
21628
21629   if (sw_if_index_set == 0)
21630     {
21631       errmsg ("missing interface name or sw_if_index");
21632       return -99;
21633     }
21634   if (qs == 0xff)
21635     {
21636       errmsg ("input location must be specified");
21637       return -99;
21638     }
21639
21640   M (QOS_RECORD_ENABLE_DISABLE, mp);
21641
21642   mp->sw_if_index = ntohl (sw_if_index);
21643   mp->input_source = qs;
21644   mp->enable = enable;
21645
21646   S (mp);
21647   W (ret);
21648   return ret;
21649 }
21650
21651
21652 static int
21653 q_or_quit (vat_main_t * vam)
21654 {
21655 #if VPP_API_TEST_BUILTIN == 0
21656   longjmp (vam->jump_buf, 1);
21657 #endif
21658   return 0;                     /* not so much */
21659 }
21660
21661 static int
21662 q (vat_main_t * vam)
21663 {
21664   return q_or_quit (vam);
21665 }
21666
21667 static int
21668 quit (vat_main_t * vam)
21669 {
21670   return q_or_quit (vam);
21671 }
21672
21673 static int
21674 comment (vat_main_t * vam)
21675 {
21676   return 0;
21677 }
21678
21679 static int
21680 statseg (vat_main_t * vam)
21681 {
21682   ssvm_private_t *ssvmp = &vam->stat_segment;
21683   ssvm_shared_header_t *shared_header = ssvmp->sh;
21684   vlib_counter_t **counters;
21685   u64 thread0_index1_packets;
21686   u64 thread0_index1_bytes;
21687   f64 vector_rate, input_rate;
21688   uword *p;
21689
21690   uword *counter_vector_by_name;
21691   if (vam->stat_segment_lockp == 0)
21692     {
21693       errmsg ("Stat segment not mapped...");
21694       return -99;
21695     }
21696
21697   /* look up "/if/rx for sw_if_index 1 as a test */
21698
21699   clib_spinlock_lock (vam->stat_segment_lockp);
21700
21701   counter_vector_by_name = (uword *) shared_header->opaque[1];
21702
21703   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21704   if (p == 0)
21705     {
21706       clib_spinlock_unlock (vam->stat_segment_lockp);
21707       errmsg ("/if/tx not found?");
21708       return -99;
21709     }
21710
21711   /* Fish per-thread vector of combined counters from shared memory */
21712   counters = (vlib_counter_t **) p[0];
21713
21714   if (vec_len (counters[0]) < 2)
21715     {
21716       clib_spinlock_unlock (vam->stat_segment_lockp);
21717       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21718       return -99;
21719     }
21720
21721   /* Read thread 0 sw_if_index 1 counter */
21722   thread0_index1_packets = counters[0][1].packets;
21723   thread0_index1_bytes = counters[0][1].bytes;
21724
21725   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21726   if (p == 0)
21727     {
21728       clib_spinlock_unlock (vam->stat_segment_lockp);
21729       errmsg ("vector_rate not found?");
21730       return -99;
21731     }
21732
21733   vector_rate = *(f64 *) (p[0]);
21734   p = hash_get_mem (counter_vector_by_name, "input_rate");
21735   if (p == 0)
21736     {
21737       clib_spinlock_unlock (vam->stat_segment_lockp);
21738       errmsg ("input_rate not found?");
21739       return -99;
21740     }
21741   input_rate = *(f64 *) (p[0]);
21742
21743   clib_spinlock_unlock (vam->stat_segment_lockp);
21744
21745   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21746          vector_rate, input_rate);
21747   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21748          thread0_index1_packets, thread0_index1_bytes);
21749
21750   return 0;
21751 }
21752
21753 static int
21754 cmd_cmp (void *a1, void *a2)
21755 {
21756   u8 **c1 = a1;
21757   u8 **c2 = a2;
21758
21759   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21760 }
21761
21762 static int
21763 help (vat_main_t * vam)
21764 {
21765   u8 **cmds = 0;
21766   u8 *name = 0;
21767   hash_pair_t *p;
21768   unformat_input_t *i = vam->input;
21769   int j;
21770
21771   if (unformat (i, "%s", &name))
21772     {
21773       uword *hs;
21774
21775       vec_add1 (name, 0);
21776
21777       hs = hash_get_mem (vam->help_by_name, name);
21778       if (hs)
21779         print (vam->ofp, "usage: %s %s", name, hs[0]);
21780       else
21781         print (vam->ofp, "No such msg / command '%s'", name);
21782       vec_free (name);
21783       return 0;
21784     }
21785
21786   print (vam->ofp, "Help is available for the following:");
21787
21788     /* *INDENT-OFF* */
21789     hash_foreach_pair (p, vam->function_by_name,
21790     ({
21791       vec_add1 (cmds, (u8 *)(p->key));
21792     }));
21793     /* *INDENT-ON* */
21794
21795   vec_sort_with_function (cmds, cmd_cmp);
21796
21797   for (j = 0; j < vec_len (cmds); j++)
21798     print (vam->ofp, "%s", cmds[j]);
21799
21800   vec_free (cmds);
21801   return 0;
21802 }
21803
21804 static int
21805 set (vat_main_t * vam)
21806 {
21807   u8 *name = 0, *value = 0;
21808   unformat_input_t *i = vam->input;
21809
21810   if (unformat (i, "%s", &name))
21811     {
21812       /* The input buffer is a vector, not a string. */
21813       value = vec_dup (i->buffer);
21814       vec_delete (value, i->index, 0);
21815       /* Almost certainly has a trailing newline */
21816       if (value[vec_len (value) - 1] == '\n')
21817         value[vec_len (value) - 1] = 0;
21818       /* Make sure it's a proper string, one way or the other */
21819       vec_add1 (value, 0);
21820       (void) clib_macro_set_value (&vam->macro_main,
21821                                    (char *) name, (char *) value);
21822     }
21823   else
21824     errmsg ("usage: set <name> <value>");
21825
21826   vec_free (name);
21827   vec_free (value);
21828   return 0;
21829 }
21830
21831 static int
21832 unset (vat_main_t * vam)
21833 {
21834   u8 *name = 0;
21835
21836   if (unformat (vam->input, "%s", &name))
21837     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21838       errmsg ("unset: %s wasn't set", name);
21839   vec_free (name);
21840   return 0;
21841 }
21842
21843 typedef struct
21844 {
21845   u8 *name;
21846   u8 *value;
21847 } macro_sort_t;
21848
21849
21850 static int
21851 macro_sort_cmp (void *a1, void *a2)
21852 {
21853   macro_sort_t *s1 = a1;
21854   macro_sort_t *s2 = a2;
21855
21856   return strcmp ((char *) (s1->name), (char *) (s2->name));
21857 }
21858
21859 static int
21860 dump_macro_table (vat_main_t * vam)
21861 {
21862   macro_sort_t *sort_me = 0, *sm;
21863   int i;
21864   hash_pair_t *p;
21865
21866     /* *INDENT-OFF* */
21867     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21868     ({
21869       vec_add2 (sort_me, sm, 1);
21870       sm->name = (u8 *)(p->key);
21871       sm->value = (u8 *) (p->value[0]);
21872     }));
21873     /* *INDENT-ON* */
21874
21875   vec_sort_with_function (sort_me, macro_sort_cmp);
21876
21877   if (vec_len (sort_me))
21878     print (vam->ofp, "%-15s%s", "Name", "Value");
21879   else
21880     print (vam->ofp, "The macro table is empty...");
21881
21882   for (i = 0; i < vec_len (sort_me); i++)
21883     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21884   return 0;
21885 }
21886
21887 static int
21888 dump_node_table (vat_main_t * vam)
21889 {
21890   int i, j;
21891   vlib_node_t *node, *next_node;
21892
21893   if (vec_len (vam->graph_nodes) == 0)
21894     {
21895       print (vam->ofp, "Node table empty, issue get_node_graph...");
21896       return 0;
21897     }
21898
21899   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21900     {
21901       node = vam->graph_nodes[0][i];
21902       print (vam->ofp, "[%d] %s", i, node->name);
21903       for (j = 0; j < vec_len (node->next_nodes); j++)
21904         {
21905           if (node->next_nodes[j] != ~0)
21906             {
21907               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21908               print (vam->ofp, "  [%d] %s", j, next_node->name);
21909             }
21910         }
21911     }
21912   return 0;
21913 }
21914
21915 static int
21916 value_sort_cmp (void *a1, void *a2)
21917 {
21918   name_sort_t *n1 = a1;
21919   name_sort_t *n2 = a2;
21920
21921   if (n1->value < n2->value)
21922     return -1;
21923   if (n1->value > n2->value)
21924     return 1;
21925   return 0;
21926 }
21927
21928
21929 static int
21930 dump_msg_api_table (vat_main_t * vam)
21931 {
21932   api_main_t *am = &api_main;
21933   name_sort_t *nses = 0, *ns;
21934   hash_pair_t *hp;
21935   int i;
21936
21937   /* *INDENT-OFF* */
21938   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21939   ({
21940     vec_add2 (nses, ns, 1);
21941     ns->name = (u8 *)(hp->key);
21942     ns->value = (u32) hp->value[0];
21943   }));
21944   /* *INDENT-ON* */
21945
21946   vec_sort_with_function (nses, value_sort_cmp);
21947
21948   for (i = 0; i < vec_len (nses); i++)
21949     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21950   vec_free (nses);
21951   return 0;
21952 }
21953
21954 static int
21955 get_msg_id (vat_main_t * vam)
21956 {
21957   u8 *name_and_crc;
21958   u32 message_index;
21959
21960   if (unformat (vam->input, "%s", &name_and_crc))
21961     {
21962       message_index = vl_msg_api_get_msg_index (name_and_crc);
21963       if (message_index == ~0)
21964         {
21965           print (vam->ofp, " '%s' not found", name_and_crc);
21966           return 0;
21967         }
21968       print (vam->ofp, " '%s' has message index %d",
21969              name_and_crc, message_index);
21970       return 0;
21971     }
21972   errmsg ("name_and_crc required...");
21973   return 0;
21974 }
21975
21976 static int
21977 search_node_table (vat_main_t * vam)
21978 {
21979   unformat_input_t *line_input = vam->input;
21980   u8 *node_to_find;
21981   int j;
21982   vlib_node_t *node, *next_node;
21983   uword *p;
21984
21985   if (vam->graph_node_index_by_name == 0)
21986     {
21987       print (vam->ofp, "Node table empty, issue get_node_graph...");
21988       return 0;
21989     }
21990
21991   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21992     {
21993       if (unformat (line_input, "%s", &node_to_find))
21994         {
21995           vec_add1 (node_to_find, 0);
21996           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21997           if (p == 0)
21998             {
21999               print (vam->ofp, "%s not found...", node_to_find);
22000               goto out;
22001             }
22002           node = vam->graph_nodes[0][p[0]];
22003           print (vam->ofp, "[%d] %s", p[0], node->name);
22004           for (j = 0; j < vec_len (node->next_nodes); j++)
22005             {
22006               if (node->next_nodes[j] != ~0)
22007                 {
22008                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22009                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22010                 }
22011             }
22012         }
22013
22014       else
22015         {
22016           clib_warning ("parse error '%U'", format_unformat_error,
22017                         line_input);
22018           return -99;
22019         }
22020
22021     out:
22022       vec_free (node_to_find);
22023
22024     }
22025
22026   return 0;
22027 }
22028
22029
22030 static int
22031 script (vat_main_t * vam)
22032 {
22033 #if (VPP_API_TEST_BUILTIN==0)
22034   u8 *s = 0;
22035   char *save_current_file;
22036   unformat_input_t save_input;
22037   jmp_buf save_jump_buf;
22038   u32 save_line_number;
22039
22040   FILE *new_fp, *save_ifp;
22041
22042   if (unformat (vam->input, "%s", &s))
22043     {
22044       new_fp = fopen ((char *) s, "r");
22045       if (new_fp == 0)
22046         {
22047           errmsg ("Couldn't open script file %s", s);
22048           vec_free (s);
22049           return -99;
22050         }
22051     }
22052   else
22053     {
22054       errmsg ("Missing script name");
22055       return -99;
22056     }
22057
22058   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22059   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22060   save_ifp = vam->ifp;
22061   save_line_number = vam->input_line_number;
22062   save_current_file = (char *) vam->current_file;
22063
22064   vam->input_line_number = 0;
22065   vam->ifp = new_fp;
22066   vam->current_file = s;
22067   do_one_file (vam);
22068
22069   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22070   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22071   vam->ifp = save_ifp;
22072   vam->input_line_number = save_line_number;
22073   vam->current_file = (u8 *) save_current_file;
22074   vec_free (s);
22075
22076   return 0;
22077 #else
22078   clib_warning ("use the exec command...");
22079   return -99;
22080 #endif
22081 }
22082
22083 static int
22084 echo (vat_main_t * vam)
22085 {
22086   print (vam->ofp, "%v", vam->input->buffer);
22087   return 0;
22088 }
22089
22090 /* List of API message constructors, CLI names map to api_xxx */
22091 #define foreach_vpe_api_msg                                             \
22092 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22093 _(sw_interface_dump,"")                                                 \
22094 _(sw_interface_set_flags,                                               \
22095   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22096 _(sw_interface_add_del_address,                                         \
22097   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22098 _(sw_interface_set_rx_mode,                                             \
22099   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22100 _(sw_interface_set_rx_placement,                                        \
22101   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22102 _(sw_interface_rx_placement_dump,                                       \
22103   "[<intfc> | sw_if_index <id>]")                                         \
22104 _(sw_interface_set_table,                                               \
22105   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22106 _(sw_interface_set_mpls_enable,                                         \
22107   "<intfc> | sw_if_index [disable | dis]")                              \
22108 _(sw_interface_set_vpath,                                               \
22109   "<intfc> | sw_if_index <id> enable | disable")                        \
22110 _(sw_interface_set_vxlan_bypass,                                        \
22111   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22112 _(sw_interface_set_geneve_bypass,                                       \
22113   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22114 _(sw_interface_set_l2_xconnect,                                         \
22115   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22116   "enable | disable")                                                   \
22117 _(sw_interface_set_l2_bridge,                                           \
22118   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22119   "[shg <split-horizon-group>] [bvi]\n"                                 \
22120   "enable | disable")                                                   \
22121 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22122 _(bridge_domain_add_del,                                                \
22123   "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") \
22124 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22125 _(l2fib_add_del,                                                        \
22126   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22127 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22128 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22129 _(l2_flags,                                                             \
22130   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22131 _(bridge_flags,                                                         \
22132   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22133 _(tap_create_v2,                                                        \
22134   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22135 _(tap_delete_v2,                                                        \
22136   "<vpp-if-name> | sw_if_index <id>")                                   \
22137 _(sw_interface_tap_v2_dump, "")                                         \
22138 _(virtio_pci_create,                                                    \
22139   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
22140 _(virtio_pci_delete,                                                    \
22141   "<vpp-if-name> | sw_if_index <id>")                                   \
22142 _(sw_interface_virtio_pci_dump, "")                                     \
22143 _(bond_create,                                                          \
22144   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22145   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22146   "[id <if-id>]")                                                       \
22147 _(bond_delete,                                                          \
22148   "<vpp-if-name> | sw_if_index <id>")                                   \
22149 _(bond_enslave,                                                         \
22150   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22151 _(bond_detach_slave,                                                    \
22152   "sw_if_index <n>")                                                    \
22153 _(sw_interface_bond_dump, "")                                           \
22154 _(sw_interface_slave_dump,                                              \
22155   "<vpp-if-name> | sw_if_index <id>")                                   \
22156 _(ip_table_add_del,                                                     \
22157   "table <n> [ipv6] [add | del]\n")                                     \
22158 _(ip_add_del_route,                                                     \
22159   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22160   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22161   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22162   "[multipath] [count <n>] [del]")                                      \
22163 _(ip_mroute_add_del,                                                    \
22164   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22165   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22166 _(mpls_table_add_del,                                                   \
22167   "table <n> [add | del]\n")                                            \
22168 _(mpls_route_add_del,                                                   \
22169   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22170   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22171   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22172   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22173   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22174   "[count <n>] [del]")                                                  \
22175 _(mpls_ip_bind_unbind,                                                  \
22176   "<label> <addr/len>")                                                 \
22177 _(mpls_tunnel_add_del,                                                  \
22178   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22179   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22180   "[l2-only]  [out-label <n>]")                                         \
22181 _(sr_mpls_policy_add,                                                   \
22182   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22183 _(sr_mpls_policy_del,                                                   \
22184   "bsid <id>")                                                          \
22185 _(bier_table_add_del,                                                   \
22186   "<label> <sub-domain> <set> <bsl> [del]")                             \
22187 _(bier_route_add_del,                                                   \
22188   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22189   "[<intfc> | sw_if_index <id>]"                                        \
22190   "[weight <n>] [del] [multipath]")                                     \
22191 _(proxy_arp_add_del,                                                    \
22192   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22193 _(proxy_arp_intfc_enable_disable,                                       \
22194   "<intfc> | sw_if_index <id> enable | disable")                        \
22195 _(sw_interface_set_unnumbered,                                          \
22196   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22197 _(ip_neighbor_add_del,                                                  \
22198   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22199   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22200 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22201 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22202   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22203   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22204   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22205 _(reset_fib, "vrf <n> [ipv6]")                                          \
22206 _(dhcp_proxy_config,                                                    \
22207   "svr <v46-address> src <v46-address>\n"                               \
22208    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22209 _(dhcp_proxy_set_vss,                                                   \
22210   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22211 _(dhcp_proxy_dump, "ip6")                                               \
22212 _(dhcp_client_config,                                                   \
22213   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22214 _(set_ip_flow_hash,                                                     \
22215   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22216 _(sw_interface_ip6_enable_disable,                                      \
22217   "<intfc> | sw_if_index <id> enable | disable")                        \
22218 _(ip6nd_proxy_add_del,                                                  \
22219   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22220 _(ip6nd_proxy_dump, "")                                                 \
22221 _(sw_interface_ip6nd_ra_prefix,                                         \
22222   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22223   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22224   "[nolink] [isno]")                                                    \
22225 _(sw_interface_ip6nd_ra_config,                                         \
22226   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22227   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22228   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22229 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22230 _(l2_patch_add_del,                                                     \
22231   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22232   "enable | disable")                                                   \
22233 _(sr_localsid_add_del,                                                  \
22234   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22235   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22236 _(classify_add_del_table,                                               \
22237   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22238   " [del] [del-chain] mask <mask-value>\n"                              \
22239   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22240   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22241 _(classify_add_del_session,                                             \
22242   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22243   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22244   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22245   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22246 _(classify_set_interface_ip_table,                                      \
22247   "<intfc> | sw_if_index <nn> table <nn>")                              \
22248 _(classify_set_interface_l2_tables,                                     \
22249   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22250   "  [other-table <nn>]")                                               \
22251 _(get_node_index, "node <node-name")                                    \
22252 _(add_node_next, "node <node-name> next <next-node-name>")              \
22253 _(l2tpv3_create_tunnel,                                                 \
22254   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22255   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22256   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22257 _(l2tpv3_set_tunnel_cookies,                                            \
22258   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22259   "[new_remote_cookie <nn>]\n")                                         \
22260 _(l2tpv3_interface_enable_disable,                                      \
22261   "<intfc> | sw_if_index <nn> enable | disable")                        \
22262 _(l2tpv3_set_lookup_key,                                                \
22263   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22264 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22265 _(vxlan_offload_rx,                                                     \
22266   "hw { <interface name> | hw_if_index <nn>} "                          \
22267   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22268 _(vxlan_add_del_tunnel,                                                 \
22269   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22270   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22271   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22272 _(geneve_add_del_tunnel,                                                \
22273   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22274   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22275   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22276 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22277 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22278 _(gre_tunnel_add_del,                                                   \
22279   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22280   "[teb | erspan <session-id>] [del]")                                  \
22281 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22282 _(l2_fib_clear_table, "")                                               \
22283 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22284 _(l2_interface_vlan_tag_rewrite,                                        \
22285   "<intfc> | sw_if_index <nn> \n"                                       \
22286   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22287   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22288 _(create_vhost_user_if,                                                 \
22289         "socket <filename> [server] [renumber <dev_instance>] "         \
22290         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22291         "[mac <mac_address>]")                                          \
22292 _(modify_vhost_user_if,                                                 \
22293         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22294         "[server] [renumber <dev_instance>]")                           \
22295 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22296 _(sw_interface_vhost_user_dump, "")                                     \
22297 _(show_version, "")                                                     \
22298 _(show_threads, "")                                                     \
22299 _(vxlan_gpe_add_del_tunnel,                                             \
22300   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22301   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22302   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22303   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22304 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22305 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22306 _(interface_name_renumber,                                              \
22307   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22308 _(input_acl_set_interface,                                              \
22309   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22310   "  [l2-table <nn>] [del]")                                            \
22311 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22312 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22313   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22314 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22315 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22316 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22317 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22318 _(ip_dump, "ipv4 | ipv6")                                               \
22319 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22320 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22321   "  spid_id <n> ")                                                     \
22322 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22323   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22324   "  integ_alg <alg> integ_key <hex>")                                  \
22325 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22326   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22327   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22328   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22329 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22330   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22331   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22332   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22333   "  [instance <n>]")     \
22334 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22335 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22336 _(delete_loopback,"sw_if_index <nn>")                                   \
22337 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22338 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22339 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22340 _(want_interface_events,  "enable|disable")                             \
22341 _(get_first_msg_id, "client <name>")                                    \
22342 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22343 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22344   "fib-id <nn> [ip4][ip6][default]")                                    \
22345 _(get_node_graph, " ")                                                  \
22346 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22347 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22348 _(ioam_disable, "")                                                     \
22349 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22350                             " sw_if_index <sw_if_index> p <priority> "  \
22351                             "w <weight>] [del]")                        \
22352 _(one_add_del_locator, "locator-set <locator_name> "                    \
22353                         "iface <intf> | sw_if_index <sw_if_index> "     \
22354                         "p <priority> w <weight> [del]")                \
22355 _(one_add_del_local_eid,"vni <vni> eid "                                \
22356                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22357                          "locator-set <locator_name> [del]"             \
22358                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22359 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22360 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22361 _(one_enable_disable, "enable|disable")                                 \
22362 _(one_map_register_enable_disable, "enable|disable")                    \
22363 _(one_map_register_fallback_threshold, "<value>")                       \
22364 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22365 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22366                                "[seid <seid>] "                         \
22367                                "rloc <locator> p <prio> "               \
22368                                "w <weight> [rloc <loc> ... ] "          \
22369                                "action <action> [del-all]")             \
22370 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22371                           "<local-eid>")                                \
22372 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22373 _(one_use_petr, "ip-address> | disable")                                \
22374 _(one_map_request_mode, "src-dst|dst-only")                             \
22375 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22376 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22377 _(one_locator_set_dump, "[local | remote]")                             \
22378 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22379 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22380                        "[local] | [remote]")                            \
22381 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22382 _(one_ndp_bd_get, "")                                                   \
22383 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22384 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22385 _(one_l2_arp_bd_get, "")                                                \
22386 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22387 _(one_stats_enable_disable, "enable|disable")                           \
22388 _(show_one_stats_enable_disable, "")                                    \
22389 _(one_eid_table_vni_dump, "")                                           \
22390 _(one_eid_table_map_dump, "l2|l3")                                      \
22391 _(one_map_resolver_dump, "")                                            \
22392 _(one_map_server_dump, "")                                              \
22393 _(one_adjacencies_get, "vni <vni>")                                     \
22394 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22395 _(show_one_rloc_probe_state, "")                                        \
22396 _(show_one_map_register_state, "")                                      \
22397 _(show_one_status, "")                                                  \
22398 _(one_stats_dump, "")                                                   \
22399 _(one_stats_flush, "")                                                  \
22400 _(one_get_map_request_itr_rlocs, "")                                    \
22401 _(one_map_register_set_ttl, "<ttl>")                                    \
22402 _(one_set_transport_protocol, "udp|api")                                \
22403 _(one_get_transport_protocol, "")                                       \
22404 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22405 _(one_show_xtr_mode, "")                                                \
22406 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22407 _(one_show_pitr_mode, "")                                               \
22408 _(one_enable_disable_petr_mode, "enable|disable")                       \
22409 _(one_show_petr_mode, "")                                               \
22410 _(show_one_nsh_mapping, "")                                             \
22411 _(show_one_pitr, "")                                                    \
22412 _(show_one_use_petr, "")                                                \
22413 _(show_one_map_request_mode, "")                                        \
22414 _(show_one_map_register_ttl, "")                                        \
22415 _(show_one_map_register_fallback_threshold, "")                         \
22416 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22417                             " sw_if_index <sw_if_index> p <priority> "  \
22418                             "w <weight>] [del]")                        \
22419 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22420                         "iface <intf> | sw_if_index <sw_if_index> "     \
22421                         "p <priority> w <weight> [del]")                \
22422 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22423                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22424                          "locator-set <locator_name> [del]"             \
22425                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22426 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22427 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22428 _(lisp_enable_disable, "enable|disable")                                \
22429 _(lisp_map_register_enable_disable, "enable|disable")                   \
22430 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22431 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22432                                "[seid <seid>] "                         \
22433                                "rloc <locator> p <prio> "               \
22434                                "w <weight> [rloc <loc> ... ] "          \
22435                                "action <action> [del-all]")             \
22436 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22437                           "<local-eid>")                                \
22438 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22439 _(lisp_use_petr, "<ip-address> | disable")                              \
22440 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22441 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22442 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22443 _(lisp_locator_set_dump, "[local | remote]")                            \
22444 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22445 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22446                        "[local] | [remote]")                            \
22447 _(lisp_eid_table_vni_dump, "")                                          \
22448 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22449 _(lisp_map_resolver_dump, "")                                           \
22450 _(lisp_map_server_dump, "")                                             \
22451 _(lisp_adjacencies_get, "vni <vni>")                                    \
22452 _(gpe_fwd_entry_vnis_get, "")                                           \
22453 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22454 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22455                                 "[table <table-id>]")                   \
22456 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22457 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22458 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22459 _(gpe_get_encap_mode, "")                                               \
22460 _(lisp_gpe_add_del_iface, "up|down")                                    \
22461 _(lisp_gpe_enable_disable, "enable|disable")                            \
22462 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22463   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22464 _(show_lisp_rloc_probe_state, "")                                       \
22465 _(show_lisp_map_register_state, "")                                     \
22466 _(show_lisp_status, "")                                                 \
22467 _(lisp_get_map_request_itr_rlocs, "")                                   \
22468 _(show_lisp_pitr, "")                                                   \
22469 _(show_lisp_use_petr, "")                                               \
22470 _(show_lisp_map_request_mode, "")                                       \
22471 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22472 _(af_packet_delete, "name <host interface name>")                       \
22473 _(af_packet_dump, "")                                                   \
22474 _(policer_add_del, "name <policer name> <params> [del]")                \
22475 _(policer_dump, "[name <policer name>]")                                \
22476 _(policer_classify_set_interface,                                       \
22477   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22478   "  [l2-table <nn>] [del]")                                            \
22479 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22480 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22481     "[master|slave]")                                                   \
22482 _(netmap_delete, "name <interface name>")                               \
22483 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22484 _(mpls_fib_dump, "")                                                    \
22485 _(classify_table_ids, "")                                               \
22486 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22487 _(classify_table_info, "table_id <nn>")                                 \
22488 _(classify_session_dump, "table_id <nn>")                               \
22489 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22490     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22491     "[template_interval <nn>] [udp_checksum]")                          \
22492 _(ipfix_exporter_dump, "")                                              \
22493 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22494 _(ipfix_classify_stream_dump, "")                                       \
22495 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22496 _(ipfix_classify_table_dump, "")                                        \
22497 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22498 _(sw_interface_span_dump, "[l2]")                                           \
22499 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22500 _(pg_create_interface, "if_id <nn>")                                    \
22501 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22502 _(pg_enable_disable, "[stream <id>] disable")                           \
22503 _(ip_source_and_port_range_check_add_del,                               \
22504   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22505 _(ip_source_and_port_range_check_interface_add_del,                     \
22506   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22507   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22508 _(ipsec_gre_tunnel_add_del,                                             \
22509   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22510 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22511 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22512 _(l2_interface_pbb_tag_rewrite,                                         \
22513   "<intfc> | sw_if_index <nn> \n"                                       \
22514   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22515   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22516 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22517 _(flow_classify_set_interface,                                          \
22518   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22519 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22520 _(ip_fib_dump, "")                                                      \
22521 _(ip_mfib_dump, "")                                                     \
22522 _(ip6_fib_dump, "")                                                     \
22523 _(ip6_mfib_dump, "")                                                    \
22524 _(feature_enable_disable, "arc_name <arc_name> "                        \
22525   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22526 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22527 "[disable]")                                                            \
22528 _(l2_xconnect_dump, "")                                                 \
22529 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22530 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22531 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22532 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22533 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22534 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22535 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22536   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22537 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22538 _(sock_init_shm, "size <nnn>")                                          \
22539 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22540 _(dns_enable_disable, "[enable][disable]")                              \
22541 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22542 _(dns_resolve_name, "<hostname>")                                       \
22543 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22544 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22545 _(dns_resolve_name, "<hostname>")                                       \
22546 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22547   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22548 _(session_rules_dump, "")                                               \
22549 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22550 _(output_acl_set_interface,                                             \
22551   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22552   "  [l2-table <nn>] [del]")                                            \
22553 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22554
22555 /* List of command functions, CLI names map directly to functions */
22556 #define foreach_cli_function                                    \
22557 _(comment, "usage: comment <ignore-rest-of-line>")              \
22558 _(dump_interface_table, "usage: dump_interface_table")          \
22559 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22560 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22561 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22562 _(dump_macro_table, "usage: dump_macro_table ")                 \
22563 _(dump_node_table, "usage: dump_node_table")                    \
22564 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22565 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22566 _(echo, "usage: echo <message>")                                \
22567 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22568 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22569 _(help, "usage: help")                                          \
22570 _(q, "usage: quit")                                             \
22571 _(quit, "usage: quit")                                          \
22572 _(search_node_table, "usage: search_node_table <name>...")      \
22573 _(set, "usage: set <variable-name> <value>")                    \
22574 _(script, "usage: script <file-name>")                          \
22575 _(statseg, "usage: statseg");                                   \
22576 _(unset, "usage: unset <variable-name>")
22577
22578 #define _(N,n)                                  \
22579     static void vl_api_##n##_t_handler_uni      \
22580     (vl_api_##n##_t * mp)                       \
22581     {                                           \
22582         vat_main_t * vam = &vat_main;           \
22583         if (vam->json_output) {                 \
22584             vl_api_##n##_t_handler_json(mp);    \
22585         } else {                                \
22586             vl_api_##n##_t_handler(mp);         \
22587         }                                       \
22588     }
22589 foreach_vpe_api_reply_msg;
22590 #if VPP_API_TEST_BUILTIN == 0
22591 foreach_standalone_reply_msg;
22592 #endif
22593 #undef _
22594
22595 void
22596 vat_api_hookup (vat_main_t * vam)
22597 {
22598 #define _(N,n)                                                  \
22599     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22600                            vl_api_##n##_t_handler_uni,          \
22601                            vl_noop_handler,                     \
22602                            vl_api_##n##_t_endian,               \
22603                            vl_api_##n##_t_print,                \
22604                            sizeof(vl_api_##n##_t), 1);
22605   foreach_vpe_api_reply_msg;
22606 #if VPP_API_TEST_BUILTIN == 0
22607   foreach_standalone_reply_msg;
22608 #endif
22609 #undef _
22610
22611 #if (VPP_API_TEST_BUILTIN==0)
22612   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22613
22614   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22615
22616   vam->function_by_name = hash_create_string (0, sizeof (uword));
22617
22618   vam->help_by_name = hash_create_string (0, sizeof (uword));
22619 #endif
22620
22621   /* API messages we can send */
22622 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22623   foreach_vpe_api_msg;
22624 #undef _
22625
22626   /* Help strings */
22627 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22628   foreach_vpe_api_msg;
22629 #undef _
22630
22631   /* CLI functions */
22632 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22633   foreach_cli_function;
22634 #undef _
22635
22636   /* Help strings */
22637 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22638   foreach_cli_function;
22639 #undef _
22640 }
22641
22642 #if VPP_API_TEST_BUILTIN
22643 static clib_error_t *
22644 vat_api_hookup_shim (vlib_main_t * vm)
22645 {
22646   vat_api_hookup (&vat_main);
22647   return 0;
22648 }
22649
22650 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22651 #endif
22652
22653 /*
22654  * fd.io coding-style-patch-verification: ON
22655  *
22656  * Local Variables:
22657  * eval: (c-set-style "gnu")
22658  * End:
22659  */