api: Cleanup APIs interface.api
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 void vl_api_set_elog_main (elog_main_t * m);
89 int vl_api_set_elog_trace_api_messages (int enable);
90
91 #if VPP_API_TEST_BUILTIN == 0
92 #include <netdb.h>
93
94 u32
95 vl (void *p)
96 {
97   return vec_len (p);
98 }
99
100 int
101 vat_socket_connect (vat_main_t * vam)
102 {
103   int rv;
104   vam->socket_client_main = &socket_client_main;
105   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
106                                       "vpp_api_test",
107                                       0 /* default socket rx, tx buffer */ )))
108     return rv;
109   /* vpp expects the client index in network order */
110   vam->my_client_index = htonl (socket_client_main.client_index);
111   return 0;
112 }
113 #else /* vpp built-in case, we don't do sockets... */
114 int
115 vat_socket_connect (vat_main_t * vam)
116 {
117   return 0;
118 }
119
120 int
121 vl_socket_client_read (int wait)
122 {
123   return -1;
124 };
125
126 int
127 vl_socket_client_write ()
128 {
129   return -1;
130 };
131
132 void *
133 vl_socket_client_msg_alloc (int nbytes)
134 {
135   return 0;
136 }
137 #endif
138
139
140 f64
141 vat_time_now (vat_main_t * vam)
142 {
143 #if VPP_API_TEST_BUILTIN
144   return vlib_time_now (vam->vlib_main);
145 #else
146   return clib_time_now (&vam->clib_time);
147 #endif
148 }
149
150 void
151 errmsg (char *fmt, ...)
152 {
153   vat_main_t *vam = &vat_main;
154   va_list va;
155   u8 *s;
156
157   va_start (va, fmt);
158   s = va_format (0, fmt, &va);
159   va_end (va);
160
161   vec_add1 (s, 0);
162
163 #if VPP_API_TEST_BUILTIN
164   vlib_cli_output (vam->vlib_main, (char *) s);
165 #else
166   {
167     if (vam->ifp != stdin)
168       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
169                vam->input_line_number);
170     else
171       fformat (vam->ofp, "%s\n", (char *) s);
172     fflush (vam->ofp);
173   }
174 #endif
175
176   vec_free (s);
177 }
178
179 #if VPP_API_TEST_BUILTIN == 0
180 static uword
181 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
182 {
183   vat_main_t *vam = va_arg (*args, vat_main_t *);
184   u32 *result = va_arg (*args, u32 *);
185   u8 *if_name;
186   uword *p;
187
188   if (!unformat (input, "%s", &if_name))
189     return 0;
190
191   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
192   if (p == 0)
193     return 0;
194   *result = p[0];
195   return 1;
196 }
197
198 static uword
199 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
200 {
201   return 0;
202 }
203
204 /* Parse an IP4 address %d.%d.%d.%d. */
205 uword
206 unformat_ip4_address (unformat_input_t * input, va_list * args)
207 {
208   u8 *result = va_arg (*args, u8 *);
209   unsigned a[4];
210
211   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
212     return 0;
213
214   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
215     return 0;
216
217   result[0] = a[0];
218   result[1] = a[1];
219   result[2] = a[2];
220   result[3] = a[3];
221
222   return 1;
223 }
224
225 uword
226 unformat_ethernet_address (unformat_input_t * input, va_list * args)
227 {
228   u8 *result = va_arg (*args, u8 *);
229   u32 i, a[6];
230
231   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
232                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
233     return 0;
234
235   /* Check range. */
236   for (i = 0; i < 6; i++)
237     if (a[i] >= (1 << 8))
238       return 0;
239
240   for (i = 0; i < 6; i++)
241     result[i] = a[i];
242
243   return 1;
244 }
245
246 /* Returns ethernet type as an int in host byte order. */
247 uword
248 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
249                                         va_list * args)
250 {
251   u16 *result = va_arg (*args, u16 *);
252   int type;
253
254   /* Numeric type. */
255   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
256     {
257       if (type >= (1 << 16))
258         return 0;
259       *result = type;
260       return 1;
261     }
262   return 0;
263 }
264
265 /* Parse an IP6 address. */
266 uword
267 unformat_ip6_address (unformat_input_t * input, va_list * args)
268 {
269   ip6_address_t *result = va_arg (*args, ip6_address_t *);
270   u16 hex_quads[8];
271   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
272   uword c, n_colon, double_colon_index;
273
274   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
275   double_colon_index = ARRAY_LEN (hex_quads);
276   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
277     {
278       hex_digit = 16;
279       if (c >= '0' && c <= '9')
280         hex_digit = c - '0';
281       else if (c >= 'a' && c <= 'f')
282         hex_digit = c + 10 - 'a';
283       else if (c >= 'A' && c <= 'F')
284         hex_digit = c + 10 - 'A';
285       else if (c == ':' && n_colon < 2)
286         n_colon++;
287       else
288         {
289           unformat_put_input (input);
290           break;
291         }
292
293       /* Too many hex quads. */
294       if (n_hex_quads >= ARRAY_LEN (hex_quads))
295         return 0;
296
297       if (hex_digit < 16)
298         {
299           hex_quad = (hex_quad << 4) | hex_digit;
300
301           /* Hex quad must fit in 16 bits. */
302           if (n_hex_digits >= 4)
303             return 0;
304
305           n_colon = 0;
306           n_hex_digits++;
307         }
308
309       /* Save position of :: */
310       if (n_colon == 2)
311         {
312           /* More than one :: ? */
313           if (double_colon_index < ARRAY_LEN (hex_quads))
314             return 0;
315           double_colon_index = n_hex_quads;
316         }
317
318       if (n_colon > 0 && n_hex_digits > 0)
319         {
320           hex_quads[n_hex_quads++] = hex_quad;
321           hex_quad = 0;
322           n_hex_digits = 0;
323         }
324     }
325
326   if (n_hex_digits > 0)
327     hex_quads[n_hex_quads++] = hex_quad;
328
329   {
330     word i;
331
332     /* Expand :: to appropriate number of zero hex quads. */
333     if (double_colon_index < ARRAY_LEN (hex_quads))
334       {
335         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
336
337         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
338           hex_quads[n_zero + i] = hex_quads[i];
339
340         for (i = 0; i < n_zero; i++)
341           hex_quads[double_colon_index + i] = 0;
342
343         n_hex_quads = ARRAY_LEN (hex_quads);
344       }
345
346     /* Too few hex quads given. */
347     if (n_hex_quads < ARRAY_LEN (hex_quads))
348       return 0;
349
350     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
351       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
352
353     return 1;
354   }
355 }
356
357 uword
358 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
359 {
360   u32 *r = va_arg (*args, u32 *);
361
362   if (0);
363 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
364   foreach_ipsec_policy_action
365 #undef _
366     else
367     return 0;
368   return 1;
369 }
370
371 u8 *
372 format_ipsec_crypto_alg (u8 * s, va_list * args)
373 {
374   u32 i = va_arg (*args, u32);
375   u8 *t = 0;
376
377   switch (i)
378     {
379 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
380       foreach_ipsec_crypto_alg
381 #undef _
382     default:
383       return format (s, "unknown");
384     }
385   return format (s, "%s", t);
386 }
387
388 u8 *
389 format_ipsec_integ_alg (u8 * s, va_list * args)
390 {
391   u32 i = va_arg (*args, u32);
392   u8 *t = 0;
393
394   switch (i)
395     {
396 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
397       foreach_ipsec_integ_alg
398 #undef _
399     default:
400       return format (s, "unknown");
401     }
402   return format (s, "%s", t);
403 }
404
405 #else /* VPP_API_TEST_BUILTIN == 1 */
406 static uword
407 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
408 {
409   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
410   vnet_main_t *vnm = vnet_get_main ();
411   u32 *result = va_arg (*args, u32 *);
412
413   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
414 }
415
416 static uword
417 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
418 {
419   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
420   vnet_main_t *vnm = vnet_get_main ();
421   u32 *result = va_arg (*args, u32 *);
422
423   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
424 }
425
426 #endif /* VPP_API_TEST_BUILTIN */
427
428 uword
429 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
435   foreach_ipsec_crypto_alg
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
444 {
445   u32 *r = va_arg (*args, u32 *);
446
447   if (0);
448 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
449   foreach_ipsec_integ_alg
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
458 {
459   u8 *r = va_arg (*args, u8 *);
460
461   if (unformat (input, "kbps"))
462     *r = SSE2_QOS_RATE_KBPS;
463   else if (unformat (input, "pps"))
464     *r = SSE2_QOS_RATE_PPS;
465   else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_round_type (unformat_input_t * input, va_list * args)
472 {
473   u8 *r = va_arg (*args, u8 *);
474
475   if (unformat (input, "closest"))
476     *r = SSE2_QOS_ROUND_TO_CLOSEST;
477   else if (unformat (input, "up"))
478     *r = SSE2_QOS_ROUND_TO_UP;
479   else if (unformat (input, "down"))
480     *r = SSE2_QOS_ROUND_TO_DOWN;
481   else
482     return 0;
483   return 1;
484 }
485
486 static uword
487 unformat_policer_type (unformat_input_t * input, va_list * args)
488 {
489   u8 *r = va_arg (*args, u8 *);
490
491   if (unformat (input, "1r2c"))
492     *r = SSE2_QOS_POLICER_TYPE_1R2C;
493   else if (unformat (input, "1r3c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
495   else if (unformat (input, "2r3c-2698"))
496     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
497   else if (unformat (input, "2r3c-4115"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
499   else if (unformat (input, "2r3c-mef5cf1"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
501   else
502     return 0;
503   return 1;
504 }
505
506 static uword
507 unformat_dscp (unformat_input_t * input, va_list * va)
508 {
509   u8 *r = va_arg (*va, u8 *);
510
511   if (0);
512 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
513   foreach_vnet_dscp
514 #undef _
515     else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_action_type (unformat_input_t * input, va_list * va)
522 {
523   sse2_qos_pol_action_params_st *a
524     = va_arg (*va, sse2_qos_pol_action_params_st *);
525
526   if (unformat (input, "drop"))
527     a->action_type = SSE2_QOS_ACTION_DROP;
528   else if (unformat (input, "transmit"))
529     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
530   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
531     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
532   else
533     return 0;
534   return 1;
535 }
536
537 static uword
538 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
539 {
540   u32 *r = va_arg (*va, u32 *);
541   u32 tid;
542
543   if (unformat (input, "ip4"))
544     tid = POLICER_CLASSIFY_TABLE_IP4;
545   else if (unformat (input, "ip6"))
546     tid = POLICER_CLASSIFY_TABLE_IP6;
547   else if (unformat (input, "l2"))
548     tid = POLICER_CLASSIFY_TABLE_L2;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static uword
557 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = FLOW_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = FLOW_CLASSIFY_TABLE_IP6;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 #if (VPP_API_TEST_BUILTIN==0)
574
575 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
576 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
577 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
578 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
579
580 uword
581 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
582 {
583   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
584   mfib_itf_attribute_t attr;
585
586   old = *iflags;
587   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
588   {
589     if (unformat (input, mfib_itf_flag_long_names[attr]))
590       *iflags |= (1 << attr);
591   }
592   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
593   {
594     if (unformat (input, mfib_itf_flag_names[attr]))
595       *iflags |= (1 << attr);
596   }
597
598   return (old == *iflags ? 0 : 1);
599 }
600
601 uword
602 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
603 {
604   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
605   mfib_entry_attribute_t attr;
606
607   old = *eflags;
608   FOR_EACH_MFIB_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_flag_long_names[attr]))
611       *eflags |= (1 << attr);
612   }
613   FOR_EACH_MFIB_ATTRIBUTE (attr)
614   {
615     if (unformat (input, mfib_flag_names[attr]))
616       *eflags |= (1 << attr);
617   }
618
619   return (old == *eflags ? 0 : 1);
620 }
621
622 u8 *
623 format_ip4_address (u8 * s, va_list * args)
624 {
625   u8 *a = va_arg (*args, u8 *);
626   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
627 }
628
629 u8 *
630 format_ip6_address (u8 * s, va_list * args)
631 {
632   ip6_address_t *a = va_arg (*args, ip6_address_t *);
633   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
634
635   i_max_n_zero = ARRAY_LEN (a->as_u16);
636   max_n_zeros = 0;
637   i_first_zero = i_max_n_zero;
638   n_zeros = 0;
639   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
640     {
641       u32 is_zero = a->as_u16[i] == 0;
642       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
643         {
644           i_first_zero = i;
645           n_zeros = 0;
646         }
647       n_zeros += is_zero;
648       if ((!is_zero && n_zeros > max_n_zeros)
649           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
650         {
651           i_max_n_zero = i_first_zero;
652           max_n_zeros = n_zeros;
653           i_first_zero = ARRAY_LEN (a->as_u16);
654           n_zeros = 0;
655         }
656     }
657
658   last_double_colon = 0;
659   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
660     {
661       if (i == i_max_n_zero && max_n_zeros > 1)
662         {
663           s = format (s, "::");
664           i += max_n_zeros - 1;
665           last_double_colon = 1;
666         }
667       else
668         {
669           s = format (s, "%s%x",
670                       (last_double_colon || i == 0) ? "" : ":",
671                       clib_net_to_host_u16 (a->as_u16[i]));
672           last_double_colon = 0;
673         }
674     }
675
676   return s;
677 }
678
679 /* Format an IP46 address. */
680 u8 *
681 format_ip46_address (u8 * s, va_list * args)
682 {
683   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
684   ip46_type_t type = va_arg (*args, ip46_type_t);
685   int is_ip4 = 1;
686
687   switch (type)
688     {
689     case IP46_TYPE_ANY:
690       is_ip4 = ip46_address_is_ip4 (ip46);
691       break;
692     case IP46_TYPE_IP4:
693       is_ip4 = 1;
694       break;
695     case IP46_TYPE_IP6:
696       is_ip4 = 0;
697       break;
698     }
699
700   return is_ip4 ?
701     format (s, "%U", format_ip4_address, &ip46->ip4) :
702     format (s, "%U", format_ip6_address, &ip46->ip6);
703 }
704
705 u8 *
706 format_ethernet_address (u8 * s, va_list * args)
707 {
708   u8 *a = va_arg (*args, u8 *);
709
710   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
711                  a[0], a[1], a[2], a[3], a[4], a[5]);
712 }
713 #endif
714
715 static void
716 increment_v4_address (vl_api_ip4_address_t * i)
717 {
718   ip4_address_t *a = (ip4_address_t *) i;
719   u32 v;
720
721   v = ntohl (a->as_u32) + 1;
722   a->as_u32 = ntohl (v);
723 }
724
725 static void
726 increment_v6_address (vl_api_ip6_address_t * i)
727 {
728   ip6_address_t *a = (ip6_address_t *) i;
729   u64 v0, v1;
730
731   v0 = clib_net_to_host_u64 (a->as_u64[0]);
732   v1 = clib_net_to_host_u64 (a->as_u64[1]);
733
734   v1 += 1;
735   if (v1 == 0)
736     v0 += 1;
737   a->as_u64[0] = clib_net_to_host_u64 (v0);
738   a->as_u64[1] = clib_net_to_host_u64 (v1);
739 }
740
741 static void
742 increment_address (vl_api_address_t * a)
743 {
744   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
745     increment_v4_address (&a->un.ip4);
746   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
747     increment_v6_address (&a->un.ip6);
748 }
749
750 static void
751 set_ip4_address (vl_api_address_t * a, u32 v)
752 {
753   if (a->af == ADDRESS_IP4)
754     {
755       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
756       i->as_u32 = v;
757     }
758 }
759
760 static void
761 increment_mac_address (u8 * mac)
762 {
763   u64 tmp = *((u64 *) mac);
764   tmp = clib_net_to_host_u64 (tmp);
765   tmp += 1 << 16;               /* skip unused (least significant) octets */
766   tmp = clib_host_to_net_u64 (tmp);
767
768   clib_memcpy (mac, &tmp, 6);
769 }
770
771 static void
772 vat_json_object_add_address (vat_json_node_t * node,
773                              const char *str, const vl_api_address_t * addr)
774 {
775   if (ADDRESS_IP6 == addr->af)
776     {
777       struct in6_addr ip6;
778
779       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
780       vat_json_object_add_ip6 (node, str, ip6);
781     }
782   else
783     {
784       struct in_addr ip4;
785
786       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
787       vat_json_object_add_ip4 (node, str, ip4);
788     }
789 }
790
791 static void
792 vat_json_object_add_prefix (vat_json_node_t * node,
793                             const vl_api_prefix_t * prefix)
794 {
795   vat_json_object_add_uint (node, "len", prefix->len);
796   vat_json_object_add_address (node, "address", &prefix->address);
797 }
798
799 static void vl_api_create_loopback_reply_t_handler
800   (vl_api_create_loopback_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   i32 retval = ntohl (mp->retval);
804
805   vam->retval = retval;
806   vam->regenerate_interface_table = 1;
807   vam->sw_if_index = ntohl (mp->sw_if_index);
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_create_loopback_reply_t_handler_json
812   (vl_api_create_loopback_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
820
821   vat_json_print (vam->ofp, &node);
822   vat_json_free (&node);
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 static void vl_api_create_loopback_instance_reply_t_handler
828   (vl_api_create_loopback_instance_reply_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   i32 retval = ntohl (mp->retval);
832
833   vam->retval = retval;
834   vam->regenerate_interface_table = 1;
835   vam->sw_if_index = ntohl (mp->sw_if_index);
836   vam->result_ready = 1;
837 }
838
839 static void vl_api_create_loopback_instance_reply_t_handler_json
840   (vl_api_create_loopback_instance_reply_t * mp)
841 {
842   vat_main_t *vam = &vat_main;
843   vat_json_node_t node;
844
845   vat_json_init_object (&node);
846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
848
849   vat_json_print (vam->ofp, &node);
850   vat_json_free (&node);
851   vam->retval = ntohl (mp->retval);
852   vam->result_ready = 1;
853 }
854
855 static void vl_api_af_packet_create_reply_t_handler
856   (vl_api_af_packet_create_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->regenerate_interface_table = 1;
863   vam->sw_if_index = ntohl (mp->sw_if_index);
864   vam->result_ready = 1;
865 }
866
867 static void vl_api_af_packet_create_reply_t_handler_json
868   (vl_api_af_packet_create_reply_t * mp)
869 {
870   vat_main_t *vam = &vat_main;
871   vat_json_node_t node;
872
873   vat_json_init_object (&node);
874   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
875   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
876
877   vat_json_print (vam->ofp, &node);
878   vat_json_free (&node);
879
880   vam->retval = ntohl (mp->retval);
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_create_vlan_subif_reply_t_handler
885   (vl_api_create_vlan_subif_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   i32 retval = ntohl (mp->retval);
889
890   vam->retval = retval;
891   vam->regenerate_interface_table = 1;
892   vam->sw_if_index = ntohl (mp->sw_if_index);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_create_vlan_subif_reply_t_handler_json
897   (vl_api_create_vlan_subif_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_create_subif_reply_t_handler
914   (vl_api_create_subif_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918
919   vam->retval = retval;
920   vam->regenerate_interface_table = 1;
921   vam->sw_if_index = ntohl (mp->sw_if_index);
922   vam->result_ready = 1;
923 }
924
925 static void vl_api_create_subif_reply_t_handler_json
926   (vl_api_create_subif_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_interface_name_renumber_reply_t_handler
943   (vl_api_interface_name_renumber_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947
948   vam->retval = retval;
949   vam->regenerate_interface_table = 1;
950   vam->result_ready = 1;
951 }
952
953 static void vl_api_interface_name_renumber_reply_t_handler_json
954   (vl_api_interface_name_renumber_reply_t * mp)
955 {
956   vat_main_t *vam = &vat_main;
957   vat_json_node_t node;
958
959   vat_json_init_object (&node);
960   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
961
962   vat_json_print (vam->ofp, &node);
963   vat_json_free (&node);
964
965   vam->retval = ntohl (mp->retval);
966   vam->result_ready = 1;
967 }
968
969 /*
970  * Special-case: build the interface table, maintain
971  * the next loopback sw_if_index vbl.
972  */
973 static void vl_api_sw_interface_details_t_handler
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   u8 *s = format (0, "%s%c",
978                   vl_api_from_api_string (&mp->interface_name), 0);
979
980   hash_set_mem (vam->sw_if_index_by_interface_name, s,
981                 ntohl (mp->sw_if_index));
982
983   /* In sub interface case, fill the sub interface table entry */
984   if (mp->sw_if_index != mp->sup_sw_if_index)
985     {
986       sw_interface_subif_t *sub = NULL;
987
988       vec_add2 (vam->sw_if_subif_table, sub, 1);
989
990       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
991       strncpy ((char *) sub->interface_name, (char *) s,
992                vec_len (sub->interface_name));
993       sub->sw_if_index = ntohl (mp->sw_if_index);
994       sub->sub_id = ntohl (mp->sub_id);
995
996       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
997
998       sub->sub_number_of_tags = mp->sub_number_of_tags;
999       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1000       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1001
1002       /* vlan tag rewrite */
1003       sub->vtr_op = ntohl (mp->vtr_op);
1004       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1005       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1006       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1007     }
1008 }
1009
1010 static void vl_api_sw_interface_details_t_handler_json
1011   (vl_api_sw_interface_details_t * mp)
1012 {
1013   vat_main_t *vam = &vat_main;
1014   vat_json_node_t *node = NULL;
1015
1016   if (VAT_JSON_ARRAY != vam->json_tree.type)
1017     {
1018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1019       vat_json_init_array (&vam->json_tree);
1020     }
1021   node = vat_json_array_add (&vam->json_tree);
1022
1023   vat_json_init_object (node);
1024   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1025   vat_json_object_add_uint (node, "sup_sw_if_index",
1026                             ntohl (mp->sup_sw_if_index));
1027   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1028                              sizeof (mp->l2_address));
1029   vat_json_object_add_string_copy (node, "interface_name",
1030                                    mp->interface_name.buf);
1031   vat_json_object_add_uint (node, "flags", mp->flags);
1032   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1033   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1034   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1035   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1036   vat_json_object_add_uint (node, "sub_number_of_tags",
1037                             mp->sub_number_of_tags);
1038   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1039                             ntohs (mp->sub_outer_vlan_id));
1040   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1041                             ntohs (mp->sub_inner_vlan_id));
1042   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1043   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1044   vat_json_object_add_uint (node, "vtr_push_dot1q",
1045                             ntohl (mp->vtr_push_dot1q));
1046   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1047   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1048   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1049     {
1050       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1051                                        format (0, "%U",
1052                                                format_ethernet_address,
1053                                                &mp->b_dmac));
1054       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1055                                        format (0, "%U",
1056                                                format_ethernet_address,
1057                                                &mp->b_smac));
1058       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1059       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1060     }
1061 }
1062
1063 #if VPP_API_TEST_BUILTIN == 0
1064 static void vl_api_sw_interface_event_t_handler
1065   (vl_api_sw_interface_event_t * mp)
1066 {
1067   vat_main_t *vam = &vat_main;
1068   if (vam->interface_event_display)
1069     errmsg ("interface flags: sw_if_index %d %s %s",
1070             ntohl (mp->sw_if_index),
1071             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1072             "admin-up" : "admin-down",
1073             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1074             "link-up" : "link-down");
1075 }
1076 #endif
1077
1078 __clib_unused static void
1079 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1080 {
1081   /* JSON output not supported */
1082 }
1083
1084 static void
1085 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   vam->retval = retval;
1091   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1092   vam->result_ready = 1;
1093 }
1094
1095 static void
1096 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1097 {
1098   vat_main_t *vam = &vat_main;
1099   vat_json_node_t node;
1100   api_main_t *am = &api_main;
1101   void *oldheap;
1102   u8 *reply;
1103
1104   vat_json_init_object (&node);
1105   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1106   vat_json_object_add_uint (&node, "reply_in_shmem",
1107                             ntohl (mp->reply_in_shmem));
1108   /* Toss the shared-memory original... */
1109   pthread_mutex_lock (&am->vlib_rp->mutex);
1110   oldheap = svm_push_data_heap (am->vlib_rp);
1111
1112   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1113   vec_free (reply);
1114
1115   svm_pop_heap (oldheap);
1116   pthread_mutex_unlock (&am->vlib_rp->mutex);
1117
1118   vat_json_print (vam->ofp, &node);
1119   vat_json_free (&node);
1120
1121   vam->retval = ntohl (mp->retval);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   i32 retval = ntohl (mp->retval);
1130   u32 length = vl_api_string_len (&mp->reply);
1131
1132   vec_reset_length (vam->cmd_reply);
1133
1134   vam->retval = retval;
1135   if (retval == 0)
1136     {
1137       vec_validate (vam->cmd_reply, length);
1138       clib_memcpy ((char *) (vam->cmd_reply),
1139                    vl_api_from_api_string (&mp->reply), length);
1140       vam->cmd_reply[length] = 0;
1141     }
1142   vam->result_ready = 1;
1143 }
1144
1145 static void
1146 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vec_reset_length (vam->cmd_reply);
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "reply",
1156                                    vl_api_from_api_string (&mp->reply));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_classify_add_del_table_reply_t_handler
1166   (vl_api_classify_add_del_table_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0 &&
1178           ((mp->new_table_index != 0xFFFFFFFF) ||
1179            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1180            (mp->match_n_vectors != 0xFFFFFFFF)))
1181         /*
1182          * Note: this is just barely thread-safe, depends on
1183          * the main thread spinning waiting for an answer...
1184          */
1185         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1186                 ntohl (mp->new_table_index),
1187                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1188       vam->result_ready = 1;
1189     }
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler_json
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   vat_json_node_t node;
1197
1198   vat_json_init_object (&node);
1199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1200   vat_json_object_add_uint (&node, "new_table_index",
1201                             ntohl (mp->new_table_index));
1202   vat_json_object_add_uint (&node, "skip_n_vectors",
1203                             ntohl (mp->skip_n_vectors));
1204   vat_json_object_add_uint (&node, "match_n_vectors",
1205                             ntohl (mp->match_n_vectors));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_node_index_reply_t_handler
1215   (vl_api_get_node_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("node index %d", ntohl (mp->node_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_node_index_reply_t_handler_json
1233   (vl_api_get_node_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_get_next_index_reply_t_handler
1250   (vl_api_get_next_index_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next node index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_get_next_index_reply_t_handler_json
1268   (vl_api_get_next_index_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_add_node_next_reply_t_handler
1285   (vl_api_add_node_next_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289   if (vam->async_mode)
1290     {
1291       vam->async_errors += (retval < 0);
1292     }
1293   else
1294     {
1295       vam->retval = retval;
1296       if (retval == 0)
1297         errmsg ("next index %d", ntohl (mp->next_index));
1298       vam->result_ready = 1;
1299     }
1300 }
1301
1302 static void vl_api_add_node_next_reply_t_handler_json
1303   (vl_api_add_node_next_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1311
1312   vat_json_print (vam->ofp, &node);
1313   vat_json_free (&node);
1314
1315   vam->retval = ntohl (mp->retval);
1316   vam->result_ready = 1;
1317 }
1318
1319 static void vl_api_show_version_reply_t_handler
1320   (vl_api_show_version_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   i32 retval = ntohl (mp->retval);
1324
1325   if (retval >= 0)
1326     {
1327       u8 *s = 0;
1328       char *p = (char *) &mp->program;
1329
1330       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1331       errmsg ("        program: %v\n", s);
1332       vec_free (s);
1333
1334       p +=
1335         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1336       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1337       errmsg ("        version: %v\n", s);
1338       vec_free (s);
1339
1340       p +=
1341         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1342       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1343       errmsg ("     build date: %v\n", s);
1344       vec_free (s);
1345
1346       p +=
1347         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1348       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1349       errmsg ("build directory: %v\n", s);
1350       vec_free (s);
1351     }
1352   vam->retval = retval;
1353   vam->result_ready = 1;
1354 }
1355
1356 static void vl_api_show_version_reply_t_handler_json
1357   (vl_api_show_version_reply_t * mp)
1358 {
1359   vat_main_t *vam = &vat_main;
1360   vat_json_node_t node;
1361
1362   vat_json_init_object (&node);
1363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1364   char *p = (char *) &mp->program;
1365   vat_json_object_add_string_copy (&node, "program",
1366                                    vl_api_from_api_string ((vl_api_string_t *)
1367                                                            p));
1368   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1369   vat_json_object_add_string_copy (&node, "version",
1370                                    vl_api_from_api_string ((vl_api_string_t *)
1371                                                            p));
1372   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1373   vat_json_object_add_string_copy (&node, "build_date",
1374                                    vl_api_from_api_string ((vl_api_string_t *)
1375                                                            p));
1376   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1377   vat_json_object_add_string_copy (&node, "build_directory",
1378                                    vl_api_from_api_string ((vl_api_string_t *)
1379                                                            p));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_show_threads_reply_t_handler
1389   (vl_api_show_threads_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   int i, count = 0;
1394
1395   if (retval >= 0)
1396     count = ntohl (mp->count);
1397
1398   for (i = 0; i < count; i++)
1399     print (vam->ofp,
1400            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1401            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1402            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1403            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1404            ntohl (mp->thread_data[i].cpu_socket));
1405
1406   vam->retval = retval;
1407   vam->result_ready = 1;
1408 }
1409
1410 static void vl_api_show_threads_reply_t_handler_json
1411   (vl_api_show_threads_reply_t * mp)
1412 {
1413   vat_main_t *vam = &vat_main;
1414   vat_json_node_t node;
1415   vl_api_thread_data_t *td;
1416   i32 retval = ntohl (mp->retval);
1417   int i, count = 0;
1418
1419   if (retval >= 0)
1420     count = ntohl (mp->count);
1421
1422   vat_json_init_object (&node);
1423   vat_json_object_add_int (&node, "retval", retval);
1424   vat_json_object_add_uint (&node, "count", count);
1425
1426   for (i = 0; i < count; i++)
1427     {
1428       td = &mp->thread_data[i];
1429       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1430       vat_json_object_add_string_copy (&node, "name", td->name);
1431       vat_json_object_add_string_copy (&node, "type", td->type);
1432       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1433       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1434       vat_json_object_add_int (&node, "core", ntohl (td->id));
1435       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1436     }
1437
1438   vat_json_print (vam->ofp, &node);
1439   vat_json_free (&node);
1440
1441   vam->retval = retval;
1442   vam->result_ready = 1;
1443 }
1444
1445 static int
1446 api_show_threads (vat_main_t * vam)
1447 {
1448   vl_api_show_threads_t *mp;
1449   int ret;
1450
1451   print (vam->ofp,
1452          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1453          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1454
1455   M (SHOW_THREADS, mp);
1456
1457   S (mp);
1458   W (ret);
1459   return ret;
1460 }
1461
1462 static void
1463 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1464 {
1465   u32 sw_if_index = ntohl (mp->sw_if_index);
1466   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1467           mp->mac_ip ? "mac/ip binding" : "address resolution",
1468           ntohl (mp->pid), format_ip4_address, mp->ip,
1469           format_vl_api_mac_address, &mp->mac, sw_if_index);
1470 }
1471
1472 static void
1473 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1474 {
1475   /* JSON output not supported */
1476 }
1477
1478 static void
1479 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1480 {
1481   u32 sw_if_index = ntohl (mp->sw_if_index);
1482   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1483           mp->mac_ip ? "mac/ip binding" : "address resolution",
1484           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1485           format_vl_api_mac_address, mp->mac, sw_if_index);
1486 }
1487
1488 static void
1489 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1490 {
1491   /* JSON output not supported */
1492 }
1493
1494 static void
1495 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1496 {
1497   u32 n_macs = ntohl (mp->n_macs);
1498   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1499           ntohl (mp->pid), mp->client_index, n_macs);
1500   int i;
1501   for (i = 0; i < n_macs; i++)
1502     {
1503       vl_api_mac_entry_t *mac = &mp->mac[i];
1504       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1505               i + 1, ntohl (mac->sw_if_index),
1506               format_ethernet_address, mac->mac_addr, mac->action);
1507       if (i == 1000)
1508         break;
1509     }
1510 }
1511
1512 static void
1513 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1514 {
1515   /* JSON output not supported */
1516 }
1517
1518 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1519 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1520
1521 /*
1522  * Special-case: build the bridge domain table, maintain
1523  * the next bd id vbl.
1524  */
1525 static void vl_api_bridge_domain_details_t_handler
1526   (vl_api_bridge_domain_details_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1530   int i;
1531
1532   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1533          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1534
1535   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1536          ntohl (mp->bd_id), mp->learn, mp->forward,
1537          mp->flood, ntohl (mp->bvi_sw_if_index),
1538          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1539
1540   if (n_sw_ifs)
1541     {
1542       vl_api_bridge_domain_sw_if_t *sw_ifs;
1543       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1544              "Interface Name");
1545
1546       sw_ifs = mp->sw_if_details;
1547       for (i = 0; i < n_sw_ifs; i++)
1548         {
1549           u8 *sw_if_name = 0;
1550           u32 sw_if_index;
1551           hash_pair_t *p;
1552
1553           sw_if_index = ntohl (sw_ifs->sw_if_index);
1554
1555           /* *INDENT-OFF* */
1556           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1557                              ({
1558                                if ((u32) p->value[0] == sw_if_index)
1559                                  {
1560                                    sw_if_name = (u8 *)(p->key);
1561                                    break;
1562                                  }
1563                              }));
1564           /* *INDENT-ON* */
1565           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1566                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1567                  "sw_if_index not found!");
1568
1569           sw_ifs++;
1570         }
1571     }
1572 }
1573
1574 static void vl_api_bridge_domain_details_t_handler_json
1575   (vl_api_bridge_domain_details_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   vat_json_node_t *node, *array = NULL;
1579   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1580
1581   if (VAT_JSON_ARRAY != vam->json_tree.type)
1582     {
1583       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1584       vat_json_init_array (&vam->json_tree);
1585     }
1586   node = vat_json_array_add (&vam->json_tree);
1587
1588   vat_json_init_object (node);
1589   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1590   vat_json_object_add_uint (node, "flood", mp->flood);
1591   vat_json_object_add_uint (node, "forward", mp->forward);
1592   vat_json_object_add_uint (node, "learn", mp->learn);
1593   vat_json_object_add_uint (node, "bvi_sw_if_index",
1594                             ntohl (mp->bvi_sw_if_index));
1595   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1596   array = vat_json_object_add (node, "sw_if");
1597   vat_json_init_array (array);
1598
1599
1600
1601   if (n_sw_ifs)
1602     {
1603       vl_api_bridge_domain_sw_if_t *sw_ifs;
1604       int i;
1605
1606       sw_ifs = mp->sw_if_details;
1607       for (i = 0; i < n_sw_ifs; i++)
1608         {
1609           node = vat_json_array_add (array);
1610           vat_json_init_object (node);
1611           vat_json_object_add_uint (node, "sw_if_index",
1612                                     ntohl (sw_ifs->sw_if_index));
1613           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1614           sw_ifs++;
1615         }
1616     }
1617 }
1618
1619 static void vl_api_control_ping_reply_t_handler
1620   (vl_api_control_ping_reply_t * mp)
1621 {
1622   vat_main_t *vam = &vat_main;
1623   i32 retval = ntohl (mp->retval);
1624   if (vam->async_mode)
1625     {
1626       vam->async_errors += (retval < 0);
1627     }
1628   else
1629     {
1630       vam->retval = retval;
1631       vam->result_ready = 1;
1632     }
1633   if (vam->socket_client_main)
1634     vam->socket_client_main->control_pings_outstanding--;
1635 }
1636
1637 static void vl_api_control_ping_reply_t_handler_json
1638   (vl_api_control_ping_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642
1643   if (VAT_JSON_NONE != vam->json_tree.type)
1644     {
1645       vat_json_print (vam->ofp, &vam->json_tree);
1646       vat_json_free (&vam->json_tree);
1647       vam->json_tree.type = VAT_JSON_NONE;
1648     }
1649   else
1650     {
1651       /* just print [] */
1652       vat_json_init_array (&vam->json_tree);
1653       vat_json_print (vam->ofp, &vam->json_tree);
1654       vam->json_tree.type = VAT_JSON_NONE;
1655     }
1656
1657   vam->retval = retval;
1658   vam->result_ready = 1;
1659 }
1660
1661 static void
1662   vl_api_bridge_domain_set_mac_age_reply_t_handler
1663   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   i32 retval = ntohl (mp->retval);
1667   if (vam->async_mode)
1668     {
1669       vam->async_errors += (retval < 0);
1670     }
1671   else
1672     {
1673       vam->retval = retval;
1674       vam->result_ready = 1;
1675     }
1676 }
1677
1678 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1679   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   vat_json_node_t node;
1683
1684   vat_json_init_object (&node);
1685   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void
1695 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   i32 retval = ntohl (mp->retval);
1699   if (vam->async_mode)
1700     {
1701       vam->async_errors += (retval < 0);
1702     }
1703   else
1704     {
1705       vam->retval = retval;
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_l2_flags_reply_t_handler_json
1711   (vl_api_l2_flags_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1719                             ntohl (mp->resulting_feature_bitmap));
1720
1721   vat_json_print (vam->ofp, &node);
1722   vat_json_free (&node);
1723
1724   vam->retval = ntohl (mp->retval);
1725   vam->result_ready = 1;
1726 }
1727
1728 static void vl_api_bridge_flags_reply_t_handler
1729   (vl_api_bridge_flags_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   i32 retval = ntohl (mp->retval);
1733   if (vam->async_mode)
1734     {
1735       vam->async_errors += (retval < 0);
1736     }
1737   else
1738     {
1739       vam->retval = retval;
1740       vam->result_ready = 1;
1741     }
1742 }
1743
1744 static void vl_api_bridge_flags_reply_t_handler_json
1745   (vl_api_bridge_flags_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1753                             ntohl (mp->resulting_feature_bitmap));
1754
1755   vat_json_print (vam->ofp, &node);
1756   vat_json_free (&node);
1757
1758   vam->retval = ntohl (mp->retval);
1759   vam->result_ready = 1;
1760 }
1761
1762 static void
1763 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   i32 retval = ntohl (mp->retval);
1767   if (vam->async_mode)
1768     {
1769       vam->async_errors += (retval < 0);
1770     }
1771   else
1772     {
1773       vam->retval = retval;
1774       vam->sw_if_index = ntohl (mp->sw_if_index);
1775       vam->result_ready = 1;
1776     }
1777
1778 }
1779
1780 static void vl_api_tap_create_v2_reply_t_handler_json
1781   (vl_api_tap_create_v2_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1789
1790   vat_json_print (vam->ofp, &node);
1791   vat_json_free (&node);
1792
1793   vam->retval = ntohl (mp->retval);
1794   vam->result_ready = 1;
1795
1796 }
1797
1798 static void
1799 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->result_ready = 1;
1811     }
1812 }
1813
1814 static void vl_api_tap_delete_v2_reply_t_handler_json
1815   (vl_api_tap_delete_v2_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   vat_json_node_t node;
1819
1820   vat_json_init_object (&node);
1821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1822
1823   vat_json_print (vam->ofp, &node);
1824   vat_json_free (&node);
1825
1826   vam->retval = ntohl (mp->retval);
1827   vam->result_ready = 1;
1828 }
1829
1830 static void
1831 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1832                                           mp)
1833 {
1834   vat_main_t *vam = &vat_main;
1835   i32 retval = ntohl (mp->retval);
1836   if (vam->async_mode)
1837     {
1838       vam->async_errors += (retval < 0);
1839     }
1840   else
1841     {
1842       vam->retval = retval;
1843       vam->sw_if_index = ntohl (mp->sw_if_index);
1844       vam->result_ready = 1;
1845     }
1846 }
1847
1848 static void vl_api_virtio_pci_create_reply_t_handler_json
1849   (vl_api_virtio_pci_create_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863
1864 }
1865
1866 static void
1867 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1868                                           mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   i32 retval = ntohl (mp->retval);
1872   if (vam->async_mode)
1873     {
1874       vam->async_errors += (retval < 0);
1875     }
1876   else
1877     {
1878       vam->retval = retval;
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_virtio_pci_delete_reply_t_handler_json
1884   (vl_api_virtio_pci_delete_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891
1892   vat_json_print (vam->ofp, &node);
1893   vat_json_free (&node);
1894
1895   vam->retval = ntohl (mp->retval);
1896   vam->result_ready = 1;
1897 }
1898
1899 static void
1900 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   i32 retval = ntohl (mp->retval);
1904
1905   if (vam->async_mode)
1906     {
1907       vam->async_errors += (retval < 0);
1908     }
1909   else
1910     {
1911       vam->retval = retval;
1912       vam->sw_if_index = ntohl (mp->sw_if_index);
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_create_reply_t_handler_json
1918   (vl_api_bond_create_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1926
1927   vat_json_print (vam->ofp, &node);
1928   vat_json_free (&node);
1929
1930   vam->retval = ntohl (mp->retval);
1931   vam->result_ready = 1;
1932 }
1933
1934 static void
1935 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1936 {
1937   vat_main_t *vam = &vat_main;
1938   i32 retval = ntohl (mp->retval);
1939
1940   if (vam->async_mode)
1941     {
1942       vam->async_errors += (retval < 0);
1943     }
1944   else
1945     {
1946       vam->retval = retval;
1947       vam->result_ready = 1;
1948     }
1949 }
1950
1951 static void vl_api_bond_delete_reply_t_handler_json
1952   (vl_api_bond_delete_reply_t * mp)
1953 {
1954   vat_main_t *vam = &vat_main;
1955   vat_json_node_t node;
1956
1957   vat_json_init_object (&node);
1958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1959
1960   vat_json_print (vam->ofp, &node);
1961   vat_json_free (&node);
1962
1963   vam->retval = ntohl (mp->retval);
1964   vam->result_ready = 1;
1965 }
1966
1967 static void
1968 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   i32 retval = ntohl (mp->retval);
1972
1973   if (vam->async_mode)
1974     {
1975       vam->async_errors += (retval < 0);
1976     }
1977   else
1978     {
1979       vam->retval = retval;
1980       vam->result_ready = 1;
1981     }
1982 }
1983
1984 static void vl_api_bond_enslave_reply_t_handler_json
1985   (vl_api_bond_enslave_reply_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t node;
1989
1990   vat_json_init_object (&node);
1991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993   vat_json_print (vam->ofp, &node);
1994   vat_json_free (&node);
1995
1996   vam->retval = ntohl (mp->retval);
1997   vam->result_ready = 1;
1998 }
1999
2000 static void
2001 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2002                                           mp)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   i32 retval = ntohl (mp->retval);
2006
2007   if (vam->async_mode)
2008     {
2009       vam->async_errors += (retval < 0);
2010     }
2011   else
2012     {
2013       vam->retval = retval;
2014       vam->result_ready = 1;
2015     }
2016 }
2017
2018 static void vl_api_bond_detach_slave_reply_t_handler_json
2019   (vl_api_bond_detach_slave_reply_t * mp)
2020 {
2021   vat_main_t *vam = &vat_main;
2022   vat_json_node_t node;
2023
2024   vat_json_init_object (&node);
2025   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2026
2027   vat_json_print (vam->ofp, &node);
2028   vat_json_free (&node);
2029
2030   vam->retval = ntohl (mp->retval);
2031   vam->result_ready = 1;
2032 }
2033
2034 static void vl_api_sw_interface_bond_details_t_handler
2035   (vl_api_sw_interface_bond_details_t * mp)
2036 {
2037   vat_main_t *vam = &vat_main;
2038
2039   print (vam->ofp,
2040          "%-16s %-12d %-12U %-13U %-14u %-14u",
2041          mp->interface_name, ntohl (mp->sw_if_index),
2042          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2043          ntohl (mp->active_slaves), ntohl (mp->slaves));
2044 }
2045
2046 static void vl_api_sw_interface_bond_details_t_handler_json
2047   (vl_api_sw_interface_bond_details_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   vat_json_node_t *node = NULL;
2051
2052   if (VAT_JSON_ARRAY != vam->json_tree.type)
2053     {
2054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2055       vat_json_init_array (&vam->json_tree);
2056     }
2057   node = vat_json_array_add (&vam->json_tree);
2058
2059   vat_json_init_object (node);
2060   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2061   vat_json_object_add_string_copy (node, "interface_name",
2062                                    mp->interface_name);
2063   vat_json_object_add_uint (node, "mode", mp->mode);
2064   vat_json_object_add_uint (node, "load_balance", mp->lb);
2065   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2066   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2067 }
2068
2069 static int
2070 api_sw_interface_bond_dump (vat_main_t * vam)
2071 {
2072   vl_api_sw_interface_bond_dump_t *mp;
2073   vl_api_control_ping_t *mp_ping;
2074   int ret;
2075
2076   print (vam->ofp,
2077          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2078          "interface name", "sw_if_index", "mode", "load balance",
2079          "active slaves", "slaves");
2080
2081   /* Get list of bond interfaces */
2082   M (SW_INTERFACE_BOND_DUMP, mp);
2083   S (mp);
2084
2085   /* Use a control ping for synchronization */
2086   MPING (CONTROL_PING, mp_ping);
2087   S (mp_ping);
2088
2089   W (ret);
2090   return ret;
2091 }
2092
2093 static void vl_api_sw_interface_slave_details_t_handler
2094   (vl_api_sw_interface_slave_details_t * mp)
2095 {
2096   vat_main_t *vam = &vat_main;
2097
2098   print (vam->ofp,
2099          "%-25s %-12d %-12d %d", mp->interface_name,
2100          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2101 }
2102
2103 static void vl_api_sw_interface_slave_details_t_handler_json
2104   (vl_api_sw_interface_slave_details_t * mp)
2105 {
2106   vat_main_t *vam = &vat_main;
2107   vat_json_node_t *node = NULL;
2108
2109   if (VAT_JSON_ARRAY != vam->json_tree.type)
2110     {
2111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2112       vat_json_init_array (&vam->json_tree);
2113     }
2114   node = vat_json_array_add (&vam->json_tree);
2115
2116   vat_json_init_object (node);
2117   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2118   vat_json_object_add_string_copy (node, "interface_name",
2119                                    mp->interface_name);
2120   vat_json_object_add_uint (node, "passive", mp->is_passive);
2121   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2122 }
2123
2124 static int
2125 api_sw_interface_slave_dump (vat_main_t * vam)
2126 {
2127   unformat_input_t *i = vam->input;
2128   vl_api_sw_interface_slave_dump_t *mp;
2129   vl_api_control_ping_t *mp_ping;
2130   u32 sw_if_index = ~0;
2131   u8 sw_if_index_set = 0;
2132   int ret;
2133
2134   /* Parse args required to build the message */
2135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2136     {
2137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2138         sw_if_index_set = 1;
2139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2140         sw_if_index_set = 1;
2141       else
2142         break;
2143     }
2144
2145   if (sw_if_index_set == 0)
2146     {
2147       errmsg ("missing vpp interface name. ");
2148       return -99;
2149     }
2150
2151   print (vam->ofp,
2152          "\n%-25s %-12s %-12s %s",
2153          "slave interface name", "sw_if_index", "passive", "long_timeout");
2154
2155   /* Get list of bond interfaces */
2156   M (SW_INTERFACE_SLAVE_DUMP, mp);
2157   mp->sw_if_index = ntohl (sw_if_index);
2158   S (mp);
2159
2160   /* Use a control ping for synchronization */
2161   MPING (CONTROL_PING, mp_ping);
2162   S (mp_ping);
2163
2164   W (ret);
2165   return ret;
2166 }
2167
2168 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2169   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2170 {
2171   vat_main_t *vam = &vat_main;
2172   i32 retval = ntohl (mp->retval);
2173   if (vam->async_mode)
2174     {
2175       vam->async_errors += (retval < 0);
2176     }
2177   else
2178     {
2179       vam->retval = retval;
2180       vam->sw_if_index = ntohl (mp->sw_if_index);
2181       vam->result_ready = 1;
2182     }
2183   vam->regenerate_interface_table = 1;
2184 }
2185
2186 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2187   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2188 {
2189   vat_main_t *vam = &vat_main;
2190   vat_json_node_t node;
2191
2192   vat_json_init_object (&node);
2193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2194   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2195                             ntohl (mp->sw_if_index));
2196
2197   vat_json_print (vam->ofp, &node);
2198   vat_json_free (&node);
2199
2200   vam->retval = ntohl (mp->retval);
2201   vam->result_ready = 1;
2202 }
2203
2204 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2205   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2206 {
2207   vat_main_t *vam = &vat_main;
2208   i32 retval = ntohl (mp->retval);
2209   if (vam->async_mode)
2210     {
2211       vam->async_errors += (retval < 0);
2212     }
2213   else
2214     {
2215       vam->retval = retval;
2216       vam->sw_if_index = ntohl (mp->sw_if_index);
2217       vam->result_ready = 1;
2218     }
2219 }
2220
2221 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2222   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2223 {
2224   vat_main_t *vam = &vat_main;
2225   vat_json_node_t node;
2226
2227   vat_json_init_object (&node);
2228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2229   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2230
2231   vat_json_print (vam->ofp, &node);
2232   vat_json_free (&node);
2233
2234   vam->retval = ntohl (mp->retval);
2235   vam->result_ready = 1;
2236 }
2237
2238 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2239   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   i32 retval = ntohl (mp->retval);
2243   if (vam->async_mode)
2244     {
2245       vam->async_errors += (retval < 0);
2246     }
2247   else
2248     {
2249       vam->retval = retval;
2250       vam->result_ready = 1;
2251     }
2252 }
2253
2254 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2255   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   vat_json_node_t node;
2259
2260   vat_json_init_object (&node);
2261   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2262   vat_json_object_add_uint (&node, "fwd_entry_index",
2263                             clib_net_to_host_u32 (mp->fwd_entry_index));
2264
2265   vat_json_print (vam->ofp, &node);
2266   vat_json_free (&node);
2267
2268   vam->retval = ntohl (mp->retval);
2269   vam->result_ready = 1;
2270 }
2271
2272 u8 *
2273 format_lisp_transport_protocol (u8 * s, va_list * args)
2274 {
2275   u32 proto = va_arg (*args, u32);
2276
2277   switch (proto)
2278     {
2279     case 1:
2280       return format (s, "udp");
2281     case 2:
2282       return format (s, "api");
2283     default:
2284       return 0;
2285     }
2286   return 0;
2287 }
2288
2289 static void vl_api_one_get_transport_protocol_reply_t_handler
2290   (vl_api_one_get_transport_protocol_reply_t * mp)
2291 {
2292   vat_main_t *vam = &vat_main;
2293   i32 retval = ntohl (mp->retval);
2294   if (vam->async_mode)
2295     {
2296       vam->async_errors += (retval < 0);
2297     }
2298   else
2299     {
2300       u32 proto = mp->protocol;
2301       print (vam->ofp, "Transport protocol: %U",
2302              format_lisp_transport_protocol, proto);
2303       vam->retval = retval;
2304       vam->result_ready = 1;
2305     }
2306 }
2307
2308 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2309   (vl_api_one_get_transport_protocol_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   vat_json_node_t node;
2313   u8 *s;
2314
2315   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2316   vec_add1 (s, 0);
2317
2318   vat_json_init_object (&node);
2319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2320   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2321
2322   vec_free (s);
2323   vat_json_print (vam->ofp, &node);
2324   vat_json_free (&node);
2325
2326   vam->retval = ntohl (mp->retval);
2327   vam->result_ready = 1;
2328 }
2329
2330 static void vl_api_one_add_del_locator_set_reply_t_handler
2331   (vl_api_one_add_del_locator_set_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   i32 retval = ntohl (mp->retval);
2335   if (vam->async_mode)
2336     {
2337       vam->async_errors += (retval < 0);
2338     }
2339   else
2340     {
2341       vam->retval = retval;
2342       vam->result_ready = 1;
2343     }
2344 }
2345
2346 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2347   (vl_api_one_add_del_locator_set_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   vat_json_node_t node;
2351
2352   vat_json_init_object (&node);
2353   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2354   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2355
2356   vat_json_print (vam->ofp, &node);
2357   vat_json_free (&node);
2358
2359   vam->retval = ntohl (mp->retval);
2360   vam->result_ready = 1;
2361 }
2362
2363 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2364   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   i32 retval = ntohl (mp->retval);
2368   if (vam->async_mode)
2369     {
2370       vam->async_errors += (retval < 0);
2371     }
2372   else
2373     {
2374       vam->retval = retval;
2375       vam->sw_if_index = ntohl (mp->sw_if_index);
2376       vam->result_ready = 1;
2377     }
2378   vam->regenerate_interface_table = 1;
2379 }
2380
2381 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2382   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   vat_json_node_t node;
2386
2387   vat_json_init_object (&node);
2388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2389   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2390
2391   vat_json_print (vam->ofp, &node);
2392   vat_json_free (&node);
2393
2394   vam->retval = ntohl (mp->retval);
2395   vam->result_ready = 1;
2396 }
2397
2398 static void vl_api_vxlan_offload_rx_reply_t_handler
2399   (vl_api_vxlan_offload_rx_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   i32 retval = ntohl (mp->retval);
2403   if (vam->async_mode)
2404     {
2405       vam->async_errors += (retval < 0);
2406     }
2407   else
2408     {
2409       vam->retval = retval;
2410       vam->result_ready = 1;
2411     }
2412 }
2413
2414 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2415   (vl_api_vxlan_offload_rx_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   vat_json_node_t node;
2419
2420   vat_json_init_object (&node);
2421   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2422
2423   vat_json_print (vam->ofp, &node);
2424   vat_json_free (&node);
2425
2426   vam->retval = ntohl (mp->retval);
2427   vam->result_ready = 1;
2428 }
2429
2430 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2431   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434   i32 retval = ntohl (mp->retval);
2435   if (vam->async_mode)
2436     {
2437       vam->async_errors += (retval < 0);
2438     }
2439   else
2440     {
2441       vam->retval = retval;
2442       vam->sw_if_index = ntohl (mp->sw_if_index);
2443       vam->result_ready = 1;
2444     }
2445 }
2446
2447 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2448   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451   vat_json_node_t node;
2452
2453   vat_json_init_object (&node);
2454   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2455   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2456
2457   vat_json_print (vam->ofp, &node);
2458   vat_json_free (&node);
2459
2460   vam->retval = ntohl (mp->retval);
2461   vam->result_ready = 1;
2462 }
2463
2464 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2465   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2466 {
2467   vat_main_t *vam = &vat_main;
2468   i32 retval = ntohl (mp->retval);
2469   if (vam->async_mode)
2470     {
2471       vam->async_errors += (retval < 0);
2472     }
2473   else
2474     {
2475       vam->retval = retval;
2476       vam->sw_if_index = ntohl (mp->sw_if_index);
2477       vam->result_ready = 1;
2478     }
2479   vam->regenerate_interface_table = 1;
2480 }
2481
2482 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2483   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2484 {
2485   vat_main_t *vam = &vat_main;
2486   vat_json_node_t node;
2487
2488   vat_json_init_object (&node);
2489   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2490   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2491
2492   vat_json_print (vam->ofp, &node);
2493   vat_json_free (&node);
2494
2495   vam->retval = ntohl (mp->retval);
2496   vam->result_ready = 1;
2497 }
2498
2499 static void vl_api_gre_tunnel_add_del_reply_t_handler
2500   (vl_api_gre_tunnel_add_del_reply_t * mp)
2501 {
2502   vat_main_t *vam = &vat_main;
2503   i32 retval = ntohl (mp->retval);
2504   if (vam->async_mode)
2505     {
2506       vam->async_errors += (retval < 0);
2507     }
2508   else
2509     {
2510       vam->retval = retval;
2511       vam->sw_if_index = ntohl (mp->sw_if_index);
2512       vam->result_ready = 1;
2513     }
2514 }
2515
2516 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2517   (vl_api_gre_tunnel_add_del_reply_t * mp)
2518 {
2519   vat_main_t *vam = &vat_main;
2520   vat_json_node_t node;
2521
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2525
2526   vat_json_print (vam->ofp, &node);
2527   vat_json_free (&node);
2528
2529   vam->retval = ntohl (mp->retval);
2530   vam->result_ready = 1;
2531 }
2532
2533 static void vl_api_create_vhost_user_if_reply_t_handler
2534   (vl_api_create_vhost_user_if_reply_t * mp)
2535 {
2536   vat_main_t *vam = &vat_main;
2537   i32 retval = ntohl (mp->retval);
2538   if (vam->async_mode)
2539     {
2540       vam->async_errors += (retval < 0);
2541     }
2542   else
2543     {
2544       vam->retval = retval;
2545       vam->sw_if_index = ntohl (mp->sw_if_index);
2546       vam->result_ready = 1;
2547     }
2548   vam->regenerate_interface_table = 1;
2549 }
2550
2551 static void vl_api_create_vhost_user_if_reply_t_handler_json
2552   (vl_api_create_vhost_user_if_reply_t * mp)
2553 {
2554   vat_main_t *vam = &vat_main;
2555   vat_json_node_t node;
2556
2557   vat_json_init_object (&node);
2558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2559   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2560
2561   vat_json_print (vam->ofp, &node);
2562   vat_json_free (&node);
2563
2564   vam->retval = ntohl (mp->retval);
2565   vam->result_ready = 1;
2566 }
2567
2568 static void vl_api_dns_resolve_name_reply_t_handler
2569   (vl_api_dns_resolve_name_reply_t * mp)
2570 {
2571   vat_main_t *vam = &vat_main;
2572   i32 retval = ntohl (mp->retval);
2573   if (vam->async_mode)
2574     {
2575       vam->async_errors += (retval < 0);
2576     }
2577   else
2578     {
2579       vam->retval = retval;
2580       vam->result_ready = 1;
2581
2582       if (retval == 0)
2583         {
2584           if (mp->ip4_set)
2585             clib_warning ("ip4 address %U", format_ip4_address,
2586                           (ip4_address_t *) mp->ip4_address);
2587           if (mp->ip6_set)
2588             clib_warning ("ip6 address %U", format_ip6_address,
2589                           (ip6_address_t *) mp->ip6_address);
2590         }
2591       else
2592         clib_warning ("retval %d", retval);
2593     }
2594 }
2595
2596 static void vl_api_dns_resolve_name_reply_t_handler_json
2597   (vl_api_dns_resolve_name_reply_t * mp)
2598 {
2599   clib_warning ("not implemented");
2600 }
2601
2602 static void vl_api_dns_resolve_ip_reply_t_handler
2603   (vl_api_dns_resolve_ip_reply_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   i32 retval = ntohl (mp->retval);
2607   if (vam->async_mode)
2608     {
2609       vam->async_errors += (retval < 0);
2610     }
2611   else
2612     {
2613       vam->retval = retval;
2614       vam->result_ready = 1;
2615
2616       if (retval == 0)
2617         {
2618           clib_warning ("canonical name %s", mp->name);
2619         }
2620       else
2621         clib_warning ("retval %d", retval);
2622     }
2623 }
2624
2625 static void vl_api_dns_resolve_ip_reply_t_handler_json
2626   (vl_api_dns_resolve_ip_reply_t * mp)
2627 {
2628   clib_warning ("not implemented");
2629 }
2630
2631
2632 static void vl_api_ip_address_details_t_handler
2633   (vl_api_ip_address_details_t * mp)
2634 {
2635   vat_main_t *vam = &vat_main;
2636   static ip_address_details_t empty_ip_address_details = { {0} };
2637   ip_address_details_t *address = NULL;
2638   ip_details_t *current_ip_details = NULL;
2639   ip_details_t *details = NULL;
2640
2641   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2642
2643   if (!details || vam->current_sw_if_index >= vec_len (details)
2644       || !details[vam->current_sw_if_index].present)
2645     {
2646       errmsg ("ip address details arrived but not stored");
2647       errmsg ("ip_dump should be called first");
2648       return;
2649     }
2650
2651   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2652
2653 #define addresses (current_ip_details->addr)
2654
2655   vec_validate_init_empty (addresses, vec_len (addresses),
2656                            empty_ip_address_details);
2657
2658   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2659
2660   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2661   address->prefix_length = mp->prefix.len;
2662 #undef addresses
2663 }
2664
2665 static void vl_api_ip_address_details_t_handler_json
2666   (vl_api_ip_address_details_t * mp)
2667 {
2668   vat_main_t *vam = &vat_main;
2669   vat_json_node_t *node = NULL;
2670
2671   if (VAT_JSON_ARRAY != vam->json_tree.type)
2672     {
2673       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2674       vat_json_init_array (&vam->json_tree);
2675     }
2676   node = vat_json_array_add (&vam->json_tree);
2677
2678   vat_json_init_object (node);
2679   vat_json_object_add_prefix (node, &mp->prefix);
2680 }
2681
2682 static void
2683 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2684 {
2685   vat_main_t *vam = &vat_main;
2686   static ip_details_t empty_ip_details = { 0 };
2687   ip_details_t *ip = NULL;
2688   u32 sw_if_index = ~0;
2689
2690   sw_if_index = ntohl (mp->sw_if_index);
2691
2692   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2693                            sw_if_index, empty_ip_details);
2694
2695   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2696                          sw_if_index);
2697
2698   ip->present = 1;
2699 }
2700
2701 static void
2702 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2703 {
2704   vat_main_t *vam = &vat_main;
2705
2706   if (VAT_JSON_ARRAY != vam->json_tree.type)
2707     {
2708       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2709       vat_json_init_array (&vam->json_tree);
2710     }
2711   vat_json_array_add_uint (&vam->json_tree,
2712                            clib_net_to_host_u32 (mp->sw_if_index));
2713 }
2714
2715 static void
2716 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2717 {
2718   u8 *s, i;
2719
2720   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2721               "host_mac %U router_addr %U",
2722               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2723               mp->lease.hostname,
2724               format_ip4_address, mp->lease.host_address,
2725               format_ethernet_address, mp->lease.host_mac,
2726               format_ip4_address, mp->lease.router_address);
2727
2728   for (i = 0; i < mp->lease.count; i++)
2729     s =
2730       format (s, " domain_server_addr %U", format_ip4_address,
2731               mp->lease.domain_server[i].address);
2732
2733   errmsg ((char *) s);
2734   vec_free (s);
2735 }
2736
2737 static void vl_api_dhcp_compl_event_t_handler_json
2738   (vl_api_dhcp_compl_event_t * mp)
2739 {
2740   /* JSON output not supported */
2741 }
2742
2743 static void vl_api_get_first_msg_id_reply_t_handler
2744   (vl_api_get_first_msg_id_reply_t * mp)
2745 {
2746   vat_main_t *vam = &vat_main;
2747   i32 retval = ntohl (mp->retval);
2748
2749   if (vam->async_mode)
2750     {
2751       vam->async_errors += (retval < 0);
2752     }
2753   else
2754     {
2755       vam->retval = retval;
2756       vam->result_ready = 1;
2757     }
2758   if (retval >= 0)
2759     {
2760       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2761     }
2762 }
2763
2764 static void vl_api_get_first_msg_id_reply_t_handler_json
2765   (vl_api_get_first_msg_id_reply_t * mp)
2766 {
2767   vat_main_t *vam = &vat_main;
2768   vat_json_node_t node;
2769
2770   vat_json_init_object (&node);
2771   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2772   vat_json_object_add_uint (&node, "first_msg_id",
2773                             (uint) ntohs (mp->first_msg_id));
2774
2775   vat_json_print (vam->ofp, &node);
2776   vat_json_free (&node);
2777
2778   vam->retval = ntohl (mp->retval);
2779   vam->result_ready = 1;
2780 }
2781
2782 static void vl_api_get_node_graph_reply_t_handler
2783   (vl_api_get_node_graph_reply_t * mp)
2784 {
2785   vat_main_t *vam = &vat_main;
2786   api_main_t *am = &api_main;
2787   i32 retval = ntohl (mp->retval);
2788   u8 *pvt_copy, *reply;
2789   void *oldheap;
2790   vlib_node_t *node;
2791   int i;
2792
2793   if (vam->async_mode)
2794     {
2795       vam->async_errors += (retval < 0);
2796     }
2797   else
2798     {
2799       vam->retval = retval;
2800       vam->result_ready = 1;
2801     }
2802
2803   /* "Should never happen..." */
2804   if (retval != 0)
2805     return;
2806
2807   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2808   pvt_copy = vec_dup (reply);
2809
2810   /* Toss the shared-memory original... */
2811   pthread_mutex_lock (&am->vlib_rp->mutex);
2812   oldheap = svm_push_data_heap (am->vlib_rp);
2813
2814   vec_free (reply);
2815
2816   svm_pop_heap (oldheap);
2817   pthread_mutex_unlock (&am->vlib_rp->mutex);
2818
2819   if (vam->graph_nodes)
2820     {
2821       hash_free (vam->graph_node_index_by_name);
2822
2823       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2824         {
2825           node = vam->graph_nodes[0][i];
2826           vec_free (node->name);
2827           vec_free (node->next_nodes);
2828           vec_free (node);
2829         }
2830       vec_free (vam->graph_nodes[0]);
2831       vec_free (vam->graph_nodes);
2832     }
2833
2834   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2835   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2836   vec_free (pvt_copy);
2837
2838   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2839     {
2840       node = vam->graph_nodes[0][i];
2841       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2842     }
2843 }
2844
2845 static void vl_api_get_node_graph_reply_t_handler_json
2846   (vl_api_get_node_graph_reply_t * mp)
2847 {
2848   vat_main_t *vam = &vat_main;
2849   api_main_t *am = &api_main;
2850   void *oldheap;
2851   vat_json_node_t node;
2852   u8 *reply;
2853
2854   /* $$$$ make this real? */
2855   vat_json_init_object (&node);
2856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2857   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2858
2859   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2860
2861   /* Toss the shared-memory original... */
2862   pthread_mutex_lock (&am->vlib_rp->mutex);
2863   oldheap = svm_push_data_heap (am->vlib_rp);
2864
2865   vec_free (reply);
2866
2867   svm_pop_heap (oldheap);
2868   pthread_mutex_unlock (&am->vlib_rp->mutex);
2869
2870   vat_json_print (vam->ofp, &node);
2871   vat_json_free (&node);
2872
2873   vam->retval = ntohl (mp->retval);
2874   vam->result_ready = 1;
2875 }
2876
2877 static void
2878 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2879 {
2880   vat_main_t *vam = &vat_main;
2881   u8 *s = 0;
2882
2883   if (mp->local)
2884     {
2885       s = format (s, "%=16d%=16d%=16d",
2886                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2887     }
2888   else
2889     {
2890       s = format (s, "%=16U%=16d%=16d",
2891                   mp->is_ipv6 ? format_ip6_address :
2892                   format_ip4_address,
2893                   mp->ip_address, mp->priority, mp->weight);
2894     }
2895
2896   print (vam->ofp, "%v", s);
2897   vec_free (s);
2898 }
2899
2900 static void
2901 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2902 {
2903   vat_main_t *vam = &vat_main;
2904   vat_json_node_t *node = NULL;
2905   struct in6_addr ip6;
2906   struct in_addr ip4;
2907
2908   if (VAT_JSON_ARRAY != vam->json_tree.type)
2909     {
2910       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2911       vat_json_init_array (&vam->json_tree);
2912     }
2913   node = vat_json_array_add (&vam->json_tree);
2914   vat_json_init_object (node);
2915
2916   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2917   vat_json_object_add_uint (node, "priority", mp->priority);
2918   vat_json_object_add_uint (node, "weight", mp->weight);
2919
2920   if (mp->local)
2921     vat_json_object_add_uint (node, "sw_if_index",
2922                               clib_net_to_host_u32 (mp->sw_if_index));
2923   else
2924     {
2925       if (mp->is_ipv6)
2926         {
2927           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2928           vat_json_object_add_ip6 (node, "address", ip6);
2929         }
2930       else
2931         {
2932           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2933           vat_json_object_add_ip4 (node, "address", ip4);
2934         }
2935     }
2936 }
2937
2938 static void
2939 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2940                                           mp)
2941 {
2942   vat_main_t *vam = &vat_main;
2943   u8 *ls_name = 0;
2944
2945   ls_name = format (0, "%s", mp->ls_name);
2946
2947   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2948          ls_name);
2949   vec_free (ls_name);
2950 }
2951
2952 static void
2953   vl_api_one_locator_set_details_t_handler_json
2954   (vl_api_one_locator_set_details_t * mp)
2955 {
2956   vat_main_t *vam = &vat_main;
2957   vat_json_node_t *node = 0;
2958   u8 *ls_name = 0;
2959
2960   ls_name = format (0, "%s", mp->ls_name);
2961   vec_add1 (ls_name, 0);
2962
2963   if (VAT_JSON_ARRAY != vam->json_tree.type)
2964     {
2965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2966       vat_json_init_array (&vam->json_tree);
2967     }
2968   node = vat_json_array_add (&vam->json_tree);
2969
2970   vat_json_init_object (node);
2971   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2972   vat_json_object_add_uint (node, "ls_index",
2973                             clib_net_to_host_u32 (mp->ls_index));
2974   vec_free (ls_name);
2975 }
2976
2977 typedef struct
2978 {
2979   u32 spi;
2980   u8 si;
2981 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2982
2983 uword
2984 unformat_nsh_address (unformat_input_t * input, va_list * args)
2985 {
2986   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2987   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2988 }
2989
2990 u8 *
2991 format_nsh_address_vat (u8 * s, va_list * args)
2992 {
2993   nsh_t *a = va_arg (*args, nsh_t *);
2994   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2995 }
2996
2997 static u8 *
2998 format_lisp_flat_eid (u8 * s, va_list * args)
2999 {
3000   u32 type = va_arg (*args, u32);
3001   u8 *eid = va_arg (*args, u8 *);
3002   u32 eid_len = va_arg (*args, u32);
3003
3004   switch (type)
3005     {
3006     case 0:
3007       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3008     case 1:
3009       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3010     case 2:
3011       return format (s, "%U", format_ethernet_address, eid);
3012     case 3:
3013       return format (s, "%U", format_nsh_address_vat, eid);
3014     }
3015   return 0;
3016 }
3017
3018 static u8 *
3019 format_lisp_eid_vat (u8 * s, va_list * args)
3020 {
3021   u32 type = va_arg (*args, u32);
3022   u8 *eid = va_arg (*args, u8 *);
3023   u32 eid_len = va_arg (*args, u32);
3024   u8 *seid = va_arg (*args, u8 *);
3025   u32 seid_len = va_arg (*args, u32);
3026   u32 is_src_dst = va_arg (*args, u32);
3027
3028   if (is_src_dst)
3029     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3030
3031   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3032
3033   return s;
3034 }
3035
3036 static void
3037 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   u8 *s = 0, *eid = 0;
3041
3042   if (~0 == mp->locator_set_index)
3043     s = format (0, "action: %d", mp->action);
3044   else
3045     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3046
3047   eid = format (0, "%U", format_lisp_eid_vat,
3048                 mp->eid_type,
3049                 mp->eid,
3050                 mp->eid_prefix_len,
3051                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3052   vec_add1 (eid, 0);
3053
3054   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3055          clib_net_to_host_u32 (mp->vni),
3056          eid,
3057          mp->is_local ? "local" : "remote",
3058          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3059          clib_net_to_host_u16 (mp->key_id), mp->key);
3060
3061   vec_free (s);
3062   vec_free (eid);
3063 }
3064
3065 static void
3066 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3067                                              * mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   vat_json_node_t *node = 0;
3071   u8 *eid = 0;
3072
3073   if (VAT_JSON_ARRAY != vam->json_tree.type)
3074     {
3075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3076       vat_json_init_array (&vam->json_tree);
3077     }
3078   node = vat_json_array_add (&vam->json_tree);
3079
3080   vat_json_init_object (node);
3081   if (~0 == mp->locator_set_index)
3082     vat_json_object_add_uint (node, "action", mp->action);
3083   else
3084     vat_json_object_add_uint (node, "locator_set_index",
3085                               clib_net_to_host_u32 (mp->locator_set_index));
3086
3087   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3088   if (mp->eid_type == 3)
3089     {
3090       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3091       vat_json_init_object (nsh_json);
3092       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3093       vat_json_object_add_uint (nsh_json, "spi",
3094                                 clib_net_to_host_u32 (nsh->spi));
3095       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3096     }
3097   else
3098     {
3099       eid = format (0, "%U", format_lisp_eid_vat,
3100                     mp->eid_type,
3101                     mp->eid,
3102                     mp->eid_prefix_len,
3103                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3104       vec_add1 (eid, 0);
3105       vat_json_object_add_string_copy (node, "eid", eid);
3106       vec_free (eid);
3107     }
3108   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3109   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3110   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3111
3112   if (mp->key_id)
3113     {
3114       vat_json_object_add_uint (node, "key_id",
3115                                 clib_net_to_host_u16 (mp->key_id));
3116       vat_json_object_add_string_copy (node, "key", mp->key);
3117     }
3118 }
3119
3120 static void
3121 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   u8 *seid = 0, *deid = 0;
3125   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3126
3127   deid = format (0, "%U", format_lisp_eid_vat,
3128                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3129
3130   seid = format (0, "%U", format_lisp_eid_vat,
3131                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3132
3133   vec_add1 (deid, 0);
3134   vec_add1 (seid, 0);
3135
3136   if (mp->is_ip4)
3137     format_ip_address_fcn = format_ip4_address;
3138   else
3139     format_ip_address_fcn = format_ip6_address;
3140
3141
3142   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3143          clib_net_to_host_u32 (mp->vni),
3144          seid, deid,
3145          format_ip_address_fcn, mp->lloc,
3146          format_ip_address_fcn, mp->rloc,
3147          clib_net_to_host_u32 (mp->pkt_count),
3148          clib_net_to_host_u32 (mp->bytes));
3149
3150   vec_free (deid);
3151   vec_free (seid);
3152 }
3153
3154 static void
3155 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3156 {
3157   struct in6_addr ip6;
3158   struct in_addr ip4;
3159   vat_main_t *vam = &vat_main;
3160   vat_json_node_t *node = 0;
3161   u8 *deid = 0, *seid = 0;
3162
3163   if (VAT_JSON_ARRAY != vam->json_tree.type)
3164     {
3165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3166       vat_json_init_array (&vam->json_tree);
3167     }
3168   node = vat_json_array_add (&vam->json_tree);
3169
3170   vat_json_init_object (node);
3171   deid = format (0, "%U", format_lisp_eid_vat,
3172                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3173
3174   seid = format (0, "%U", format_lisp_eid_vat,
3175                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3176
3177   vec_add1 (deid, 0);
3178   vec_add1 (seid, 0);
3179
3180   vat_json_object_add_string_copy (node, "seid", seid);
3181   vat_json_object_add_string_copy (node, "deid", deid);
3182   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3183
3184   if (mp->is_ip4)
3185     {
3186       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3187       vat_json_object_add_ip4 (node, "lloc", ip4);
3188       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3189       vat_json_object_add_ip4 (node, "rloc", ip4);
3190     }
3191   else
3192     {
3193       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3194       vat_json_object_add_ip6 (node, "lloc", ip6);
3195       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3196       vat_json_object_add_ip6 (node, "rloc", ip6);
3197     }
3198   vat_json_object_add_uint (node, "pkt_count",
3199                             clib_net_to_host_u32 (mp->pkt_count));
3200   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3201
3202   vec_free (deid);
3203   vec_free (seid);
3204 }
3205
3206 static void
3207   vl_api_one_eid_table_map_details_t_handler
3208   (vl_api_one_eid_table_map_details_t * mp)
3209 {
3210   vat_main_t *vam = &vat_main;
3211
3212   u8 *line = format (0, "%=10d%=10d",
3213                      clib_net_to_host_u32 (mp->vni),
3214                      clib_net_to_host_u32 (mp->dp_table));
3215   print (vam->ofp, "%v", line);
3216   vec_free (line);
3217 }
3218
3219 static void
3220   vl_api_one_eid_table_map_details_t_handler_json
3221   (vl_api_one_eid_table_map_details_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   vat_json_node_t *node = NULL;
3225
3226   if (VAT_JSON_ARRAY != vam->json_tree.type)
3227     {
3228       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3229       vat_json_init_array (&vam->json_tree);
3230     }
3231   node = vat_json_array_add (&vam->json_tree);
3232   vat_json_init_object (node);
3233   vat_json_object_add_uint (node, "dp_table",
3234                             clib_net_to_host_u32 (mp->dp_table));
3235   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3236 }
3237
3238 static void
3239   vl_api_one_eid_table_vni_details_t_handler
3240   (vl_api_one_eid_table_vni_details_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243
3244   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3245   print (vam->ofp, "%v", line);
3246   vec_free (line);
3247 }
3248
3249 static void
3250   vl_api_one_eid_table_vni_details_t_handler_json
3251   (vl_api_one_eid_table_vni_details_t * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254   vat_json_node_t *node = NULL;
3255
3256   if (VAT_JSON_ARRAY != vam->json_tree.type)
3257     {
3258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3259       vat_json_init_array (&vam->json_tree);
3260     }
3261   node = vat_json_array_add (&vam->json_tree);
3262   vat_json_init_object (node);
3263   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3264 }
3265
3266 static void
3267   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3268   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3269 {
3270   vat_main_t *vam = &vat_main;
3271   int retval = clib_net_to_host_u32 (mp->retval);
3272
3273   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3274   print (vam->ofp, "fallback threshold value: %d", mp->value);
3275
3276   vam->retval = retval;
3277   vam->result_ready = 1;
3278 }
3279
3280 static void
3281   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3282   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3283 {
3284   vat_main_t *vam = &vat_main;
3285   vat_json_node_t _node, *node = &_node;
3286   int retval = clib_net_to_host_u32 (mp->retval);
3287
3288   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3289   vat_json_init_object (node);
3290   vat_json_object_add_uint (node, "value", mp->value);
3291
3292   vat_json_print (vam->ofp, node);
3293   vat_json_free (node);
3294
3295   vam->retval = retval;
3296   vam->result_ready = 1;
3297 }
3298
3299 static void
3300   vl_api_show_one_map_register_state_reply_t_handler
3301   (vl_api_show_one_map_register_state_reply_t * mp)
3302 {
3303   vat_main_t *vam = &vat_main;
3304   int retval = clib_net_to_host_u32 (mp->retval);
3305
3306   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3307
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_show_one_map_register_state_reply_t_handler_json
3314   (vl_api_show_one_map_register_state_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   vat_json_node_t _node, *node = &_node;
3318   int retval = clib_net_to_host_u32 (mp->retval);
3319
3320   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3321
3322   vat_json_init_object (node);
3323   vat_json_object_add_string_copy (node, "state", s);
3324
3325   vat_json_print (vam->ofp, node);
3326   vat_json_free (node);
3327
3328   vam->retval = retval;
3329   vam->result_ready = 1;
3330   vec_free (s);
3331 }
3332
3333 static void
3334   vl_api_show_one_rloc_probe_state_reply_t_handler
3335   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3336 {
3337   vat_main_t *vam = &vat_main;
3338   int retval = clib_net_to_host_u32 (mp->retval);
3339
3340   if (retval)
3341     goto end;
3342
3343   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3344 end:
3345   vam->retval = retval;
3346   vam->result_ready = 1;
3347 }
3348
3349 static void
3350   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3351   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3352 {
3353   vat_main_t *vam = &vat_main;
3354   vat_json_node_t _node, *node = &_node;
3355   int retval = clib_net_to_host_u32 (mp->retval);
3356
3357   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3358   vat_json_init_object (node);
3359   vat_json_object_add_string_copy (node, "state", s);
3360
3361   vat_json_print (vam->ofp, node);
3362   vat_json_free (node);
3363
3364   vam->retval = retval;
3365   vam->result_ready = 1;
3366   vec_free (s);
3367 }
3368
3369 static void
3370   vl_api_show_one_stats_enable_disable_reply_t_handler
3371   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   int retval = clib_net_to_host_u32 (mp->retval);
3375
3376   if (retval)
3377     goto end;
3378
3379   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3380 end:
3381   vam->retval = retval;
3382   vam->result_ready = 1;
3383 }
3384
3385 static void
3386   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3387   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3388 {
3389   vat_main_t *vam = &vat_main;
3390   vat_json_node_t _node, *node = &_node;
3391   int retval = clib_net_to_host_u32 (mp->retval);
3392
3393   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3394   vat_json_init_object (node);
3395   vat_json_object_add_string_copy (node, "state", s);
3396
3397   vat_json_print (vam->ofp, node);
3398   vat_json_free (node);
3399
3400   vam->retval = retval;
3401   vam->result_ready = 1;
3402   vec_free (s);
3403 }
3404
3405 static void
3406 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3407 {
3408   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3409   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3410   e->vni = clib_net_to_host_u32 (e->vni);
3411 }
3412
3413 static void
3414   gpe_fwd_entries_get_reply_t_net_to_host
3415   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3416 {
3417   u32 i;
3418
3419   mp->count = clib_net_to_host_u32 (mp->count);
3420   for (i = 0; i < mp->count; i++)
3421     {
3422       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3423     }
3424 }
3425
3426 static u8 *
3427 format_gpe_encap_mode (u8 * s, va_list * args)
3428 {
3429   u32 mode = va_arg (*args, u32);
3430
3431   switch (mode)
3432     {
3433     case 0:
3434       return format (s, "lisp");
3435     case 1:
3436       return format (s, "vxlan");
3437     }
3438   return 0;
3439 }
3440
3441 static void
3442   vl_api_gpe_get_encap_mode_reply_t_handler
3443   (vl_api_gpe_get_encap_mode_reply_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446
3447   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3448   vam->retval = ntohl (mp->retval);
3449   vam->result_ready = 1;
3450 }
3451
3452 static void
3453   vl_api_gpe_get_encap_mode_reply_t_handler_json
3454   (vl_api_gpe_get_encap_mode_reply_t * mp)
3455 {
3456   vat_main_t *vam = &vat_main;
3457   vat_json_node_t node;
3458
3459   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3460   vec_add1 (encap_mode, 0);
3461
3462   vat_json_init_object (&node);
3463   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3464
3465   vec_free (encap_mode);
3466   vat_json_print (vam->ofp, &node);
3467   vat_json_free (&node);
3468
3469   vam->retval = ntohl (mp->retval);
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_gpe_fwd_entry_path_details_t_handler
3475   (vl_api_gpe_fwd_entry_path_details_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3479
3480   if (mp->lcl_loc.is_ip4)
3481     format_ip_address_fcn = format_ip4_address;
3482   else
3483     format_ip_address_fcn = format_ip6_address;
3484
3485   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3486          format_ip_address_fcn, &mp->lcl_loc,
3487          format_ip_address_fcn, &mp->rmt_loc);
3488 }
3489
3490 static void
3491 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3492 {
3493   struct in6_addr ip6;
3494   struct in_addr ip4;
3495
3496   if (loc->is_ip4)
3497     {
3498       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3499       vat_json_object_add_ip4 (n, "address", ip4);
3500     }
3501   else
3502     {
3503       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3504       vat_json_object_add_ip6 (n, "address", ip6);
3505     }
3506   vat_json_object_add_uint (n, "weight", loc->weight);
3507 }
3508
3509 static void
3510   vl_api_gpe_fwd_entry_path_details_t_handler_json
3511   (vl_api_gpe_fwd_entry_path_details_t * mp)
3512 {
3513   vat_main_t *vam = &vat_main;
3514   vat_json_node_t *node = NULL;
3515   vat_json_node_t *loc_node;
3516
3517   if (VAT_JSON_ARRAY != vam->json_tree.type)
3518     {
3519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3520       vat_json_init_array (&vam->json_tree);
3521     }
3522   node = vat_json_array_add (&vam->json_tree);
3523   vat_json_init_object (node);
3524
3525   loc_node = vat_json_object_add (node, "local_locator");
3526   vat_json_init_object (loc_node);
3527   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3528
3529   loc_node = vat_json_object_add (node, "remote_locator");
3530   vat_json_init_object (loc_node);
3531   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3532 }
3533
3534 static void
3535   vl_api_gpe_fwd_entries_get_reply_t_handler
3536   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3537 {
3538   vat_main_t *vam = &vat_main;
3539   u32 i;
3540   int retval = clib_net_to_host_u32 (mp->retval);
3541   vl_api_gpe_fwd_entry_t *e;
3542
3543   if (retval)
3544     goto end;
3545
3546   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3547
3548   for (i = 0; i < mp->count; i++)
3549     {
3550       e = &mp->entries[i];
3551       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3552              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3553              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3554     }
3555
3556 end:
3557   vam->retval = retval;
3558   vam->result_ready = 1;
3559 }
3560
3561 static void
3562   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3563   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3564 {
3565   u8 *s = 0;
3566   vat_main_t *vam = &vat_main;
3567   vat_json_node_t *e = 0, root;
3568   u32 i;
3569   int retval = clib_net_to_host_u32 (mp->retval);
3570   vl_api_gpe_fwd_entry_t *fwd;
3571
3572   if (retval)
3573     goto end;
3574
3575   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3576   vat_json_init_array (&root);
3577
3578   for (i = 0; i < mp->count; i++)
3579     {
3580       e = vat_json_array_add (&root);
3581       fwd = &mp->entries[i];
3582
3583       vat_json_init_object (e);
3584       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3585       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3586       vat_json_object_add_int (e, "vni", fwd->vni);
3587       vat_json_object_add_int (e, "action", fwd->action);
3588
3589       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3590                   fwd->leid_prefix_len);
3591       vec_add1 (s, 0);
3592       vat_json_object_add_string_copy (e, "leid", s);
3593       vec_free (s);
3594
3595       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3596                   fwd->reid_prefix_len);
3597       vec_add1 (s, 0);
3598       vat_json_object_add_string_copy (e, "reid", s);
3599       vec_free (s);
3600     }
3601
3602   vat_json_print (vam->ofp, &root);
3603   vat_json_free (&root);
3604
3605 end:
3606   vam->retval = retval;
3607   vam->result_ready = 1;
3608 }
3609
3610 static void
3611   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3612   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615   u32 i, n;
3616   int retval = clib_net_to_host_u32 (mp->retval);
3617   vl_api_gpe_native_fwd_rpath_t *r;
3618
3619   if (retval)
3620     goto end;
3621
3622   n = clib_net_to_host_u32 (mp->count);
3623
3624   for (i = 0; i < n; i++)
3625     {
3626       r = &mp->entries[i];
3627       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3628              clib_net_to_host_u32 (r->fib_index),
3629              clib_net_to_host_u32 (r->nh_sw_if_index),
3630              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3631     }
3632
3633 end:
3634   vam->retval = retval;
3635   vam->result_ready = 1;
3636 }
3637
3638 static void
3639   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3640   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3641 {
3642   vat_main_t *vam = &vat_main;
3643   vat_json_node_t root, *e;
3644   u32 i, n;
3645   int retval = clib_net_to_host_u32 (mp->retval);
3646   vl_api_gpe_native_fwd_rpath_t *r;
3647   u8 *s;
3648
3649   if (retval)
3650     goto end;
3651
3652   n = clib_net_to_host_u32 (mp->count);
3653   vat_json_init_array (&root);
3654
3655   for (i = 0; i < n; i++)
3656     {
3657       e = vat_json_array_add (&root);
3658       vat_json_init_object (e);
3659       r = &mp->entries[i];
3660       s =
3661         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3662                 r->nh_addr);
3663       vec_add1 (s, 0);
3664       vat_json_object_add_string_copy (e, "ip4", s);
3665       vec_free (s);
3666
3667       vat_json_object_add_uint (e, "fib_index",
3668                                 clib_net_to_host_u32 (r->fib_index));
3669       vat_json_object_add_uint (e, "nh_sw_if_index",
3670                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3671     }
3672
3673   vat_json_print (vam->ofp, &root);
3674   vat_json_free (&root);
3675
3676 end:
3677   vam->retval = retval;
3678   vam->result_ready = 1;
3679 }
3680
3681 static void
3682   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3683   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3684 {
3685   vat_main_t *vam = &vat_main;
3686   u32 i, n;
3687   int retval = clib_net_to_host_u32 (mp->retval);
3688
3689   if (retval)
3690     goto end;
3691
3692   n = clib_net_to_host_u32 (mp->count);
3693
3694   for (i = 0; i < n; i++)
3695     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3696
3697 end:
3698   vam->retval = retval;
3699   vam->result_ready = 1;
3700 }
3701
3702 static void
3703   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3704   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   vat_json_node_t root;
3708   u32 i, n;
3709   int retval = clib_net_to_host_u32 (mp->retval);
3710
3711   if (retval)
3712     goto end;
3713
3714   n = clib_net_to_host_u32 (mp->count);
3715   vat_json_init_array (&root);
3716
3717   for (i = 0; i < n; i++)
3718     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3719
3720   vat_json_print (vam->ofp, &root);
3721   vat_json_free (&root);
3722
3723 end:
3724   vam->retval = retval;
3725   vam->result_ready = 1;
3726 }
3727
3728 static void
3729   vl_api_one_ndp_entries_get_reply_t_handler
3730   (vl_api_one_ndp_entries_get_reply_t * mp)
3731 {
3732   vat_main_t *vam = &vat_main;
3733   u32 i, n;
3734   int retval = clib_net_to_host_u32 (mp->retval);
3735
3736   if (retval)
3737     goto end;
3738
3739   n = clib_net_to_host_u32 (mp->count);
3740
3741   for (i = 0; i < n; i++)
3742     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3743            format_ethernet_address, mp->entries[i].mac);
3744
3745 end:
3746   vam->retval = retval;
3747   vam->result_ready = 1;
3748 }
3749
3750 static void
3751   vl_api_one_ndp_entries_get_reply_t_handler_json
3752   (vl_api_one_ndp_entries_get_reply_t * mp)
3753 {
3754   u8 *s = 0;
3755   vat_main_t *vam = &vat_main;
3756   vat_json_node_t *e = 0, root;
3757   u32 i, n;
3758   int retval = clib_net_to_host_u32 (mp->retval);
3759   vl_api_one_ndp_entry_t *arp_entry;
3760
3761   if (retval)
3762     goto end;
3763
3764   n = clib_net_to_host_u32 (mp->count);
3765   vat_json_init_array (&root);
3766
3767   for (i = 0; i < n; i++)
3768     {
3769       e = vat_json_array_add (&root);
3770       arp_entry = &mp->entries[i];
3771
3772       vat_json_init_object (e);
3773       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3774       vec_add1 (s, 0);
3775
3776       vat_json_object_add_string_copy (e, "mac", s);
3777       vec_free (s);
3778
3779       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3780       vec_add1 (s, 0);
3781       vat_json_object_add_string_copy (e, "ip6", s);
3782       vec_free (s);
3783     }
3784
3785   vat_json_print (vam->ofp, &root);
3786   vat_json_free (&root);
3787
3788 end:
3789   vam->retval = retval;
3790   vam->result_ready = 1;
3791 }
3792
3793 static void
3794   vl_api_one_l2_arp_entries_get_reply_t_handler
3795   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3796 {
3797   vat_main_t *vam = &vat_main;
3798   u32 i, n;
3799   int retval = clib_net_to_host_u32 (mp->retval);
3800
3801   if (retval)
3802     goto end;
3803
3804   n = clib_net_to_host_u32 (mp->count);
3805
3806   for (i = 0; i < n; i++)
3807     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3808            format_ethernet_address, mp->entries[i].mac);
3809
3810 end:
3811   vam->retval = retval;
3812   vam->result_ready = 1;
3813 }
3814
3815 static void
3816   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3817   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3818 {
3819   u8 *s = 0;
3820   vat_main_t *vam = &vat_main;
3821   vat_json_node_t *e = 0, root;
3822   u32 i, n;
3823   int retval = clib_net_to_host_u32 (mp->retval);
3824   vl_api_one_l2_arp_entry_t *arp_entry;
3825
3826   if (retval)
3827     goto end;
3828
3829   n = clib_net_to_host_u32 (mp->count);
3830   vat_json_init_array (&root);
3831
3832   for (i = 0; i < n; i++)
3833     {
3834       e = vat_json_array_add (&root);
3835       arp_entry = &mp->entries[i];
3836
3837       vat_json_init_object (e);
3838       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3839       vec_add1 (s, 0);
3840
3841       vat_json_object_add_string_copy (e, "mac", s);
3842       vec_free (s);
3843
3844       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3845       vec_add1 (s, 0);
3846       vat_json_object_add_string_copy (e, "ip4", s);
3847       vec_free (s);
3848     }
3849
3850   vat_json_print (vam->ofp, &root);
3851   vat_json_free (&root);
3852
3853 end:
3854   vam->retval = retval;
3855   vam->result_ready = 1;
3856 }
3857
3858 static void
3859 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3860 {
3861   vat_main_t *vam = &vat_main;
3862   u32 i, n;
3863   int retval = clib_net_to_host_u32 (mp->retval);
3864
3865   if (retval)
3866     goto end;
3867
3868   n = clib_net_to_host_u32 (mp->count);
3869
3870   for (i = 0; i < n; i++)
3871     {
3872       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3873     }
3874
3875 end:
3876   vam->retval = retval;
3877   vam->result_ready = 1;
3878 }
3879
3880 static void
3881   vl_api_one_ndp_bd_get_reply_t_handler_json
3882   (vl_api_one_ndp_bd_get_reply_t * mp)
3883 {
3884   vat_main_t *vam = &vat_main;
3885   vat_json_node_t root;
3886   u32 i, n;
3887   int retval = clib_net_to_host_u32 (mp->retval);
3888
3889   if (retval)
3890     goto end;
3891
3892   n = clib_net_to_host_u32 (mp->count);
3893   vat_json_init_array (&root);
3894
3895   for (i = 0; i < n; i++)
3896     {
3897       vat_json_array_add_uint (&root,
3898                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3899     }
3900
3901   vat_json_print (vam->ofp, &root);
3902   vat_json_free (&root);
3903
3904 end:
3905   vam->retval = retval;
3906   vam->result_ready = 1;
3907 }
3908
3909 static void
3910   vl_api_one_l2_arp_bd_get_reply_t_handler
3911   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3912 {
3913   vat_main_t *vam = &vat_main;
3914   u32 i, n;
3915   int retval = clib_net_to_host_u32 (mp->retval);
3916
3917   if (retval)
3918     goto end;
3919
3920   n = clib_net_to_host_u32 (mp->count);
3921
3922   for (i = 0; i < n; i++)
3923     {
3924       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3925     }
3926
3927 end:
3928   vam->retval = retval;
3929   vam->result_ready = 1;
3930 }
3931
3932 static void
3933   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3934   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3935 {
3936   vat_main_t *vam = &vat_main;
3937   vat_json_node_t root;
3938   u32 i, n;
3939   int retval = clib_net_to_host_u32 (mp->retval);
3940
3941   if (retval)
3942     goto end;
3943
3944   n = clib_net_to_host_u32 (mp->count);
3945   vat_json_init_array (&root);
3946
3947   for (i = 0; i < n; i++)
3948     {
3949       vat_json_array_add_uint (&root,
3950                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3951     }
3952
3953   vat_json_print (vam->ofp, &root);
3954   vat_json_free (&root);
3955
3956 end:
3957   vam->retval = retval;
3958   vam->result_ready = 1;
3959 }
3960
3961 static void
3962   vl_api_one_adjacencies_get_reply_t_handler
3963   (vl_api_one_adjacencies_get_reply_t * mp)
3964 {
3965   vat_main_t *vam = &vat_main;
3966   u32 i, n;
3967   int retval = clib_net_to_host_u32 (mp->retval);
3968   vl_api_one_adjacency_t *a;
3969
3970   if (retval)
3971     goto end;
3972
3973   n = clib_net_to_host_u32 (mp->count);
3974
3975   for (i = 0; i < n; i++)
3976     {
3977       a = &mp->adjacencies[i];
3978       print (vam->ofp, "%U %40U",
3979              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3980              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3981     }
3982
3983 end:
3984   vam->retval = retval;
3985   vam->result_ready = 1;
3986 }
3987
3988 static void
3989   vl_api_one_adjacencies_get_reply_t_handler_json
3990   (vl_api_one_adjacencies_get_reply_t * mp)
3991 {
3992   u8 *s = 0;
3993   vat_main_t *vam = &vat_main;
3994   vat_json_node_t *e = 0, root;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997   vl_api_one_adjacency_t *a;
3998
3999   if (retval)
4000     goto end;
4001
4002   n = clib_net_to_host_u32 (mp->count);
4003   vat_json_init_array (&root);
4004
4005   for (i = 0; i < n; i++)
4006     {
4007       e = vat_json_array_add (&root);
4008       a = &mp->adjacencies[i];
4009
4010       vat_json_init_object (e);
4011       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4012                   a->leid_prefix_len);
4013       vec_add1 (s, 0);
4014       vat_json_object_add_string_copy (e, "leid", s);
4015       vec_free (s);
4016
4017       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4018                   a->reid_prefix_len);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "reid", s);
4021       vec_free (s);
4022     }
4023
4024   vat_json_print (vam->ofp, &root);
4025   vat_json_free (&root);
4026
4027 end:
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036
4037   print (vam->ofp, "%=20U",
4038          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4039          mp->ip_address);
4040 }
4041
4042 static void
4043   vl_api_one_map_server_details_t_handler_json
4044   (vl_api_one_map_server_details_t * mp)
4045 {
4046   vat_main_t *vam = &vat_main;
4047   vat_json_node_t *node = NULL;
4048   struct in6_addr ip6;
4049   struct in_addr ip4;
4050
4051   if (VAT_JSON_ARRAY != vam->json_tree.type)
4052     {
4053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4054       vat_json_init_array (&vam->json_tree);
4055     }
4056   node = vat_json_array_add (&vam->json_tree);
4057
4058   vat_json_init_object (node);
4059   if (mp->is_ipv6)
4060     {
4061       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4062       vat_json_object_add_ip6 (node, "map-server", ip6);
4063     }
4064   else
4065     {
4066       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4067       vat_json_object_add_ip4 (node, "map-server", ip4);
4068     }
4069 }
4070
4071 static void
4072 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4073                                            * mp)
4074 {
4075   vat_main_t *vam = &vat_main;
4076
4077   print (vam->ofp, "%=20U",
4078          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4079          mp->ip_address);
4080 }
4081
4082 static void
4083   vl_api_one_map_resolver_details_t_handler_json
4084   (vl_api_one_map_resolver_details_t * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087   vat_json_node_t *node = NULL;
4088   struct in6_addr ip6;
4089   struct in_addr ip4;
4090
4091   if (VAT_JSON_ARRAY != vam->json_tree.type)
4092     {
4093       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4094       vat_json_init_array (&vam->json_tree);
4095     }
4096   node = vat_json_array_add (&vam->json_tree);
4097
4098   vat_json_init_object (node);
4099   if (mp->is_ipv6)
4100     {
4101       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4102       vat_json_object_add_ip6 (node, "map resolver", ip6);
4103     }
4104   else
4105     {
4106       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4107       vat_json_object_add_ip4 (node, "map resolver", ip4);
4108     }
4109 }
4110
4111 static void
4112 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4113 {
4114   vat_main_t *vam = &vat_main;
4115   i32 retval = ntohl (mp->retval);
4116
4117   if (0 <= retval)
4118     {
4119       print (vam->ofp, "feature: %s\ngpe: %s",
4120              mp->feature_status ? "enabled" : "disabled",
4121              mp->gpe_status ? "enabled" : "disabled");
4122     }
4123
4124   vam->retval = retval;
4125   vam->result_ready = 1;
4126 }
4127
4128 static void
4129   vl_api_show_one_status_reply_t_handler_json
4130   (vl_api_show_one_status_reply_t * mp)
4131 {
4132   vat_main_t *vam = &vat_main;
4133   vat_json_node_t node;
4134   u8 *gpe_status = NULL;
4135   u8 *feature_status = NULL;
4136
4137   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4138   feature_status = format (0, "%s",
4139                            mp->feature_status ? "enabled" : "disabled");
4140   vec_add1 (gpe_status, 0);
4141   vec_add1 (feature_status, 0);
4142
4143   vat_json_init_object (&node);
4144   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4145   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4146
4147   vec_free (gpe_status);
4148   vec_free (feature_status);
4149
4150   vat_json_print (vam->ofp, &node);
4151   vat_json_free (&node);
4152
4153   vam->retval = ntohl (mp->retval);
4154   vam->result_ready = 1;
4155 }
4156
4157 static void
4158   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4159   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4160 {
4161   vat_main_t *vam = &vat_main;
4162   i32 retval = ntohl (mp->retval);
4163
4164   if (retval >= 0)
4165     {
4166       print (vam->ofp, "%=20s", mp->locator_set_name);
4167     }
4168
4169   vam->retval = retval;
4170   vam->result_ready = 1;
4171 }
4172
4173 static void
4174   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4175   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4176 {
4177   vat_main_t *vam = &vat_main;
4178   vat_json_node_t *node = NULL;
4179
4180   if (VAT_JSON_ARRAY != vam->json_tree.type)
4181     {
4182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4183       vat_json_init_array (&vam->json_tree);
4184     }
4185   node = vat_json_array_add (&vam->json_tree);
4186
4187   vat_json_init_object (node);
4188   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4189
4190   vat_json_print (vam->ofp, node);
4191   vat_json_free (node);
4192
4193   vam->retval = ntohl (mp->retval);
4194   vam->result_ready = 1;
4195 }
4196
4197 static u8 *
4198 format_lisp_map_request_mode (u8 * s, va_list * args)
4199 {
4200   u32 mode = va_arg (*args, u32);
4201
4202   switch (mode)
4203     {
4204     case 0:
4205       return format (0, "dst-only");
4206     case 1:
4207       return format (0, "src-dst");
4208     }
4209   return 0;
4210 }
4211
4212 static void
4213   vl_api_show_one_map_request_mode_reply_t_handler
4214   (vl_api_show_one_map_request_mode_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   i32 retval = ntohl (mp->retval);
4218
4219   if (0 <= retval)
4220     {
4221       u32 mode = mp->mode;
4222       print (vam->ofp, "map_request_mode: %U",
4223              format_lisp_map_request_mode, mode);
4224     }
4225
4226   vam->retval = retval;
4227   vam->result_ready = 1;
4228 }
4229
4230 static void
4231   vl_api_show_one_map_request_mode_reply_t_handler_json
4232   (vl_api_show_one_map_request_mode_reply_t * mp)
4233 {
4234   vat_main_t *vam = &vat_main;
4235   vat_json_node_t node;
4236   u8 *s = 0;
4237   u32 mode;
4238
4239   mode = mp->mode;
4240   s = format (0, "%U", format_lisp_map_request_mode, mode);
4241   vec_add1 (s, 0);
4242
4243   vat_json_init_object (&node);
4244   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4245   vat_json_print (vam->ofp, &node);
4246   vat_json_free (&node);
4247
4248   vec_free (s);
4249   vam->retval = ntohl (mp->retval);
4250   vam->result_ready = 1;
4251 }
4252
4253 static void
4254   vl_api_one_show_xtr_mode_reply_t_handler
4255   (vl_api_one_show_xtr_mode_reply_t * mp)
4256 {
4257   vat_main_t *vam = &vat_main;
4258   i32 retval = ntohl (mp->retval);
4259
4260   if (0 <= retval)
4261     {
4262       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4263     }
4264
4265   vam->retval = retval;
4266   vam->result_ready = 1;
4267 }
4268
4269 static void
4270   vl_api_one_show_xtr_mode_reply_t_handler_json
4271   (vl_api_one_show_xtr_mode_reply_t * mp)
4272 {
4273   vat_main_t *vam = &vat_main;
4274   vat_json_node_t node;
4275   u8 *status = 0;
4276
4277   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4278   vec_add1 (status, 0);
4279
4280   vat_json_init_object (&node);
4281   vat_json_object_add_string_copy (&node, "status", status);
4282
4283   vec_free (status);
4284
4285   vat_json_print (vam->ofp, &node);
4286   vat_json_free (&node);
4287
4288   vam->retval = ntohl (mp->retval);
4289   vam->result_ready = 1;
4290 }
4291
4292 static void
4293   vl_api_one_show_pitr_mode_reply_t_handler
4294   (vl_api_one_show_pitr_mode_reply_t * mp)
4295 {
4296   vat_main_t *vam = &vat_main;
4297   i32 retval = ntohl (mp->retval);
4298
4299   if (0 <= retval)
4300     {
4301       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4302     }
4303
4304   vam->retval = retval;
4305   vam->result_ready = 1;
4306 }
4307
4308 static void
4309   vl_api_one_show_pitr_mode_reply_t_handler_json
4310   (vl_api_one_show_pitr_mode_reply_t * mp)
4311 {
4312   vat_main_t *vam = &vat_main;
4313   vat_json_node_t node;
4314   u8 *status = 0;
4315
4316   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4317   vec_add1 (status, 0);
4318
4319   vat_json_init_object (&node);
4320   vat_json_object_add_string_copy (&node, "status", status);
4321
4322   vec_free (status);
4323
4324   vat_json_print (vam->ofp, &node);
4325   vat_json_free (&node);
4326
4327   vam->retval = ntohl (mp->retval);
4328   vam->result_ready = 1;
4329 }
4330
4331 static void
4332   vl_api_one_show_petr_mode_reply_t_handler
4333   (vl_api_one_show_petr_mode_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (0 <= retval)
4339     {
4340       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4341     }
4342
4343   vam->retval = retval;
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_one_show_petr_mode_reply_t_handler_json
4349   (vl_api_one_show_petr_mode_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   vat_json_node_t node;
4353   u8 *status = 0;
4354
4355   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4356   vec_add1 (status, 0);
4357
4358   vat_json_init_object (&node);
4359   vat_json_object_add_string_copy (&node, "status", status);
4360
4361   vec_free (status);
4362
4363   vat_json_print (vam->ofp, &node);
4364   vat_json_free (&node);
4365
4366   vam->retval = ntohl (mp->retval);
4367   vam->result_ready = 1;
4368 }
4369
4370 static void
4371   vl_api_show_one_use_petr_reply_t_handler
4372   (vl_api_show_one_use_petr_reply_t * mp)
4373 {
4374   vat_main_t *vam = &vat_main;
4375   i32 retval = ntohl (mp->retval);
4376
4377   if (0 <= retval)
4378     {
4379       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4380       if (mp->status)
4381         {
4382           print (vam->ofp, "Proxy-ETR address; %U",
4383                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4384                  mp->address);
4385         }
4386     }
4387
4388   vam->retval = retval;
4389   vam->result_ready = 1;
4390 }
4391
4392 static void
4393   vl_api_show_one_use_petr_reply_t_handler_json
4394   (vl_api_show_one_use_petr_reply_t * mp)
4395 {
4396   vat_main_t *vam = &vat_main;
4397   vat_json_node_t node;
4398   u8 *status = 0;
4399   struct in_addr ip4;
4400   struct in6_addr ip6;
4401
4402   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4403   vec_add1 (status, 0);
4404
4405   vat_json_init_object (&node);
4406   vat_json_object_add_string_copy (&node, "status", status);
4407   if (mp->status)
4408     {
4409       if (mp->is_ip4)
4410         {
4411           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4412           vat_json_object_add_ip6 (&node, "address", ip6);
4413         }
4414       else
4415         {
4416           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4417           vat_json_object_add_ip4 (&node, "address", ip4);
4418         }
4419     }
4420
4421   vec_free (status);
4422
4423   vat_json_print (vam->ofp, &node);
4424   vat_json_free (&node);
4425
4426   vam->retval = ntohl (mp->retval);
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431   vl_api_show_one_nsh_mapping_reply_t_handler
4432   (vl_api_show_one_nsh_mapping_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   if (0 <= retval)
4438     {
4439       print (vam->ofp, "%-20s%-16s",
4440              mp->is_set ? "set" : "not-set",
4441              mp->is_set ? (char *) mp->locator_set_name : "");
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449   vl_api_show_one_nsh_mapping_reply_t_handler_json
4450   (vl_api_show_one_nsh_mapping_reply_t * mp)
4451 {
4452   vat_main_t *vam = &vat_main;
4453   vat_json_node_t node;
4454   u8 *status = 0;
4455
4456   status = format (0, "%s", mp->is_set ? "yes" : "no");
4457   vec_add1 (status, 0);
4458
4459   vat_json_init_object (&node);
4460   vat_json_object_add_string_copy (&node, "is_set", status);
4461   if (mp->is_set)
4462     {
4463       vat_json_object_add_string_copy (&node, "locator_set",
4464                                        mp->locator_set_name);
4465     }
4466
4467   vec_free (status);
4468
4469   vat_json_print (vam->ofp, &node);
4470   vat_json_free (&node);
4471
4472   vam->retval = ntohl (mp->retval);
4473   vam->result_ready = 1;
4474 }
4475
4476 static void
4477   vl_api_show_one_map_register_ttl_reply_t_handler
4478   (vl_api_show_one_map_register_ttl_reply_t * mp)
4479 {
4480   vat_main_t *vam = &vat_main;
4481   i32 retval = ntohl (mp->retval);
4482
4483   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4484
4485   if (0 <= retval)
4486     {
4487       print (vam->ofp, "ttl: %u", mp->ttl);
4488     }
4489
4490   vam->retval = retval;
4491   vam->result_ready = 1;
4492 }
4493
4494 static void
4495   vl_api_show_one_map_register_ttl_reply_t_handler_json
4496   (vl_api_show_one_map_register_ttl_reply_t * mp)
4497 {
4498   vat_main_t *vam = &vat_main;
4499   vat_json_node_t node;
4500
4501   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4502   vat_json_init_object (&node);
4503   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4504
4505   vat_json_print (vam->ofp, &node);
4506   vat_json_free (&node);
4507
4508   vam->retval = ntohl (mp->retval);
4509   vam->result_ready = 1;
4510 }
4511
4512 static void
4513 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4514 {
4515   vat_main_t *vam = &vat_main;
4516   i32 retval = ntohl (mp->retval);
4517
4518   if (0 <= retval)
4519     {
4520       print (vam->ofp, "%-20s%-16s",
4521              mp->status ? "enabled" : "disabled",
4522              mp->status ? (char *) mp->locator_set_name : "");
4523     }
4524
4525   vam->retval = retval;
4526   vam->result_ready = 1;
4527 }
4528
4529 static void
4530 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4531 {
4532   vat_main_t *vam = &vat_main;
4533   vat_json_node_t node;
4534   u8 *status = 0;
4535
4536   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4537   vec_add1 (status, 0);
4538
4539   vat_json_init_object (&node);
4540   vat_json_object_add_string_copy (&node, "status", status);
4541   if (mp->status)
4542     {
4543       vat_json_object_add_string_copy (&node, "locator_set",
4544                                        mp->locator_set_name);
4545     }
4546
4547   vec_free (status);
4548
4549   vat_json_print (vam->ofp, &node);
4550   vat_json_free (&node);
4551
4552   vam->retval = ntohl (mp->retval);
4553   vam->result_ready = 1;
4554 }
4555
4556 static u8 *
4557 format_policer_type (u8 * s, va_list * va)
4558 {
4559   u32 i = va_arg (*va, u32);
4560
4561   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4562     s = format (s, "1r2c");
4563   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4564     s = format (s, "1r3c");
4565   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4566     s = format (s, "2r3c-2698");
4567   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4568     s = format (s, "2r3c-4115");
4569   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4570     s = format (s, "2r3c-mef5cf1");
4571   else
4572     s = format (s, "ILLEGAL");
4573   return s;
4574 }
4575
4576 static u8 *
4577 format_policer_rate_type (u8 * s, va_list * va)
4578 {
4579   u32 i = va_arg (*va, u32);
4580
4581   if (i == SSE2_QOS_RATE_KBPS)
4582     s = format (s, "kbps");
4583   else if (i == SSE2_QOS_RATE_PPS)
4584     s = format (s, "pps");
4585   else
4586     s = format (s, "ILLEGAL");
4587   return s;
4588 }
4589
4590 static u8 *
4591 format_policer_round_type (u8 * s, va_list * va)
4592 {
4593   u32 i = va_arg (*va, u32);
4594
4595   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4596     s = format (s, "closest");
4597   else if (i == SSE2_QOS_ROUND_TO_UP)
4598     s = format (s, "up");
4599   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4600     s = format (s, "down");
4601   else
4602     s = format (s, "ILLEGAL");
4603   return s;
4604 }
4605
4606 static u8 *
4607 format_policer_action_type (u8 * s, va_list * va)
4608 {
4609   u32 i = va_arg (*va, u32);
4610
4611   if (i == SSE2_QOS_ACTION_DROP)
4612     s = format (s, "drop");
4613   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4614     s = format (s, "transmit");
4615   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4616     s = format (s, "mark-and-transmit");
4617   else
4618     s = format (s, "ILLEGAL");
4619   return s;
4620 }
4621
4622 static u8 *
4623 format_dscp (u8 * s, va_list * va)
4624 {
4625   u32 i = va_arg (*va, u32);
4626   char *t = 0;
4627
4628   switch (i)
4629     {
4630 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4631       foreach_vnet_dscp
4632 #undef _
4633     default:
4634       return format (s, "ILLEGAL");
4635     }
4636   s = format (s, "%s", t);
4637   return s;
4638 }
4639
4640 static void
4641 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4642 {
4643   vat_main_t *vam = &vat_main;
4644   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4645
4646   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4647     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4648   else
4649     conform_dscp_str = format (0, "");
4650
4651   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4652     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4653   else
4654     exceed_dscp_str = format (0, "");
4655
4656   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4657     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4658   else
4659     violate_dscp_str = format (0, "");
4660
4661   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4662          "rate type %U, round type %U, %s rate, %s color-aware, "
4663          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4664          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4665          "conform action %U%s, exceed action %U%s, violate action %U%s",
4666          mp->name,
4667          format_policer_type, mp->type,
4668          ntohl (mp->cir),
4669          ntohl (mp->eir),
4670          clib_net_to_host_u64 (mp->cb),
4671          clib_net_to_host_u64 (mp->eb),
4672          format_policer_rate_type, mp->rate_type,
4673          format_policer_round_type, mp->round_type,
4674          mp->single_rate ? "single" : "dual",
4675          mp->color_aware ? "is" : "not",
4676          ntohl (mp->cir_tokens_per_period),
4677          ntohl (mp->pir_tokens_per_period),
4678          ntohl (mp->scale),
4679          ntohl (mp->current_limit),
4680          ntohl (mp->current_bucket),
4681          ntohl (mp->extended_limit),
4682          ntohl (mp->extended_bucket),
4683          clib_net_to_host_u64 (mp->last_update_time),
4684          format_policer_action_type, mp->conform_action_type,
4685          conform_dscp_str,
4686          format_policer_action_type, mp->exceed_action_type,
4687          exceed_dscp_str,
4688          format_policer_action_type, mp->violate_action_type,
4689          violate_dscp_str);
4690
4691   vec_free (conform_dscp_str);
4692   vec_free (exceed_dscp_str);
4693   vec_free (violate_dscp_str);
4694 }
4695
4696 static void vl_api_policer_details_t_handler_json
4697   (vl_api_policer_details_t * mp)
4698 {
4699   vat_main_t *vam = &vat_main;
4700   vat_json_node_t *node;
4701   u8 *rate_type_str, *round_type_str, *type_str;
4702   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4703
4704   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4705   round_type_str =
4706     format (0, "%U", format_policer_round_type, mp->round_type);
4707   type_str = format (0, "%U", format_policer_type, mp->type);
4708   conform_action_str = format (0, "%U", format_policer_action_type,
4709                                mp->conform_action_type);
4710   exceed_action_str = format (0, "%U", format_policer_action_type,
4711                               mp->exceed_action_type);
4712   violate_action_str = format (0, "%U", format_policer_action_type,
4713                                mp->violate_action_type);
4714
4715   if (VAT_JSON_ARRAY != vam->json_tree.type)
4716     {
4717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4718       vat_json_init_array (&vam->json_tree);
4719     }
4720   node = vat_json_array_add (&vam->json_tree);
4721
4722   vat_json_init_object (node);
4723   vat_json_object_add_string_copy (node, "name", mp->name);
4724   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4725   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4726   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4727   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4728   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4729   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4730   vat_json_object_add_string_copy (node, "type", type_str);
4731   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4732   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4733   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4734   vat_json_object_add_uint (node, "cir_tokens_per_period",
4735                             ntohl (mp->cir_tokens_per_period));
4736   vat_json_object_add_uint (node, "eir_tokens_per_period",
4737                             ntohl (mp->pir_tokens_per_period));
4738   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4739   vat_json_object_add_uint (node, "current_bucket",
4740                             ntohl (mp->current_bucket));
4741   vat_json_object_add_uint (node, "extended_limit",
4742                             ntohl (mp->extended_limit));
4743   vat_json_object_add_uint (node, "extended_bucket",
4744                             ntohl (mp->extended_bucket));
4745   vat_json_object_add_uint (node, "last_update_time",
4746                             ntohl (mp->last_update_time));
4747   vat_json_object_add_string_copy (node, "conform_action",
4748                                    conform_action_str);
4749   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4750     {
4751       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4752       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4753       vec_free (dscp_str);
4754     }
4755   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4756   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4757     {
4758       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4759       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4760       vec_free (dscp_str);
4761     }
4762   vat_json_object_add_string_copy (node, "violate_action",
4763                                    violate_action_str);
4764   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4765     {
4766       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4767       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4768       vec_free (dscp_str);
4769     }
4770
4771   vec_free (rate_type_str);
4772   vec_free (round_type_str);
4773   vec_free (type_str);
4774   vec_free (conform_action_str);
4775   vec_free (exceed_action_str);
4776   vec_free (violate_action_str);
4777 }
4778
4779 static void
4780 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4781                                            mp)
4782 {
4783   vat_main_t *vam = &vat_main;
4784   int i, count = ntohl (mp->count);
4785
4786   if (count > 0)
4787     print (vam->ofp, "classify table ids (%d) : ", count);
4788   for (i = 0; i < count; i++)
4789     {
4790       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4791       print (vam->ofp, (i < count - 1) ? "," : "");
4792     }
4793   vam->retval = ntohl (mp->retval);
4794   vam->result_ready = 1;
4795 }
4796
4797 static void
4798   vl_api_classify_table_ids_reply_t_handler_json
4799   (vl_api_classify_table_ids_reply_t * mp)
4800 {
4801   vat_main_t *vam = &vat_main;
4802   int i, count = ntohl (mp->count);
4803
4804   if (count > 0)
4805     {
4806       vat_json_node_t node;
4807
4808       vat_json_init_object (&node);
4809       for (i = 0; i < count; i++)
4810         {
4811           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4812         }
4813       vat_json_print (vam->ofp, &node);
4814       vat_json_free (&node);
4815     }
4816   vam->retval = ntohl (mp->retval);
4817   vam->result_ready = 1;
4818 }
4819
4820 static void
4821   vl_api_classify_table_by_interface_reply_t_handler
4822   (vl_api_classify_table_by_interface_reply_t * mp)
4823 {
4824   vat_main_t *vam = &vat_main;
4825   u32 table_id;
4826
4827   table_id = ntohl (mp->l2_table_id);
4828   if (table_id != ~0)
4829     print (vam->ofp, "l2 table id : %d", table_id);
4830   else
4831     print (vam->ofp, "l2 table id : No input ACL tables configured");
4832   table_id = ntohl (mp->ip4_table_id);
4833   if (table_id != ~0)
4834     print (vam->ofp, "ip4 table id : %d", table_id);
4835   else
4836     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4837   table_id = ntohl (mp->ip6_table_id);
4838   if (table_id != ~0)
4839     print (vam->ofp, "ip6 table id : %d", table_id);
4840   else
4841     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4842   vam->retval = ntohl (mp->retval);
4843   vam->result_ready = 1;
4844 }
4845
4846 static void
4847   vl_api_classify_table_by_interface_reply_t_handler_json
4848   (vl_api_classify_table_by_interface_reply_t * mp)
4849 {
4850   vat_main_t *vam = &vat_main;
4851   vat_json_node_t node;
4852
4853   vat_json_init_object (&node);
4854
4855   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4856   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4857   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4858
4859   vat_json_print (vam->ofp, &node);
4860   vat_json_free (&node);
4861
4862   vam->retval = ntohl (mp->retval);
4863   vam->result_ready = 1;
4864 }
4865
4866 static void vl_api_policer_add_del_reply_t_handler
4867   (vl_api_policer_add_del_reply_t * mp)
4868 {
4869   vat_main_t *vam = &vat_main;
4870   i32 retval = ntohl (mp->retval);
4871   if (vam->async_mode)
4872     {
4873       vam->async_errors += (retval < 0);
4874     }
4875   else
4876     {
4877       vam->retval = retval;
4878       vam->result_ready = 1;
4879       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4880         /*
4881          * Note: this is just barely thread-safe, depends on
4882          * the main thread spinning waiting for an answer...
4883          */
4884         errmsg ("policer index %d", ntohl (mp->policer_index));
4885     }
4886 }
4887
4888 static void vl_api_policer_add_del_reply_t_handler_json
4889   (vl_api_policer_add_del_reply_t * mp)
4890 {
4891   vat_main_t *vam = &vat_main;
4892   vat_json_node_t node;
4893
4894   vat_json_init_object (&node);
4895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4896   vat_json_object_add_uint (&node, "policer_index",
4897                             ntohl (mp->policer_index));
4898
4899   vat_json_print (vam->ofp, &node);
4900   vat_json_free (&node);
4901
4902   vam->retval = ntohl (mp->retval);
4903   vam->result_ready = 1;
4904 }
4905
4906 /* Format hex dump. */
4907 u8 *
4908 format_hex_bytes (u8 * s, va_list * va)
4909 {
4910   u8 *bytes = va_arg (*va, u8 *);
4911   int n_bytes = va_arg (*va, int);
4912   uword i;
4913
4914   /* Print short or long form depending on byte count. */
4915   uword short_form = n_bytes <= 32;
4916   u32 indent = format_get_indent (s);
4917
4918   if (n_bytes == 0)
4919     return s;
4920
4921   for (i = 0; i < n_bytes; i++)
4922     {
4923       if (!short_form && (i % 32) == 0)
4924         s = format (s, "%08x: ", i);
4925       s = format (s, "%02x", bytes[i]);
4926       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4927         s = format (s, "\n%U", format_white_space, indent);
4928     }
4929
4930   return s;
4931 }
4932
4933 static void
4934 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4935                                             * mp)
4936 {
4937   vat_main_t *vam = &vat_main;
4938   i32 retval = ntohl (mp->retval);
4939   if (retval == 0)
4940     {
4941       print (vam->ofp, "classify table info :");
4942       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4943              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4944              ntohl (mp->miss_next_index));
4945       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4946              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4947              ntohl (mp->match_n_vectors));
4948       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4949              ntohl (mp->mask_length));
4950     }
4951   vam->retval = retval;
4952   vam->result_ready = 1;
4953 }
4954
4955 static void
4956   vl_api_classify_table_info_reply_t_handler_json
4957   (vl_api_classify_table_info_reply_t * mp)
4958 {
4959   vat_main_t *vam = &vat_main;
4960   vat_json_node_t node;
4961
4962   i32 retval = ntohl (mp->retval);
4963   if (retval == 0)
4964     {
4965       vat_json_init_object (&node);
4966
4967       vat_json_object_add_int (&node, "sessions",
4968                                ntohl (mp->active_sessions));
4969       vat_json_object_add_int (&node, "nexttbl",
4970                                ntohl (mp->next_table_index));
4971       vat_json_object_add_int (&node, "nextnode",
4972                                ntohl (mp->miss_next_index));
4973       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4974       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4975       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4976       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4977                       ntohl (mp->mask_length), 0);
4978       vat_json_object_add_string_copy (&node, "mask", s);
4979
4980       vat_json_print (vam->ofp, &node);
4981       vat_json_free (&node);
4982     }
4983   vam->retval = ntohl (mp->retval);
4984   vam->result_ready = 1;
4985 }
4986
4987 static void
4988 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4989                                            mp)
4990 {
4991   vat_main_t *vam = &vat_main;
4992
4993   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4994          ntohl (mp->hit_next_index), ntohl (mp->advance),
4995          ntohl (mp->opaque_index));
4996   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4997          ntohl (mp->match_length));
4998 }
4999
5000 static void
5001   vl_api_classify_session_details_t_handler_json
5002   (vl_api_classify_session_details_t * mp)
5003 {
5004   vat_main_t *vam = &vat_main;
5005   vat_json_node_t *node = NULL;
5006
5007   if (VAT_JSON_ARRAY != vam->json_tree.type)
5008     {
5009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5010       vat_json_init_array (&vam->json_tree);
5011     }
5012   node = vat_json_array_add (&vam->json_tree);
5013
5014   vat_json_init_object (node);
5015   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5016   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5017   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5018   u8 *s =
5019     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5020             0);
5021   vat_json_object_add_string_copy (node, "match", s);
5022 }
5023
5024 static void vl_api_pg_create_interface_reply_t_handler
5025   (vl_api_pg_create_interface_reply_t * mp)
5026 {
5027   vat_main_t *vam = &vat_main;
5028
5029   vam->retval = ntohl (mp->retval);
5030   vam->result_ready = 1;
5031 }
5032
5033 static void vl_api_pg_create_interface_reply_t_handler_json
5034   (vl_api_pg_create_interface_reply_t * mp)
5035 {
5036   vat_main_t *vam = &vat_main;
5037   vat_json_node_t node;
5038
5039   i32 retval = ntohl (mp->retval);
5040   if (retval == 0)
5041     {
5042       vat_json_init_object (&node);
5043
5044       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5045
5046       vat_json_print (vam->ofp, &node);
5047       vat_json_free (&node);
5048     }
5049   vam->retval = ntohl (mp->retval);
5050   vam->result_ready = 1;
5051 }
5052
5053 static void vl_api_policer_classify_details_t_handler
5054   (vl_api_policer_classify_details_t * mp)
5055 {
5056   vat_main_t *vam = &vat_main;
5057
5058   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5059          ntohl (mp->table_index));
5060 }
5061
5062 static void vl_api_policer_classify_details_t_handler_json
5063   (vl_api_policer_classify_details_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   vat_json_node_t *node;
5067
5068   if (VAT_JSON_ARRAY != vam->json_tree.type)
5069     {
5070       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5071       vat_json_init_array (&vam->json_tree);
5072     }
5073   node = vat_json_array_add (&vam->json_tree);
5074
5075   vat_json_init_object (node);
5076   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5077   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5078 }
5079
5080 static void vl_api_flow_classify_details_t_handler
5081   (vl_api_flow_classify_details_t * mp)
5082 {
5083   vat_main_t *vam = &vat_main;
5084
5085   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5086          ntohl (mp->table_index));
5087 }
5088
5089 static void vl_api_flow_classify_details_t_handler_json
5090   (vl_api_flow_classify_details_t * mp)
5091 {
5092   vat_main_t *vam = &vat_main;
5093   vat_json_node_t *node;
5094
5095   if (VAT_JSON_ARRAY != vam->json_tree.type)
5096     {
5097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5098       vat_json_init_array (&vam->json_tree);
5099     }
5100   node = vat_json_array_add (&vam->json_tree);
5101
5102   vat_json_init_object (node);
5103   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5104   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5105 }
5106
5107 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5108 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5109 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5110 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5111 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5112 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5113 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5114 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5115 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5116 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5117
5118 /*
5119  * Generate boilerplate reply handlers, which
5120  * dig the return value out of the xxx_reply_t API message,
5121  * stick it into vam->retval, and set vam->result_ready
5122  *
5123  * Could also do this by pointing N message decode slots at
5124  * a single function, but that could break in subtle ways.
5125  */
5126
5127 #define foreach_standard_reply_retval_handler           \
5128 _(sw_interface_set_flags_reply)                         \
5129 _(sw_interface_add_del_address_reply)                   \
5130 _(sw_interface_set_rx_mode_reply)                       \
5131 _(sw_interface_set_rx_placement_reply)                  \
5132 _(sw_interface_set_table_reply)                         \
5133 _(sw_interface_set_mpls_enable_reply)                   \
5134 _(sw_interface_set_vpath_reply)                         \
5135 _(sw_interface_set_vxlan_bypass_reply)                  \
5136 _(sw_interface_set_geneve_bypass_reply)                 \
5137 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5138 _(sw_interface_set_l2_bridge_reply)                     \
5139 _(bridge_domain_add_del_reply)                          \
5140 _(sw_interface_set_l2_xconnect_reply)                   \
5141 _(l2fib_add_del_reply)                                  \
5142 _(l2fib_flush_int_reply)                                \
5143 _(l2fib_flush_bd_reply)                                 \
5144 _(ip_route_add_del_reply)                               \
5145 _(ip_table_add_del_reply)                               \
5146 _(ip_mroute_add_del_reply)                              \
5147 _(mpls_route_add_del_reply)                             \
5148 _(mpls_table_add_del_reply)                             \
5149 _(mpls_ip_bind_unbind_reply)                            \
5150 _(bier_route_add_del_reply)                             \
5151 _(bier_table_add_del_reply)                             \
5152 _(proxy_arp_add_del_reply)                              \
5153 _(proxy_arp_intfc_enable_disable_reply)                 \
5154 _(sw_interface_set_unnumbered_reply)                    \
5155 _(ip_neighbor_add_del_reply)                            \
5156 _(reset_fib_reply)                                      \
5157 _(dhcp_proxy_config_reply)                              \
5158 _(dhcp_proxy_set_vss_reply)                             \
5159 _(dhcp_client_config_reply)                             \
5160 _(set_ip_flow_hash_reply)                               \
5161 _(sw_interface_ip6_enable_disable_reply)                \
5162 _(ip6nd_proxy_add_del_reply)                            \
5163 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5164 _(sw_interface_ip6nd_ra_config_reply)                   \
5165 _(set_arp_neighbor_limit_reply)                         \
5166 _(l2_patch_add_del_reply)                               \
5167 _(sr_mpls_policy_add_reply)                             \
5168 _(sr_mpls_policy_mod_reply)                             \
5169 _(sr_mpls_policy_del_reply)                             \
5170 _(sr_policy_add_reply)                                  \
5171 _(sr_policy_mod_reply)                                  \
5172 _(sr_policy_del_reply)                                  \
5173 _(sr_localsid_add_del_reply)                            \
5174 _(sr_steering_add_del_reply)                            \
5175 _(classify_add_del_session_reply)                       \
5176 _(classify_set_interface_ip_table_reply)                \
5177 _(classify_set_interface_l2_tables_reply)               \
5178 _(l2tpv3_set_tunnel_cookies_reply)                      \
5179 _(l2tpv3_interface_enable_disable_reply)                \
5180 _(l2tpv3_set_lookup_key_reply)                          \
5181 _(l2_fib_clear_table_reply)                             \
5182 _(l2_interface_efp_filter_reply)                        \
5183 _(l2_interface_vlan_tag_rewrite_reply)                  \
5184 _(modify_vhost_user_if_reply)                           \
5185 _(delete_vhost_user_if_reply)                           \
5186 _(ip_probe_neighbor_reply)                              \
5187 _(ip_scan_neighbor_enable_disable_reply)                \
5188 _(want_ip4_arp_events_reply)                            \
5189 _(want_ip6_nd_events_reply)                             \
5190 _(want_l2_macs_events_reply)                            \
5191 _(input_acl_set_interface_reply)                        \
5192 _(ipsec_spd_add_del_reply)                              \
5193 _(ipsec_interface_add_del_spd_reply)                    \
5194 _(ipsec_spd_entry_add_del_reply)                        \
5195 _(ipsec_sad_entry_add_del_reply)                        \
5196 _(ipsec_tunnel_if_add_del_reply)                        \
5197 _(ipsec_tunnel_if_set_sa_reply)                         \
5198 _(delete_loopback_reply)                                \
5199 _(bd_ip_mac_add_del_reply)                              \
5200 _(bd_ip_mac_flush_reply)                                \
5201 _(want_interface_events_reply)                          \
5202 _(cop_interface_enable_disable_reply)                   \
5203 _(cop_whitelist_enable_disable_reply)                   \
5204 _(sw_interface_clear_stats_reply)                       \
5205 _(ioam_enable_reply)                                    \
5206 _(ioam_disable_reply)                                   \
5207 _(one_add_del_locator_reply)                            \
5208 _(one_add_del_local_eid_reply)                          \
5209 _(one_add_del_remote_mapping_reply)                     \
5210 _(one_add_del_adjacency_reply)                          \
5211 _(one_add_del_map_resolver_reply)                       \
5212 _(one_add_del_map_server_reply)                         \
5213 _(one_enable_disable_reply)                             \
5214 _(one_rloc_probe_enable_disable_reply)                  \
5215 _(one_map_register_enable_disable_reply)                \
5216 _(one_map_register_set_ttl_reply)                       \
5217 _(one_set_transport_protocol_reply)                     \
5218 _(one_map_register_fallback_threshold_reply)            \
5219 _(one_pitr_set_locator_set_reply)                       \
5220 _(one_map_request_mode_reply)                           \
5221 _(one_add_del_map_request_itr_rlocs_reply)              \
5222 _(one_eid_table_add_del_map_reply)                      \
5223 _(one_use_petr_reply)                                   \
5224 _(one_stats_enable_disable_reply)                       \
5225 _(one_add_del_l2_arp_entry_reply)                       \
5226 _(one_add_del_ndp_entry_reply)                          \
5227 _(one_stats_flush_reply)                                \
5228 _(one_enable_disable_xtr_mode_reply)                    \
5229 _(one_enable_disable_pitr_mode_reply)                   \
5230 _(one_enable_disable_petr_mode_reply)                   \
5231 _(gpe_enable_disable_reply)                             \
5232 _(gpe_set_encap_mode_reply)                             \
5233 _(gpe_add_del_iface_reply)                              \
5234 _(gpe_add_del_native_fwd_rpath_reply)                   \
5235 _(af_packet_delete_reply)                               \
5236 _(policer_classify_set_interface_reply)                 \
5237 _(netmap_create_reply)                                  \
5238 _(netmap_delete_reply)                                  \
5239 _(set_ipfix_exporter_reply)                             \
5240 _(set_ipfix_classify_stream_reply)                      \
5241 _(ipfix_classify_table_add_del_reply)                   \
5242 _(flow_classify_set_interface_reply)                    \
5243 _(sw_interface_span_enable_disable_reply)               \
5244 _(pg_capture_reply)                                     \
5245 _(pg_enable_disable_reply)                              \
5246 _(ip_source_and_port_range_check_add_del_reply)         \
5247 _(ip_source_and_port_range_check_interface_add_del_reply)\
5248 _(delete_subif_reply)                                   \
5249 _(l2_interface_pbb_tag_rewrite_reply)                   \
5250 _(set_punt_reply)                                       \
5251 _(feature_enable_disable_reply)                         \
5252 _(sw_interface_tag_add_del_reply)                       \
5253 _(hw_interface_set_mtu_reply)                           \
5254 _(p2p_ethernet_add_reply)                               \
5255 _(p2p_ethernet_del_reply)                               \
5256 _(lldp_config_reply)                                    \
5257 _(sw_interface_set_lldp_reply)                          \
5258 _(tcp_configure_src_addresses_reply)                    \
5259 _(dns_enable_disable_reply)                             \
5260 _(dns_name_server_add_del_reply)                        \
5261 _(session_rule_add_del_reply)                           \
5262 _(ip_container_proxy_add_del_reply)                     \
5263 _(output_acl_set_interface_reply)                       \
5264 _(qos_record_enable_disable_reply)
5265
5266 #define _(n)                                    \
5267     static void vl_api_##n##_t_handler          \
5268     (vl_api_##n##_t * mp)                       \
5269     {                                           \
5270         vat_main_t * vam = &vat_main;           \
5271         i32 retval = ntohl(mp->retval);         \
5272         if (vam->async_mode) {                  \
5273             vam->async_errors += (retval < 0);  \
5274         } else {                                \
5275             vam->retval = retval;               \
5276             vam->result_ready = 1;              \
5277         }                                       \
5278     }
5279 foreach_standard_reply_retval_handler;
5280 #undef _
5281
5282 #define _(n)                                    \
5283     static void vl_api_##n##_t_handler_json     \
5284     (vl_api_##n##_t * mp)                       \
5285     {                                           \
5286         vat_main_t * vam = &vat_main;           \
5287         vat_json_node_t node;                   \
5288         vat_json_init_object(&node);            \
5289         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5290         vat_json_print(vam->ofp, &node);        \
5291         vam->retval = ntohl(mp->retval);        \
5292         vam->result_ready = 1;                  \
5293     }
5294 foreach_standard_reply_retval_handler;
5295 #undef _
5296
5297 /*
5298  * Table of message reply handlers, must include boilerplate handlers
5299  * we just generated
5300  */
5301
5302 #define foreach_vpe_api_reply_msg                                       \
5303 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5304 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5305 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5306 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5307 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5308 _(CLI_REPLY, cli_reply)                                                 \
5309 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5310 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5311   sw_interface_add_del_address_reply)                                   \
5312 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5313 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5314 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5315 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5316 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5317 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5318 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5319 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5320 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5321 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5322   sw_interface_set_l2_xconnect_reply)                                   \
5323 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5324   sw_interface_set_l2_bridge_reply)                                     \
5325 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5326 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5327 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5328 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5329 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5330 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5331 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5332 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5333 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5334 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5335 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5336 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5337 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5338 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5339 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5340 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5341 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5342 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5343 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5344 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5345 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5346 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5347 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5348 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5349 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5350 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5351 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5352 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5353 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5354 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5355   proxy_arp_intfc_enable_disable_reply)                                 \
5356 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5357 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5358   sw_interface_set_unnumbered_reply)                                    \
5359 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5360 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5361 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5362 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5363 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5364 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5365 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5366 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5367 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5368 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5369   sw_interface_ip6_enable_disable_reply)                                \
5370 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5371 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5372 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5373   sw_interface_ip6nd_ra_prefix_reply)                                   \
5374 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5375   sw_interface_ip6nd_ra_config_reply)                                   \
5376 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5377 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5378 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5379 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5380 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5381 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5382 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5383 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5384 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5385 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5386 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5387 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5388 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5389 classify_set_interface_ip_table_reply)                                  \
5390 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5391   classify_set_interface_l2_tables_reply)                               \
5392 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5393 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5394 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5395 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5396 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5397   l2tpv3_interface_enable_disable_reply)                                \
5398 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5399 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5400 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5401 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5402 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5403 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5404 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5405 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5406 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5407 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5408 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5409 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5410 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5411 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5412 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5413 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5414 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5415 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5416 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5417 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5418 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5419 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5420 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5421 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5422 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5423 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5424 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5425 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5426 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5427 _(L2_MACS_EVENT, l2_macs_event)                                         \
5428 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5429 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5430 _(IP_DETAILS, ip_details)                                               \
5431 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5432 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5433 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5434 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5435 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5436 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5437 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5438 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5439 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5440 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5441 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5442 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5443 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5444 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5445 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5446 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5447 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5448 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5449 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5450 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5451 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5452 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5453 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5454 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5455 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5456 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5457 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5458 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5459 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5460   one_map_register_enable_disable_reply)                                \
5461 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5462 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5463 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5464 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5465   one_map_register_fallback_threshold_reply)                            \
5466 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5467   one_rloc_probe_enable_disable_reply)                                  \
5468 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5469 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5470 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5471 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5472 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5473 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5474 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5475 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5476 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5477 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5478 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5479 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5480 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5481 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5482 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5483 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5484   show_one_stats_enable_disable_reply)                                  \
5485 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5486 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5487 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5488 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5489 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5490 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5491 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5492 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5493   one_enable_disable_pitr_mode_reply)                                   \
5494 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5495   one_enable_disable_petr_mode_reply)                                   \
5496 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5497 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5498 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5499 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5500 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5501 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5502 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5503 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5504 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5505 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5506 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5507 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5508   gpe_add_del_native_fwd_rpath_reply)                                   \
5509 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5510   gpe_fwd_entry_path_details)                                           \
5511 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5512 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5513   one_add_del_map_request_itr_rlocs_reply)                              \
5514 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5515   one_get_map_request_itr_rlocs_reply)                                  \
5516 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5517 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5518 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5519 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5520 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5521 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5522   show_one_map_register_state_reply)                                    \
5523 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5524 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5525   show_one_map_register_fallback_threshold_reply)                       \
5526 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5527 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5528 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5529 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5530 _(POLICER_DETAILS, policer_details)                                     \
5531 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5532 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5533 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5534 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5535 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5536 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5537 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5538 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5539 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5540 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5541 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5542 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5543 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5544 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5545 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5546 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5547 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5548 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5549 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5550 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5551 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5552 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5553 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5554 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5555 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5556 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5557  ip_source_and_port_range_check_add_del_reply)                          \
5558 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5559  ip_source_and_port_range_check_interface_add_del_reply)                \
5560 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5561 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5562 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5563 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5564 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5565 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5566 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5567 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5568 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5569 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5570 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5571 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5572 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5573 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5574 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5575 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5576 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5577 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5578 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5579 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5580 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5581 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5582 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5583 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5584 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5585 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5586
5587 #define foreach_standalone_reply_msg                                    \
5588 _(SW_INTERFACE_EVENT, sw_interface_event)
5589
5590 typedef struct
5591 {
5592   u8 *name;
5593   u32 value;
5594 } name_sort_t;
5595
5596 #define STR_VTR_OP_CASE(op)     \
5597     case L2_VTR_ ## op:         \
5598         return "" # op;
5599
5600 static const char *
5601 str_vtr_op (u32 vtr_op)
5602 {
5603   switch (vtr_op)
5604     {
5605       STR_VTR_OP_CASE (DISABLED);
5606       STR_VTR_OP_CASE (PUSH_1);
5607       STR_VTR_OP_CASE (PUSH_2);
5608       STR_VTR_OP_CASE (POP_1);
5609       STR_VTR_OP_CASE (POP_2);
5610       STR_VTR_OP_CASE (TRANSLATE_1_1);
5611       STR_VTR_OP_CASE (TRANSLATE_1_2);
5612       STR_VTR_OP_CASE (TRANSLATE_2_1);
5613       STR_VTR_OP_CASE (TRANSLATE_2_2);
5614     }
5615
5616   return "UNKNOWN";
5617 }
5618
5619 static int
5620 dump_sub_interface_table (vat_main_t * vam)
5621 {
5622   const sw_interface_subif_t *sub = NULL;
5623
5624   if (vam->json_output)
5625     {
5626       clib_warning
5627         ("JSON output supported only for VPE API calls and dump_stats_table");
5628       return -99;
5629     }
5630
5631   print (vam->ofp,
5632          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5633          "Interface", "sw_if_index",
5634          "sub id", "dot1ad", "tags", "outer id",
5635          "inner id", "exact", "default", "outer any", "inner any");
5636
5637   vec_foreach (sub, vam->sw_if_subif_table)
5638   {
5639     print (vam->ofp,
5640            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5641            sub->interface_name,
5642            sub->sw_if_index,
5643            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5644            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5645            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5646            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5647     if (sub->vtr_op != L2_VTR_DISABLED)
5648       {
5649         print (vam->ofp,
5650                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5651                "tag1: %d tag2: %d ]",
5652                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5653                sub->vtr_tag1, sub->vtr_tag2);
5654       }
5655   }
5656
5657   return 0;
5658 }
5659
5660 static int
5661 name_sort_cmp (void *a1, void *a2)
5662 {
5663   name_sort_t *n1 = a1;
5664   name_sort_t *n2 = a2;
5665
5666   return strcmp ((char *) n1->name, (char *) n2->name);
5667 }
5668
5669 static int
5670 dump_interface_table (vat_main_t * vam)
5671 {
5672   hash_pair_t *p;
5673   name_sort_t *nses = 0, *ns;
5674
5675   if (vam->json_output)
5676     {
5677       clib_warning
5678         ("JSON output supported only for VPE API calls and dump_stats_table");
5679       return -99;
5680     }
5681
5682   /* *INDENT-OFF* */
5683   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5684   ({
5685     vec_add2 (nses, ns, 1);
5686     ns->name = (u8 *)(p->key);
5687     ns->value = (u32) p->value[0];
5688   }));
5689   /* *INDENT-ON* */
5690
5691   vec_sort_with_function (nses, name_sort_cmp);
5692
5693   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5694   vec_foreach (ns, nses)
5695   {
5696     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5697   }
5698   vec_free (nses);
5699   return 0;
5700 }
5701
5702 static int
5703 dump_ip_table (vat_main_t * vam, int is_ipv6)
5704 {
5705   const ip_details_t *det = NULL;
5706   const ip_address_details_t *address = NULL;
5707   u32 i = ~0;
5708
5709   print (vam->ofp, "%-12s", "sw_if_index");
5710
5711   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5712   {
5713     i++;
5714     if (!det->present)
5715       {
5716         continue;
5717       }
5718     print (vam->ofp, "%-12d", i);
5719     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5720     if (!det->addr)
5721       {
5722         continue;
5723       }
5724     vec_foreach (address, det->addr)
5725     {
5726       print (vam->ofp,
5727              "            %-30U%-13d",
5728              is_ipv6 ? format_ip6_address : format_ip4_address,
5729              address->ip, address->prefix_length);
5730     }
5731   }
5732
5733   return 0;
5734 }
5735
5736 static int
5737 dump_ipv4_table (vat_main_t * vam)
5738 {
5739   if (vam->json_output)
5740     {
5741       clib_warning
5742         ("JSON output supported only for VPE API calls and dump_stats_table");
5743       return -99;
5744     }
5745
5746   return dump_ip_table (vam, 0);
5747 }
5748
5749 static int
5750 dump_ipv6_table (vat_main_t * vam)
5751 {
5752   if (vam->json_output)
5753     {
5754       clib_warning
5755         ("JSON output supported only for VPE API calls and dump_stats_table");
5756       return -99;
5757     }
5758
5759   return dump_ip_table (vam, 1);
5760 }
5761
5762 /*
5763  * Pass CLI buffers directly in the CLI_INBAND API message,
5764  * instead of an additional shared memory area.
5765  */
5766 static int
5767 exec_inband (vat_main_t * vam)
5768 {
5769   vl_api_cli_inband_t *mp;
5770   unformat_input_t *i = vam->input;
5771   int ret;
5772
5773   if (vec_len (i->buffer) == 0)
5774     return -1;
5775
5776   if (vam->exec_mode == 0 && unformat (i, "mode"))
5777     {
5778       vam->exec_mode = 1;
5779       return 0;
5780     }
5781   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5782     {
5783       vam->exec_mode = 0;
5784       return 0;
5785     }
5786
5787   /*
5788    * In order for the CLI command to work, it
5789    * must be a vector ending in \n, not a C-string ending
5790    * in \n\0.
5791    */
5792   u32 len = vec_len (vam->input->buffer);
5793   M2 (CLI_INBAND, mp, len);
5794   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5795
5796   S (mp);
5797   W (ret);
5798   /* json responses may or may not include a useful reply... */
5799   if (vec_len (vam->cmd_reply))
5800     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5801   return ret;
5802 }
5803
5804 int
5805 exec (vat_main_t * vam)
5806 {
5807   return exec_inband (vam);
5808 }
5809
5810 static int
5811 api_create_loopback (vat_main_t * vam)
5812 {
5813   unformat_input_t *i = vam->input;
5814   vl_api_create_loopback_t *mp;
5815   vl_api_create_loopback_instance_t *mp_lbi;
5816   u8 mac_address[6];
5817   u8 mac_set = 0;
5818   u8 is_specified = 0;
5819   u32 user_instance = 0;
5820   int ret;
5821
5822   clib_memset (mac_address, 0, sizeof (mac_address));
5823
5824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5825     {
5826       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5827         mac_set = 1;
5828       if (unformat (i, "instance %d", &user_instance))
5829         is_specified = 1;
5830       else
5831         break;
5832     }
5833
5834   if (is_specified)
5835     {
5836       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5837       mp_lbi->is_specified = is_specified;
5838       if (is_specified)
5839         mp_lbi->user_instance = htonl (user_instance);
5840       if (mac_set)
5841         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5842       S (mp_lbi);
5843     }
5844   else
5845     {
5846       /* Construct the API message */
5847       M (CREATE_LOOPBACK, mp);
5848       if (mac_set)
5849         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5850       S (mp);
5851     }
5852
5853   W (ret);
5854   return ret;
5855 }
5856
5857 static int
5858 api_delete_loopback (vat_main_t * vam)
5859 {
5860   unformat_input_t *i = vam->input;
5861   vl_api_delete_loopback_t *mp;
5862   u32 sw_if_index = ~0;
5863   int ret;
5864
5865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5866     {
5867       if (unformat (i, "sw_if_index %d", &sw_if_index))
5868         ;
5869       else
5870         break;
5871     }
5872
5873   if (sw_if_index == ~0)
5874     {
5875       errmsg ("missing sw_if_index");
5876       return -99;
5877     }
5878
5879   /* Construct the API message */
5880   M (DELETE_LOOPBACK, mp);
5881   mp->sw_if_index = ntohl (sw_if_index);
5882
5883   S (mp);
5884   W (ret);
5885   return ret;
5886 }
5887
5888 static int
5889 api_want_interface_events (vat_main_t * vam)
5890 {
5891   unformat_input_t *i = vam->input;
5892   vl_api_want_interface_events_t *mp;
5893   int enable = -1;
5894   int ret;
5895
5896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5897     {
5898       if (unformat (i, "enable"))
5899         enable = 1;
5900       else if (unformat (i, "disable"))
5901         enable = 0;
5902       else
5903         break;
5904     }
5905
5906   if (enable == -1)
5907     {
5908       errmsg ("missing enable|disable");
5909       return -99;
5910     }
5911
5912   M (WANT_INTERFACE_EVENTS, mp);
5913   mp->enable_disable = enable;
5914
5915   vam->interface_event_display = enable;
5916
5917   S (mp);
5918   W (ret);
5919   return ret;
5920 }
5921
5922
5923 /* Note: non-static, called once to set up the initial intfc table */
5924 int
5925 api_sw_interface_dump (vat_main_t * vam)
5926 {
5927   vl_api_sw_interface_dump_t *mp;
5928   vl_api_control_ping_t *mp_ping;
5929   hash_pair_t *p;
5930   name_sort_t *nses = 0, *ns;
5931   sw_interface_subif_t *sub = NULL;
5932   int ret;
5933
5934   /* Toss the old name table */
5935   /* *INDENT-OFF* */
5936   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5937   ({
5938     vec_add2 (nses, ns, 1);
5939     ns->name = (u8 *)(p->key);
5940     ns->value = (u32) p->value[0];
5941   }));
5942   /* *INDENT-ON* */
5943
5944   hash_free (vam->sw_if_index_by_interface_name);
5945
5946   vec_foreach (ns, nses) vec_free (ns->name);
5947
5948   vec_free (nses);
5949
5950   vec_foreach (sub, vam->sw_if_subif_table)
5951   {
5952     vec_free (sub->interface_name);
5953   }
5954   vec_free (vam->sw_if_subif_table);
5955
5956   /* recreate the interface name hash table */
5957   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5958
5959   /*
5960    * Ask for all interface names. Otherwise, the epic catalog of
5961    * name filters becomes ridiculously long, and vat ends up needing
5962    * to be taught about new interface types.
5963    */
5964   M (SW_INTERFACE_DUMP, mp);
5965   S (mp);
5966
5967   /* Use a control ping for synchronization */
5968   MPING (CONTROL_PING, mp_ping);
5969   S (mp_ping);
5970
5971   W (ret);
5972   return ret;
5973 }
5974
5975 static int
5976 api_sw_interface_set_flags (vat_main_t * vam)
5977 {
5978   unformat_input_t *i = vam->input;
5979   vl_api_sw_interface_set_flags_t *mp;
5980   u32 sw_if_index;
5981   u8 sw_if_index_set = 0;
5982   u8 admin_up = 0;
5983   int ret;
5984
5985   /* Parse args required to build the message */
5986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5987     {
5988       if (unformat (i, "admin-up"))
5989         admin_up = 1;
5990       else if (unformat (i, "admin-down"))
5991         admin_up = 0;
5992       else
5993         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5994         sw_if_index_set = 1;
5995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5996         sw_if_index_set = 1;
5997       else
5998         break;
5999     }
6000
6001   if (sw_if_index_set == 0)
6002     {
6003       errmsg ("missing interface name or sw_if_index");
6004       return -99;
6005     }
6006
6007   /* Construct the API message */
6008   M (SW_INTERFACE_SET_FLAGS, mp);
6009   mp->sw_if_index = ntohl (sw_if_index);
6010   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
6011
6012   /* send it... */
6013   S (mp);
6014
6015   /* Wait for a reply, return the good/bad news... */
6016   W (ret);
6017   return ret;
6018 }
6019
6020 static int
6021 api_sw_interface_set_rx_mode (vat_main_t * vam)
6022 {
6023   unformat_input_t *i = vam->input;
6024   vl_api_sw_interface_set_rx_mode_t *mp;
6025   u32 sw_if_index;
6026   u8 sw_if_index_set = 0;
6027   int ret;
6028   u8 queue_id_valid = 0;
6029   u32 queue_id;
6030   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6031
6032   /* Parse args required to build the message */
6033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6034     {
6035       if (unformat (i, "queue %d", &queue_id))
6036         queue_id_valid = 1;
6037       else if (unformat (i, "polling"))
6038         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6039       else if (unformat (i, "interrupt"))
6040         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6041       else if (unformat (i, "adaptive"))
6042         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6043       else
6044         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6045         sw_if_index_set = 1;
6046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6047         sw_if_index_set = 1;
6048       else
6049         break;
6050     }
6051
6052   if (sw_if_index_set == 0)
6053     {
6054       errmsg ("missing interface name or sw_if_index");
6055       return -99;
6056     }
6057   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6058     {
6059       errmsg ("missing rx-mode");
6060       return -99;
6061     }
6062
6063   /* Construct the API message */
6064   M (SW_INTERFACE_SET_RX_MODE, mp);
6065   mp->sw_if_index = ntohl (sw_if_index);
6066   mp->mode = (vl_api_rx_mode_t) mode;
6067   mp->queue_id_valid = queue_id_valid;
6068   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6069
6070   /* send it... */
6071   S (mp);
6072
6073   /* Wait for a reply, return the good/bad news... */
6074   W (ret);
6075   return ret;
6076 }
6077
6078 static int
6079 api_sw_interface_set_rx_placement (vat_main_t * vam)
6080 {
6081   unformat_input_t *i = vam->input;
6082   vl_api_sw_interface_set_rx_placement_t *mp;
6083   u32 sw_if_index;
6084   u8 sw_if_index_set = 0;
6085   int ret;
6086   u8 is_main = 0;
6087   u32 queue_id, thread_index;
6088
6089   /* Parse args required to build the message */
6090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6091     {
6092       if (unformat (i, "queue %d", &queue_id))
6093         ;
6094       else if (unformat (i, "main"))
6095         is_main = 1;
6096       else if (unformat (i, "worker %d", &thread_index))
6097         ;
6098       else
6099         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6100         sw_if_index_set = 1;
6101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6102         sw_if_index_set = 1;
6103       else
6104         break;
6105     }
6106
6107   if (sw_if_index_set == 0)
6108     {
6109       errmsg ("missing interface name or sw_if_index");
6110       return -99;
6111     }
6112
6113   if (is_main)
6114     thread_index = 0;
6115   /* Construct the API message */
6116   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6117   mp->sw_if_index = ntohl (sw_if_index);
6118   mp->worker_id = ntohl (thread_index);
6119   mp->queue_id = ntohl (queue_id);
6120   mp->is_main = is_main;
6121
6122   /* send it... */
6123   S (mp);
6124   /* Wait for a reply, return the good/bad news... */
6125   W (ret);
6126   return ret;
6127 }
6128
6129 static void vl_api_sw_interface_rx_placement_details_t_handler
6130   (vl_api_sw_interface_rx_placement_details_t * mp)
6131 {
6132   vat_main_t *vam = &vat_main;
6133   u32 worker_id = ntohl (mp->worker_id);
6134
6135   print (vam->ofp,
6136          "\n%-11d %-11s %-6d %-5d %-9s",
6137          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6138          worker_id, ntohl (mp->queue_id),
6139          (mp->mode ==
6140           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6141 }
6142
6143 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6144   (vl_api_sw_interface_rx_placement_details_t * mp)
6145 {
6146   vat_main_t *vam = &vat_main;
6147   vat_json_node_t *node = NULL;
6148
6149   if (VAT_JSON_ARRAY != vam->json_tree.type)
6150     {
6151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6152       vat_json_init_array (&vam->json_tree);
6153     }
6154   node = vat_json_array_add (&vam->json_tree);
6155
6156   vat_json_init_object (node);
6157   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6158   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6159   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6160   vat_json_object_add_uint (node, "mode", mp->mode);
6161 }
6162
6163 static int
6164 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6165 {
6166   unformat_input_t *i = vam->input;
6167   vl_api_sw_interface_rx_placement_dump_t *mp;
6168   vl_api_control_ping_t *mp_ping;
6169   int ret;
6170   u32 sw_if_index;
6171   u8 sw_if_index_set = 0;
6172
6173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6174     {
6175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6176         sw_if_index_set++;
6177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6178         sw_if_index_set++;
6179       else
6180         break;
6181     }
6182
6183   print (vam->ofp,
6184          "\n%-11s %-11s %-6s %-5s %-4s",
6185          "sw_if_index", "main/worker", "thread", "queue", "mode");
6186
6187   /* Dump Interface rx placement */
6188   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6189
6190   if (sw_if_index_set)
6191     mp->sw_if_index = htonl (sw_if_index);
6192   else
6193     mp->sw_if_index = ~0;
6194
6195   S (mp);
6196
6197   /* Use a control ping for synchronization */
6198   MPING (CONTROL_PING, mp_ping);
6199   S (mp_ping);
6200
6201   W (ret);
6202   return ret;
6203 }
6204
6205 static int
6206 api_sw_interface_clear_stats (vat_main_t * vam)
6207 {
6208   unformat_input_t *i = vam->input;
6209   vl_api_sw_interface_clear_stats_t *mp;
6210   u32 sw_if_index;
6211   u8 sw_if_index_set = 0;
6212   int ret;
6213
6214   /* Parse args required to build the message */
6215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6216     {
6217       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6218         sw_if_index_set = 1;
6219       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6220         sw_if_index_set = 1;
6221       else
6222         break;
6223     }
6224
6225   /* Construct the API message */
6226   M (SW_INTERFACE_CLEAR_STATS, mp);
6227
6228   if (sw_if_index_set == 1)
6229     mp->sw_if_index = ntohl (sw_if_index);
6230   else
6231     mp->sw_if_index = ~0;
6232
6233   /* send it... */
6234   S (mp);
6235
6236   /* Wait for a reply, return the good/bad news... */
6237   W (ret);
6238   return ret;
6239 }
6240
6241 static int
6242 api_sw_interface_add_del_address (vat_main_t * vam)
6243 {
6244   unformat_input_t *i = vam->input;
6245   vl_api_sw_interface_add_del_address_t *mp;
6246   u32 sw_if_index;
6247   u8 sw_if_index_set = 0;
6248   u8 is_add = 1, del_all = 0;
6249   u32 address_length = 0;
6250   u8 v4_address_set = 0;
6251   u8 v6_address_set = 0;
6252   ip4_address_t v4address;
6253   ip6_address_t v6address;
6254   int ret;
6255
6256   /* Parse args required to build the message */
6257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6258     {
6259       if (unformat (i, "del-all"))
6260         del_all = 1;
6261       else if (unformat (i, "del"))
6262         is_add = 0;
6263       else
6264         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6265         sw_if_index_set = 1;
6266       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6267         sw_if_index_set = 1;
6268       else if (unformat (i, "%U/%d",
6269                          unformat_ip4_address, &v4address, &address_length))
6270         v4_address_set = 1;
6271       else if (unformat (i, "%U/%d",
6272                          unformat_ip6_address, &v6address, &address_length))
6273         v6_address_set = 1;
6274       else
6275         break;
6276     }
6277
6278   if (sw_if_index_set == 0)
6279     {
6280       errmsg ("missing interface name or sw_if_index");
6281       return -99;
6282     }
6283   if (v4_address_set && v6_address_set)
6284     {
6285       errmsg ("both v4 and v6 addresses set");
6286       return -99;
6287     }
6288   if (!v4_address_set && !v6_address_set && !del_all)
6289     {
6290       errmsg ("no addresses set");
6291       return -99;
6292     }
6293
6294   /* Construct the API message */
6295   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6296
6297   mp->sw_if_index = ntohl (sw_if_index);
6298   mp->is_add = is_add;
6299   mp->del_all = del_all;
6300   if (v6_address_set)
6301     {
6302       mp->prefix.address.af = ADDRESS_IP6;
6303       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6304     }
6305   else
6306     {
6307       mp->prefix.address.af = ADDRESS_IP4;
6308       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6309     }
6310   mp->prefix.len = address_length;
6311
6312   /* send it... */
6313   S (mp);
6314
6315   /* Wait for a reply, return good/bad news  */
6316   W (ret);
6317   return ret;
6318 }
6319
6320 static int
6321 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_sw_interface_set_mpls_enable_t *mp;
6325   u32 sw_if_index;
6326   u8 sw_if_index_set = 0;
6327   u8 enable = 1;
6328   int ret;
6329
6330   /* Parse args required to build the message */
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6334         sw_if_index_set = 1;
6335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6336         sw_if_index_set = 1;
6337       else if (unformat (i, "disable"))
6338         enable = 0;
6339       else if (unformat (i, "dis"))
6340         enable = 0;
6341       else
6342         break;
6343     }
6344
6345   if (sw_if_index_set == 0)
6346     {
6347       errmsg ("missing interface name or sw_if_index");
6348       return -99;
6349     }
6350
6351   /* Construct the API message */
6352   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6353
6354   mp->sw_if_index = ntohl (sw_if_index);
6355   mp->enable = enable;
6356
6357   /* send it... */
6358   S (mp);
6359
6360   /* Wait for a reply... */
6361   W (ret);
6362   return ret;
6363 }
6364
6365 static int
6366 api_sw_interface_set_table (vat_main_t * vam)
6367 {
6368   unformat_input_t *i = vam->input;
6369   vl_api_sw_interface_set_table_t *mp;
6370   u32 sw_if_index, vrf_id = 0;
6371   u8 sw_if_index_set = 0;
6372   u8 is_ipv6 = 0;
6373   int ret;
6374
6375   /* Parse args required to build the message */
6376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6377     {
6378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6379         sw_if_index_set = 1;
6380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6381         sw_if_index_set = 1;
6382       else if (unformat (i, "vrf %d", &vrf_id))
6383         ;
6384       else if (unformat (i, "ipv6"))
6385         is_ipv6 = 1;
6386       else
6387         break;
6388     }
6389
6390   if (sw_if_index_set == 0)
6391     {
6392       errmsg ("missing interface name or sw_if_index");
6393       return -99;
6394     }
6395
6396   /* Construct the API message */
6397   M (SW_INTERFACE_SET_TABLE, mp);
6398
6399   mp->sw_if_index = ntohl (sw_if_index);
6400   mp->is_ipv6 = is_ipv6;
6401   mp->vrf_id = ntohl (vrf_id);
6402
6403   /* send it... */
6404   S (mp);
6405
6406   /* Wait for a reply... */
6407   W (ret);
6408   return ret;
6409 }
6410
6411 static void vl_api_sw_interface_get_table_reply_t_handler
6412   (vl_api_sw_interface_get_table_reply_t * mp)
6413 {
6414   vat_main_t *vam = &vat_main;
6415
6416   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6417
6418   vam->retval = ntohl (mp->retval);
6419   vam->result_ready = 1;
6420
6421 }
6422
6423 static void vl_api_sw_interface_get_table_reply_t_handler_json
6424   (vl_api_sw_interface_get_table_reply_t * mp)
6425 {
6426   vat_main_t *vam = &vat_main;
6427   vat_json_node_t node;
6428
6429   vat_json_init_object (&node);
6430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6431   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6432
6433   vat_json_print (vam->ofp, &node);
6434   vat_json_free (&node);
6435
6436   vam->retval = ntohl (mp->retval);
6437   vam->result_ready = 1;
6438 }
6439
6440 static int
6441 api_sw_interface_get_table (vat_main_t * vam)
6442 {
6443   unformat_input_t *i = vam->input;
6444   vl_api_sw_interface_get_table_t *mp;
6445   u32 sw_if_index;
6446   u8 sw_if_index_set = 0;
6447   u8 is_ipv6 = 0;
6448   int ret;
6449
6450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6451     {
6452       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6453         sw_if_index_set = 1;
6454       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6455         sw_if_index_set = 1;
6456       else if (unformat (i, "ipv6"))
6457         is_ipv6 = 1;
6458       else
6459         break;
6460     }
6461
6462   if (sw_if_index_set == 0)
6463     {
6464       errmsg ("missing interface name or sw_if_index");
6465       return -99;
6466     }
6467
6468   M (SW_INTERFACE_GET_TABLE, mp);
6469   mp->sw_if_index = htonl (sw_if_index);
6470   mp->is_ipv6 = is_ipv6;
6471
6472   S (mp);
6473   W (ret);
6474   return ret;
6475 }
6476
6477 static int
6478 api_sw_interface_set_vpath (vat_main_t * vam)
6479 {
6480   unformat_input_t *i = vam->input;
6481   vl_api_sw_interface_set_vpath_t *mp;
6482   u32 sw_if_index = 0;
6483   u8 sw_if_index_set = 0;
6484   u8 is_enable = 0;
6485   int ret;
6486
6487   /* Parse args required to build the message */
6488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6489     {
6490       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6491         sw_if_index_set = 1;
6492       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6493         sw_if_index_set = 1;
6494       else if (unformat (i, "enable"))
6495         is_enable = 1;
6496       else if (unformat (i, "disable"))
6497         is_enable = 0;
6498       else
6499         break;
6500     }
6501
6502   if (sw_if_index_set == 0)
6503     {
6504       errmsg ("missing interface name or sw_if_index");
6505       return -99;
6506     }
6507
6508   /* Construct the API message */
6509   M (SW_INTERFACE_SET_VPATH, mp);
6510
6511   mp->sw_if_index = ntohl (sw_if_index);
6512   mp->enable = is_enable;
6513
6514   /* send it... */
6515   S (mp);
6516
6517   /* Wait for a reply... */
6518   W (ret);
6519   return ret;
6520 }
6521
6522 static int
6523 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6524 {
6525   unformat_input_t *i = vam->input;
6526   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6527   u32 sw_if_index = 0;
6528   u8 sw_if_index_set = 0;
6529   u8 is_enable = 1;
6530   u8 is_ipv6 = 0;
6531   int ret;
6532
6533   /* Parse args required to build the message */
6534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6535     {
6536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6537         sw_if_index_set = 1;
6538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6539         sw_if_index_set = 1;
6540       else if (unformat (i, "enable"))
6541         is_enable = 1;
6542       else if (unformat (i, "disable"))
6543         is_enable = 0;
6544       else if (unformat (i, "ip4"))
6545         is_ipv6 = 0;
6546       else if (unformat (i, "ip6"))
6547         is_ipv6 = 1;
6548       else
6549         break;
6550     }
6551
6552   if (sw_if_index_set == 0)
6553     {
6554       errmsg ("missing interface name or sw_if_index");
6555       return -99;
6556     }
6557
6558   /* Construct the API message */
6559   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6560
6561   mp->sw_if_index = ntohl (sw_if_index);
6562   mp->enable = is_enable;
6563   mp->is_ipv6 = is_ipv6;
6564
6565   /* send it... */
6566   S (mp);
6567
6568   /* Wait for a reply... */
6569   W (ret);
6570   return ret;
6571 }
6572
6573 static int
6574 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6575 {
6576   unformat_input_t *i = vam->input;
6577   vl_api_sw_interface_set_geneve_bypass_t *mp;
6578   u32 sw_if_index = 0;
6579   u8 sw_if_index_set = 0;
6580   u8 is_enable = 1;
6581   u8 is_ipv6 = 0;
6582   int ret;
6583
6584   /* Parse args required to build the message */
6585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6586     {
6587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6588         sw_if_index_set = 1;
6589       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6590         sw_if_index_set = 1;
6591       else if (unformat (i, "enable"))
6592         is_enable = 1;
6593       else if (unformat (i, "disable"))
6594         is_enable = 0;
6595       else if (unformat (i, "ip4"))
6596         is_ipv6 = 0;
6597       else if (unformat (i, "ip6"))
6598         is_ipv6 = 1;
6599       else
6600         break;
6601     }
6602
6603   if (sw_if_index_set == 0)
6604     {
6605       errmsg ("missing interface name or sw_if_index");
6606       return -99;
6607     }
6608
6609   /* Construct the API message */
6610   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6611
6612   mp->sw_if_index = ntohl (sw_if_index);
6613   mp->enable = is_enable;
6614   mp->is_ipv6 = is_ipv6;
6615
6616   /* send it... */
6617   S (mp);
6618
6619   /* Wait for a reply... */
6620   W (ret);
6621   return ret;
6622 }
6623
6624 static int
6625 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6626 {
6627   unformat_input_t *i = vam->input;
6628   vl_api_sw_interface_set_l2_xconnect_t *mp;
6629   u32 rx_sw_if_index;
6630   u8 rx_sw_if_index_set = 0;
6631   u32 tx_sw_if_index;
6632   u8 tx_sw_if_index_set = 0;
6633   u8 enable = 1;
6634   int ret;
6635
6636   /* Parse args required to build the message */
6637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6638     {
6639       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6640         rx_sw_if_index_set = 1;
6641       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6642         tx_sw_if_index_set = 1;
6643       else if (unformat (i, "rx"))
6644         {
6645           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6646             {
6647               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6648                             &rx_sw_if_index))
6649                 rx_sw_if_index_set = 1;
6650             }
6651           else
6652             break;
6653         }
6654       else if (unformat (i, "tx"))
6655         {
6656           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6657             {
6658               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6659                             &tx_sw_if_index))
6660                 tx_sw_if_index_set = 1;
6661             }
6662           else
6663             break;
6664         }
6665       else if (unformat (i, "enable"))
6666         enable = 1;
6667       else if (unformat (i, "disable"))
6668         enable = 0;
6669       else
6670         break;
6671     }
6672
6673   if (rx_sw_if_index_set == 0)
6674     {
6675       errmsg ("missing rx interface name or rx_sw_if_index");
6676       return -99;
6677     }
6678
6679   if (enable && (tx_sw_if_index_set == 0))
6680     {
6681       errmsg ("missing tx interface name or tx_sw_if_index");
6682       return -99;
6683     }
6684
6685   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6686
6687   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6688   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6689   mp->enable = enable;
6690
6691   S (mp);
6692   W (ret);
6693   return ret;
6694 }
6695
6696 static int
6697 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6698 {
6699   unformat_input_t *i = vam->input;
6700   vl_api_sw_interface_set_l2_bridge_t *mp;
6701   vl_api_l2_port_type_t port_type;
6702   u32 rx_sw_if_index;
6703   u8 rx_sw_if_index_set = 0;
6704   u32 bd_id;
6705   u8 bd_id_set = 0;
6706   u32 shg = 0;
6707   u8 enable = 1;
6708   int ret;
6709
6710   port_type = L2_API_PORT_TYPE_NORMAL;
6711
6712   /* Parse args required to build the message */
6713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6714     {
6715       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6716         rx_sw_if_index_set = 1;
6717       else if (unformat (i, "bd_id %d", &bd_id))
6718         bd_id_set = 1;
6719       else
6720         if (unformat
6721             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6722         rx_sw_if_index_set = 1;
6723       else if (unformat (i, "shg %d", &shg))
6724         ;
6725       else if (unformat (i, "bvi"))
6726         port_type = L2_API_PORT_TYPE_BVI;
6727       else if (unformat (i, "uu-fwd"))
6728         port_type = L2_API_PORT_TYPE_UU_FWD;
6729       else if (unformat (i, "enable"))
6730         enable = 1;
6731       else if (unformat (i, "disable"))
6732         enable = 0;
6733       else
6734         break;
6735     }
6736
6737   if (rx_sw_if_index_set == 0)
6738     {
6739       errmsg ("missing rx interface name or sw_if_index");
6740       return -99;
6741     }
6742
6743   if (enable && (bd_id_set == 0))
6744     {
6745       errmsg ("missing bridge domain");
6746       return -99;
6747     }
6748
6749   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6750
6751   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6752   mp->bd_id = ntohl (bd_id);
6753   mp->shg = (u8) shg;
6754   mp->port_type = ntohl (port_type);
6755   mp->enable = enable;
6756
6757   S (mp);
6758   W (ret);
6759   return ret;
6760 }
6761
6762 static int
6763 api_bridge_domain_dump (vat_main_t * vam)
6764 {
6765   unformat_input_t *i = vam->input;
6766   vl_api_bridge_domain_dump_t *mp;
6767   vl_api_control_ping_t *mp_ping;
6768   u32 bd_id = ~0;
6769   int ret;
6770
6771   /* Parse args required to build the message */
6772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6773     {
6774       if (unformat (i, "bd_id %d", &bd_id))
6775         ;
6776       else
6777         break;
6778     }
6779
6780   M (BRIDGE_DOMAIN_DUMP, mp);
6781   mp->bd_id = ntohl (bd_id);
6782   S (mp);
6783
6784   /* Use a control ping for synchronization */
6785   MPING (CONTROL_PING, mp_ping);
6786   S (mp_ping);
6787
6788   W (ret);
6789   return ret;
6790 }
6791
6792 static int
6793 api_bridge_domain_add_del (vat_main_t * vam)
6794 {
6795   unformat_input_t *i = vam->input;
6796   vl_api_bridge_domain_add_del_t *mp;
6797   u32 bd_id = ~0;
6798   u8 is_add = 1;
6799   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6800   u8 *bd_tag = NULL;
6801   u32 mac_age = 0;
6802   int ret;
6803
6804   /* Parse args required to build the message */
6805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6806     {
6807       if (unformat (i, "bd_id %d", &bd_id))
6808         ;
6809       else if (unformat (i, "flood %d", &flood))
6810         ;
6811       else if (unformat (i, "uu-flood %d", &uu_flood))
6812         ;
6813       else if (unformat (i, "forward %d", &forward))
6814         ;
6815       else if (unformat (i, "learn %d", &learn))
6816         ;
6817       else if (unformat (i, "arp-term %d", &arp_term))
6818         ;
6819       else if (unformat (i, "mac-age %d", &mac_age))
6820         ;
6821       else if (unformat (i, "bd-tag %s", &bd_tag))
6822         ;
6823       else if (unformat (i, "del"))
6824         {
6825           is_add = 0;
6826           flood = uu_flood = forward = learn = 0;
6827         }
6828       else
6829         break;
6830     }
6831
6832   if (bd_id == ~0)
6833     {
6834       errmsg ("missing bridge domain");
6835       ret = -99;
6836       goto done;
6837     }
6838
6839   if (mac_age > 255)
6840     {
6841       errmsg ("mac age must be less than 256 ");
6842       ret = -99;
6843       goto done;
6844     }
6845
6846   if ((bd_tag) && (vec_len (bd_tag) > 63))
6847     {
6848       errmsg ("bd-tag cannot be longer than 63");
6849       ret = -99;
6850       goto done;
6851     }
6852
6853   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6854
6855   mp->bd_id = ntohl (bd_id);
6856   mp->flood = flood;
6857   mp->uu_flood = uu_flood;
6858   mp->forward = forward;
6859   mp->learn = learn;
6860   mp->arp_term = arp_term;
6861   mp->is_add = is_add;
6862   mp->mac_age = (u8) mac_age;
6863   if (bd_tag)
6864     {
6865       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6866       mp->bd_tag[vec_len (bd_tag)] = 0;
6867     }
6868   S (mp);
6869   W (ret);
6870
6871 done:
6872   vec_free (bd_tag);
6873   return ret;
6874 }
6875
6876 static int
6877 api_l2fib_flush_bd (vat_main_t * vam)
6878 {
6879   unformat_input_t *i = vam->input;
6880   vl_api_l2fib_flush_bd_t *mp;
6881   u32 bd_id = ~0;
6882   int ret;
6883
6884   /* Parse args required to build the message */
6885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6886     {
6887       if (unformat (i, "bd_id %d", &bd_id));
6888       else
6889         break;
6890     }
6891
6892   if (bd_id == ~0)
6893     {
6894       errmsg ("missing bridge domain");
6895       return -99;
6896     }
6897
6898   M (L2FIB_FLUSH_BD, mp);
6899
6900   mp->bd_id = htonl (bd_id);
6901
6902   S (mp);
6903   W (ret);
6904   return ret;
6905 }
6906
6907 static int
6908 api_l2fib_flush_int (vat_main_t * vam)
6909 {
6910   unformat_input_t *i = vam->input;
6911   vl_api_l2fib_flush_int_t *mp;
6912   u32 sw_if_index = ~0;
6913   int ret;
6914
6915   /* Parse args required to build the message */
6916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6917     {
6918       if (unformat (i, "sw_if_index %d", &sw_if_index));
6919       else
6920         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6921       else
6922         break;
6923     }
6924
6925   if (sw_if_index == ~0)
6926     {
6927       errmsg ("missing interface name or sw_if_index");
6928       return -99;
6929     }
6930
6931   M (L2FIB_FLUSH_INT, mp);
6932
6933   mp->sw_if_index = ntohl (sw_if_index);
6934
6935   S (mp);
6936   W (ret);
6937   return ret;
6938 }
6939
6940 static int
6941 api_l2fib_add_del (vat_main_t * vam)
6942 {
6943   unformat_input_t *i = vam->input;
6944   vl_api_l2fib_add_del_t *mp;
6945   f64 timeout;
6946   u8 mac[6] = { 0 };
6947   u8 mac_set = 0;
6948   u32 bd_id;
6949   u8 bd_id_set = 0;
6950   u32 sw_if_index = 0;
6951   u8 sw_if_index_set = 0;
6952   u8 is_add = 1;
6953   u8 static_mac = 0;
6954   u8 filter_mac = 0;
6955   u8 bvi_mac = 0;
6956   int count = 1;
6957   f64 before = 0;
6958   int j;
6959
6960   /* Parse args required to build the message */
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6964         mac_set = 1;
6965       else if (unformat (i, "bd_id %d", &bd_id))
6966         bd_id_set = 1;
6967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6968         sw_if_index_set = 1;
6969       else if (unformat (i, "sw_if"))
6970         {
6971           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6972             {
6973               if (unformat
6974                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6975                 sw_if_index_set = 1;
6976             }
6977           else
6978             break;
6979         }
6980       else if (unformat (i, "static"))
6981         static_mac = 1;
6982       else if (unformat (i, "filter"))
6983         {
6984           filter_mac = 1;
6985           static_mac = 1;
6986         }
6987       else if (unformat (i, "bvi"))
6988         {
6989           bvi_mac = 1;
6990           static_mac = 1;
6991         }
6992       else if (unformat (i, "del"))
6993         is_add = 0;
6994       else if (unformat (i, "count %d", &count))
6995         ;
6996       else
6997         break;
6998     }
6999
7000   if (mac_set == 0)
7001     {
7002       errmsg ("missing mac address");
7003       return -99;
7004     }
7005
7006   if (bd_id_set == 0)
7007     {
7008       errmsg ("missing bridge domain");
7009       return -99;
7010     }
7011
7012   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7013     {
7014       errmsg ("missing interface name or sw_if_index");
7015       return -99;
7016     }
7017
7018   if (count > 1)
7019     {
7020       /* Turn on async mode */
7021       vam->async_mode = 1;
7022       vam->async_errors = 0;
7023       before = vat_time_now (vam);
7024     }
7025
7026   for (j = 0; j < count; j++)
7027     {
7028       M (L2FIB_ADD_DEL, mp);
7029
7030       clib_memcpy (mp->mac, mac, 6);
7031       mp->bd_id = ntohl (bd_id);
7032       mp->is_add = is_add;
7033       mp->sw_if_index = ntohl (sw_if_index);
7034
7035       if (is_add)
7036         {
7037           mp->static_mac = static_mac;
7038           mp->filter_mac = filter_mac;
7039           mp->bvi_mac = bvi_mac;
7040         }
7041       increment_mac_address (mac);
7042       /* send it... */
7043       S (mp);
7044     }
7045
7046   if (count > 1)
7047     {
7048       vl_api_control_ping_t *mp_ping;
7049       f64 after;
7050
7051       /* Shut off async mode */
7052       vam->async_mode = 0;
7053
7054       MPING (CONTROL_PING, mp_ping);
7055       S (mp_ping);
7056
7057       timeout = vat_time_now (vam) + 1.0;
7058       while (vat_time_now (vam) < timeout)
7059         if (vam->result_ready == 1)
7060           goto out;
7061       vam->retval = -99;
7062
7063     out:
7064       if (vam->retval == -99)
7065         errmsg ("timeout");
7066
7067       if (vam->async_errors > 0)
7068         {
7069           errmsg ("%d asynchronous errors", vam->async_errors);
7070           vam->retval = -98;
7071         }
7072       vam->async_errors = 0;
7073       after = vat_time_now (vam);
7074
7075       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7076              count, after - before, count / (after - before));
7077     }
7078   else
7079     {
7080       int ret;
7081
7082       /* Wait for a reply... */
7083       W (ret);
7084       return ret;
7085     }
7086   /* Return the good/bad news */
7087   return (vam->retval);
7088 }
7089
7090 static int
7091 api_bridge_domain_set_mac_age (vat_main_t * vam)
7092 {
7093   unformat_input_t *i = vam->input;
7094   vl_api_bridge_domain_set_mac_age_t *mp;
7095   u32 bd_id = ~0;
7096   u32 mac_age = 0;
7097   int ret;
7098
7099   /* Parse args required to build the message */
7100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7101     {
7102       if (unformat (i, "bd_id %d", &bd_id));
7103       else if (unformat (i, "mac-age %d", &mac_age));
7104       else
7105         break;
7106     }
7107
7108   if (bd_id == ~0)
7109     {
7110       errmsg ("missing bridge domain");
7111       return -99;
7112     }
7113
7114   if (mac_age > 255)
7115     {
7116       errmsg ("mac age must be less than 256 ");
7117       return -99;
7118     }
7119
7120   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7121
7122   mp->bd_id = htonl (bd_id);
7123   mp->mac_age = (u8) mac_age;
7124
7125   S (mp);
7126   W (ret);
7127   return ret;
7128 }
7129
7130 static int
7131 api_l2_flags (vat_main_t * vam)
7132 {
7133   unformat_input_t *i = vam->input;
7134   vl_api_l2_flags_t *mp;
7135   u32 sw_if_index;
7136   u32 flags = 0;
7137   u8 sw_if_index_set = 0;
7138   u8 is_set = 0;
7139   int ret;
7140
7141   /* Parse args required to build the message */
7142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7143     {
7144       if (unformat (i, "sw_if_index %d", &sw_if_index))
7145         sw_if_index_set = 1;
7146       else if (unformat (i, "sw_if"))
7147         {
7148           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7149             {
7150               if (unformat
7151                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7152                 sw_if_index_set = 1;
7153             }
7154           else
7155             break;
7156         }
7157       else if (unformat (i, "learn"))
7158         flags |= L2_LEARN;
7159       else if (unformat (i, "forward"))
7160         flags |= L2_FWD;
7161       else if (unformat (i, "flood"))
7162         flags |= L2_FLOOD;
7163       else if (unformat (i, "uu-flood"))
7164         flags |= L2_UU_FLOOD;
7165       else if (unformat (i, "arp-term"))
7166         flags |= L2_ARP_TERM;
7167       else if (unformat (i, "off"))
7168         is_set = 0;
7169       else if (unformat (i, "disable"))
7170         is_set = 0;
7171       else
7172         break;
7173     }
7174
7175   if (sw_if_index_set == 0)
7176     {
7177       errmsg ("missing interface name or sw_if_index");
7178       return -99;
7179     }
7180
7181   M (L2_FLAGS, mp);
7182
7183   mp->sw_if_index = ntohl (sw_if_index);
7184   mp->feature_bitmap = ntohl (flags);
7185   mp->is_set = is_set;
7186
7187   S (mp);
7188   W (ret);
7189   return ret;
7190 }
7191
7192 static int
7193 api_bridge_flags (vat_main_t * vam)
7194 {
7195   unformat_input_t *i = vam->input;
7196   vl_api_bridge_flags_t *mp;
7197   u32 bd_id;
7198   u8 bd_id_set = 0;
7199   u8 is_set = 1;
7200   bd_flags_t flags = 0;
7201   int ret;
7202
7203   /* Parse args required to build the message */
7204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7205     {
7206       if (unformat (i, "bd_id %d", &bd_id))
7207         bd_id_set = 1;
7208       else if (unformat (i, "learn"))
7209         flags |= BRIDGE_API_FLAG_LEARN;
7210       else if (unformat (i, "forward"))
7211         flags |= BRIDGE_API_FLAG_FWD;
7212       else if (unformat (i, "flood"))
7213         flags |= BRIDGE_API_FLAG_FLOOD;
7214       else if (unformat (i, "uu-flood"))
7215         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7216       else if (unformat (i, "arp-term"))
7217         flags |= BRIDGE_API_FLAG_ARP_TERM;
7218       else if (unformat (i, "off"))
7219         is_set = 0;
7220       else if (unformat (i, "disable"))
7221         is_set = 0;
7222       else
7223         break;
7224     }
7225
7226   if (bd_id_set == 0)
7227     {
7228       errmsg ("missing bridge domain");
7229       return -99;
7230     }
7231
7232   M (BRIDGE_FLAGS, mp);
7233
7234   mp->bd_id = ntohl (bd_id);
7235   mp->flags = ntohl (flags);
7236   mp->is_set = is_set;
7237
7238   S (mp);
7239   W (ret);
7240   return ret;
7241 }
7242
7243 static int
7244 api_bd_ip_mac_add_del (vat_main_t * vam)
7245 {
7246   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7247   vl_api_mac_address_t mac = { 0 };
7248   unformat_input_t *i = vam->input;
7249   vl_api_bd_ip_mac_add_del_t *mp;
7250   u32 bd_id;
7251   u8 is_add = 1;
7252   u8 bd_id_set = 0;
7253   u8 ip_set = 0;
7254   u8 mac_set = 0;
7255   int ret;
7256
7257
7258   /* Parse args required to build the message */
7259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7260     {
7261       if (unformat (i, "bd_id %d", &bd_id))
7262         {
7263           bd_id_set++;
7264         }
7265       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7266         {
7267           ip_set++;
7268         }
7269       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7270         {
7271           mac_set++;
7272         }
7273       else if (unformat (i, "del"))
7274         is_add = 0;
7275       else
7276         break;
7277     }
7278
7279   if (bd_id_set == 0)
7280     {
7281       errmsg ("missing bridge domain");
7282       return -99;
7283     }
7284   else if (ip_set == 0)
7285     {
7286       errmsg ("missing IP address");
7287       return -99;
7288     }
7289   else if (mac_set == 0)
7290     {
7291       errmsg ("missing MAC address");
7292       return -99;
7293     }
7294
7295   M (BD_IP_MAC_ADD_DEL, mp);
7296
7297   mp->entry.bd_id = ntohl (bd_id);
7298   mp->is_add = is_add;
7299
7300   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7301   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7302
7303   S (mp);
7304   W (ret);
7305   return ret;
7306 }
7307
7308 static int
7309 api_bd_ip_mac_flush (vat_main_t * vam)
7310 {
7311   unformat_input_t *i = vam->input;
7312   vl_api_bd_ip_mac_flush_t *mp;
7313   u32 bd_id;
7314   u8 bd_id_set = 0;
7315   int ret;
7316
7317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7318     {
7319       if (unformat (i, "bd_id %d", &bd_id))
7320         {
7321           bd_id_set++;
7322         }
7323       else
7324         break;
7325     }
7326
7327   if (bd_id_set == 0)
7328     {
7329       errmsg ("missing bridge domain");
7330       return -99;
7331     }
7332
7333   M (BD_IP_MAC_FLUSH, mp);
7334
7335   mp->bd_id = ntohl (bd_id);
7336
7337   S (mp);
7338   W (ret);
7339   return ret;
7340 }
7341
7342 static void vl_api_bd_ip_mac_details_t_handler
7343   (vl_api_bd_ip_mac_details_t * mp)
7344 {
7345   vat_main_t *vam = &vat_main;
7346
7347   print (vam->ofp,
7348          "\n%-5d %U %U",
7349          ntohl (mp->entry.bd_id),
7350          format_vl_api_mac_address, mp->entry.mac,
7351          format_vl_api_address, &mp->entry.ip);
7352 }
7353
7354 static void vl_api_bd_ip_mac_details_t_handler_json
7355   (vl_api_bd_ip_mac_details_t * mp)
7356 {
7357   vat_main_t *vam = &vat_main;
7358   vat_json_node_t *node = NULL;
7359
7360   if (VAT_JSON_ARRAY != vam->json_tree.type)
7361     {
7362       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7363       vat_json_init_array (&vam->json_tree);
7364     }
7365   node = vat_json_array_add (&vam->json_tree);
7366
7367   vat_json_init_object (node);
7368   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7369   vat_json_object_add_string_copy (node, "mac_address",
7370                                    format (0, "%U", format_vl_api_mac_address,
7371                                            &mp->entry.mac));
7372   u8 *ip = 0;
7373
7374   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7375   vat_json_object_add_string_copy (node, "ip_address", ip);
7376   vec_free (ip);
7377 }
7378
7379 static int
7380 api_bd_ip_mac_dump (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_bd_ip_mac_dump_t *mp;
7384   vl_api_control_ping_t *mp_ping;
7385   int ret;
7386   u32 bd_id;
7387   u8 bd_id_set = 0;
7388
7389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7390     {
7391       if (unformat (i, "bd_id %d", &bd_id))
7392         {
7393           bd_id_set++;
7394         }
7395       else
7396         break;
7397     }
7398
7399   print (vam->ofp,
7400          "\n%-5s %-7s %-20s %-30s",
7401          "bd_id", "is_ipv6", "mac_address", "ip_address");
7402
7403   /* Dump Bridge Domain Ip to Mac entries */
7404   M (BD_IP_MAC_DUMP, mp);
7405
7406   if (bd_id_set)
7407     mp->bd_id = htonl (bd_id);
7408   else
7409     mp->bd_id = ~0;
7410
7411   S (mp);
7412
7413   /* Use a control ping for synchronization */
7414   MPING (CONTROL_PING, mp_ping);
7415   S (mp_ping);
7416
7417   W (ret);
7418   return ret;
7419 }
7420
7421 static int
7422 api_tap_create_v2 (vat_main_t * vam)
7423 {
7424   unformat_input_t *i = vam->input;
7425   vl_api_tap_create_v2_t *mp;
7426 #define TAP_FLAG_GSO (1 << 0)
7427   u8 mac_address[6];
7428   u8 random_mac = 1;
7429   u32 id = ~0;
7430   u8 *host_if_name = 0;
7431   u8 *host_ns = 0;
7432   u8 host_mac_addr[6];
7433   u8 host_mac_addr_set = 0;
7434   u8 *host_bridge = 0;
7435   ip4_address_t host_ip4_addr;
7436   ip4_address_t host_ip4_gw;
7437   u8 host_ip4_gw_set = 0;
7438   u32 host_ip4_prefix_len = 0;
7439   ip6_address_t host_ip6_addr;
7440   ip6_address_t host_ip6_gw;
7441   u8 host_ip6_gw_set = 0;
7442   u32 host_ip6_prefix_len = 0;
7443   u8 host_mtu_set = 0;
7444   u32 host_mtu_size = 0;
7445   u32 tap_flags = 0;
7446   int ret;
7447   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7448
7449   clib_memset (mac_address, 0, sizeof (mac_address));
7450
7451   /* Parse args required to build the message */
7452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7453     {
7454       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7455         {
7456           random_mac = 0;
7457         }
7458       else if (unformat (i, "id %u", &id))
7459         ;
7460       else if (unformat (i, "host-if-name %s", &host_if_name))
7461         ;
7462       else if (unformat (i, "host-ns %s", &host_ns))
7463         ;
7464       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7465                          host_mac_addr))
7466         host_mac_addr_set = 1;
7467       else if (unformat (i, "host-bridge %s", &host_bridge))
7468         ;
7469       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7470                          &host_ip4_addr, &host_ip4_prefix_len))
7471         ;
7472       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7473                          &host_ip6_addr, &host_ip6_prefix_len))
7474         ;
7475       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7476                          &host_ip4_gw))
7477         host_ip4_gw_set = 1;
7478       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7479                          &host_ip6_gw))
7480         host_ip6_gw_set = 1;
7481       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7482         ;
7483       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7484         ;
7485       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7486         host_mtu_set = 1;
7487       else if (unformat (i, "no-gso"))
7488         tap_flags &= ~TAP_FLAG_GSO;
7489       else if (unformat (i, "gso"))
7490         tap_flags |= TAP_FLAG_GSO;
7491       else
7492         break;
7493     }
7494
7495   if (vec_len (host_if_name) > 63)
7496     {
7497       errmsg ("tap name too long. ");
7498       return -99;
7499     }
7500   if (vec_len (host_ns) > 63)
7501     {
7502       errmsg ("host name space too long. ");
7503       return -99;
7504     }
7505   if (vec_len (host_bridge) > 63)
7506     {
7507       errmsg ("host bridge name too long. ");
7508       return -99;
7509     }
7510   if (host_ip4_prefix_len > 32)
7511     {
7512       errmsg ("host ip4 prefix length not valid. ");
7513       return -99;
7514     }
7515   if (host_ip6_prefix_len > 128)
7516     {
7517       errmsg ("host ip6 prefix length not valid. ");
7518       return -99;
7519     }
7520   if (!is_pow2 (rx_ring_sz))
7521     {
7522       errmsg ("rx ring size must be power of 2. ");
7523       return -99;
7524     }
7525   if (rx_ring_sz > 32768)
7526     {
7527       errmsg ("rx ring size must be 32768 or lower. ");
7528       return -99;
7529     }
7530   if (!is_pow2 (tx_ring_sz))
7531     {
7532       errmsg ("tx ring size must be power of 2. ");
7533       return -99;
7534     }
7535   if (tx_ring_sz > 32768)
7536     {
7537       errmsg ("tx ring size must be 32768 or lower. ");
7538       return -99;
7539     }
7540   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7541     {
7542       errmsg ("host MTU size must be in between 64 and 65355. ");
7543       return -99;
7544     }
7545
7546   /* Construct the API message */
7547   M (TAP_CREATE_V2, mp);
7548
7549   mp->use_random_mac = random_mac;
7550
7551   mp->id = ntohl (id);
7552   mp->host_namespace_set = host_ns != 0;
7553   mp->host_bridge_set = host_bridge != 0;
7554   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7555   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7556   mp->rx_ring_sz = ntohs (rx_ring_sz);
7557   mp->tx_ring_sz = ntohs (tx_ring_sz);
7558   mp->host_mtu_set = host_mtu_set;
7559   mp->host_mtu_size = ntohl (host_mtu_size);
7560   mp->tap_flags = ntohl (tap_flags);
7561
7562   if (random_mac == 0)
7563     clib_memcpy (mp->mac_address, mac_address, 6);
7564   if (host_mac_addr_set)
7565     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7566   if (host_if_name)
7567     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7568   if (host_ns)
7569     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7570   if (host_bridge)
7571     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7572   if (host_ip4_prefix_len)
7573     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7574   if (host_ip6_prefix_len)
7575     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7576   if (host_ip4_gw_set)
7577     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7578   if (host_ip6_gw_set)
7579     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7580
7581   vec_free (host_ns);
7582   vec_free (host_if_name);
7583   vec_free (host_bridge);
7584
7585   /* send it... */
7586   S (mp);
7587
7588   /* Wait for a reply... */
7589   W (ret);
7590   return ret;
7591 }
7592
7593 static int
7594 api_tap_delete_v2 (vat_main_t * vam)
7595 {
7596   unformat_input_t *i = vam->input;
7597   vl_api_tap_delete_v2_t *mp;
7598   u32 sw_if_index = ~0;
7599   u8 sw_if_index_set = 0;
7600   int ret;
7601
7602   /* Parse args required to build the message */
7603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604     {
7605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7606         sw_if_index_set = 1;
7607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7608         sw_if_index_set = 1;
7609       else
7610         break;
7611     }
7612
7613   if (sw_if_index_set == 0)
7614     {
7615       errmsg ("missing vpp interface name. ");
7616       return -99;
7617     }
7618
7619   /* Construct the API message */
7620   M (TAP_DELETE_V2, mp);
7621
7622   mp->sw_if_index = ntohl (sw_if_index);
7623
7624   /* send it... */
7625   S (mp);
7626
7627   /* Wait for a reply... */
7628   W (ret);
7629   return ret;
7630 }
7631
7632 uword
7633 unformat_pci_addr (unformat_input_t * input, va_list * args)
7634 {
7635   struct pci_addr_t
7636   {
7637     u16 domain;
7638     u8 bus;
7639     u8 slot:5;
7640     u8 function:3;
7641   } *addr;
7642   addr = va_arg (*args, struct pci_addr_t *);
7643   u32 x[4];
7644
7645   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7646     return 0;
7647
7648   addr->domain = x[0];
7649   addr->bus = x[1];
7650   addr->slot = x[2];
7651   addr->function = x[3];
7652
7653   return 1;
7654 }
7655
7656 static int
7657 api_virtio_pci_create (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_virtio_pci_create_t *mp;
7661   u8 mac_address[6];
7662   u8 random_mac = 1;
7663   u8 gso_enabled = 0;
7664   u32 pci_addr = 0;
7665   u64 features = (u64) ~ (0ULL);
7666   int ret;
7667
7668   clib_memset (mac_address, 0, sizeof (mac_address));
7669
7670   /* Parse args required to build the message */
7671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7674         {
7675           random_mac = 0;
7676         }
7677       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7678         ;
7679       else if (unformat (i, "features 0x%llx", &features))
7680         ;
7681       else if (unformat (i, "gso-enabled"))
7682         gso_enabled = 1;
7683       else
7684         break;
7685     }
7686
7687   if (pci_addr == 0)
7688     {
7689       errmsg ("pci address must be non zero. ");
7690       return -99;
7691     }
7692
7693   /* Construct the API message */
7694   M (VIRTIO_PCI_CREATE, mp);
7695
7696   mp->use_random_mac = random_mac;
7697
7698   mp->pci_addr = htonl (pci_addr);
7699   mp->features = clib_host_to_net_u64 (features);
7700   mp->gso_enabled = gso_enabled;
7701
7702   if (random_mac == 0)
7703     clib_memcpy (mp->mac_address, mac_address, 6);
7704
7705   /* send it... */
7706   S (mp);
7707
7708   /* Wait for a reply... */
7709   W (ret);
7710   return ret;
7711 }
7712
7713 static int
7714 api_virtio_pci_delete (vat_main_t * vam)
7715 {
7716   unformat_input_t *i = vam->input;
7717   vl_api_virtio_pci_delete_t *mp;
7718   u32 sw_if_index = ~0;
7719   u8 sw_if_index_set = 0;
7720   int ret;
7721
7722   /* Parse args required to build the message */
7723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7724     {
7725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7726         sw_if_index_set = 1;
7727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7728         sw_if_index_set = 1;
7729       else
7730         break;
7731     }
7732
7733   if (sw_if_index_set == 0)
7734     {
7735       errmsg ("missing vpp interface name. ");
7736       return -99;
7737     }
7738
7739   /* Construct the API message */
7740   M (VIRTIO_PCI_DELETE, mp);
7741
7742   mp->sw_if_index = htonl (sw_if_index);
7743
7744   /* send it... */
7745   S (mp);
7746
7747   /* Wait for a reply... */
7748   W (ret);
7749   return ret;
7750 }
7751
7752 static int
7753 api_bond_create (vat_main_t * vam)
7754 {
7755   unformat_input_t *i = vam->input;
7756   vl_api_bond_create_t *mp;
7757   u8 mac_address[6];
7758   u8 custom_mac = 0;
7759   int ret;
7760   u8 mode;
7761   u8 lb;
7762   u8 mode_is_set = 0;
7763   u32 id = ~0;
7764   u8 numa_only = 0;
7765
7766   clib_memset (mac_address, 0, sizeof (mac_address));
7767   lb = BOND_LB_L2;
7768
7769   /* Parse args required to build the message */
7770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7771     {
7772       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7773         mode_is_set = 1;
7774       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7775                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7776         ;
7777       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7778                          mac_address))
7779         custom_mac = 1;
7780       else if (unformat (i, "numa-only"))
7781         numa_only = 1;
7782       else if (unformat (i, "id %u", &id))
7783         ;
7784       else
7785         break;
7786     }
7787
7788   if (mode_is_set == 0)
7789     {
7790       errmsg ("Missing bond mode. ");
7791       return -99;
7792     }
7793
7794   /* Construct the API message */
7795   M (BOND_CREATE, mp);
7796
7797   mp->use_custom_mac = custom_mac;
7798
7799   mp->mode = mode;
7800   mp->lb = lb;
7801   mp->id = htonl (id);
7802   mp->numa_only = numa_only;
7803
7804   if (custom_mac)
7805     clib_memcpy (mp->mac_address, mac_address, 6);
7806
7807   /* send it... */
7808   S (mp);
7809
7810   /* Wait for a reply... */
7811   W (ret);
7812   return ret;
7813 }
7814
7815 static int
7816 api_bond_delete (vat_main_t * vam)
7817 {
7818   unformat_input_t *i = vam->input;
7819   vl_api_bond_delete_t *mp;
7820   u32 sw_if_index = ~0;
7821   u8 sw_if_index_set = 0;
7822   int ret;
7823
7824   /* Parse args required to build the message */
7825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7826     {
7827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7828         sw_if_index_set = 1;
7829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7830         sw_if_index_set = 1;
7831       else
7832         break;
7833     }
7834
7835   if (sw_if_index_set == 0)
7836     {
7837       errmsg ("missing vpp interface name. ");
7838       return -99;
7839     }
7840
7841   /* Construct the API message */
7842   M (BOND_DELETE, mp);
7843
7844   mp->sw_if_index = ntohl (sw_if_index);
7845
7846   /* send it... */
7847   S (mp);
7848
7849   /* Wait for a reply... */
7850   W (ret);
7851   return ret;
7852 }
7853
7854 static int
7855 api_bond_enslave (vat_main_t * vam)
7856 {
7857   unformat_input_t *i = vam->input;
7858   vl_api_bond_enslave_t *mp;
7859   u32 bond_sw_if_index;
7860   int ret;
7861   u8 is_passive;
7862   u8 is_long_timeout;
7863   u32 bond_sw_if_index_is_set = 0;
7864   u32 sw_if_index;
7865   u8 sw_if_index_is_set = 0;
7866
7867   /* Parse args required to build the message */
7868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (i, "sw_if_index %d", &sw_if_index))
7871         sw_if_index_is_set = 1;
7872       else if (unformat (i, "bond %u", &bond_sw_if_index))
7873         bond_sw_if_index_is_set = 1;
7874       else if (unformat (i, "passive %d", &is_passive))
7875         ;
7876       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7877         ;
7878       else
7879         break;
7880     }
7881
7882   if (bond_sw_if_index_is_set == 0)
7883     {
7884       errmsg ("Missing bond sw_if_index. ");
7885       return -99;
7886     }
7887   if (sw_if_index_is_set == 0)
7888     {
7889       errmsg ("Missing slave sw_if_index. ");
7890       return -99;
7891     }
7892
7893   /* Construct the API message */
7894   M (BOND_ENSLAVE, mp);
7895
7896   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7897   mp->sw_if_index = ntohl (sw_if_index);
7898   mp->is_long_timeout = is_long_timeout;
7899   mp->is_passive = is_passive;
7900
7901   /* send it... */
7902   S (mp);
7903
7904   /* Wait for a reply... */
7905   W (ret);
7906   return ret;
7907 }
7908
7909 static int
7910 api_bond_detach_slave (vat_main_t * vam)
7911 {
7912   unformat_input_t *i = vam->input;
7913   vl_api_bond_detach_slave_t *mp;
7914   u32 sw_if_index = ~0;
7915   u8 sw_if_index_set = 0;
7916   int ret;
7917
7918   /* Parse args required to build the message */
7919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7920     {
7921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7922         sw_if_index_set = 1;
7923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7924         sw_if_index_set = 1;
7925       else
7926         break;
7927     }
7928
7929   if (sw_if_index_set == 0)
7930     {
7931       errmsg ("missing vpp interface name. ");
7932       return -99;
7933     }
7934
7935   /* Construct the API message */
7936   M (BOND_DETACH_SLAVE, mp);
7937
7938   mp->sw_if_index = ntohl (sw_if_index);
7939
7940   /* send it... */
7941   S (mp);
7942
7943   /* Wait for a reply... */
7944   W (ret);
7945   return ret;
7946 }
7947
7948 static int
7949 api_ip_table_add_del (vat_main_t * vam)
7950 {
7951   unformat_input_t *i = vam->input;
7952   vl_api_ip_table_add_del_t *mp;
7953   u32 table_id = ~0;
7954   u8 is_ipv6 = 0;
7955   u8 is_add = 1;
7956   int ret = 0;
7957
7958   /* Parse args required to build the message */
7959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7960     {
7961       if (unformat (i, "ipv6"))
7962         is_ipv6 = 1;
7963       else if (unformat (i, "del"))
7964         is_add = 0;
7965       else if (unformat (i, "add"))
7966         is_add = 1;
7967       else if (unformat (i, "table %d", &table_id))
7968         ;
7969       else
7970         {
7971           clib_warning ("parse error '%U'", format_unformat_error, i);
7972           return -99;
7973         }
7974     }
7975
7976   if (~0 == table_id)
7977     {
7978       errmsg ("missing table-ID");
7979       return -99;
7980     }
7981
7982   /* Construct the API message */
7983   M (IP_TABLE_ADD_DEL, mp);
7984
7985   mp->table.table_id = ntohl (table_id);
7986   mp->table.is_ip6 = is_ipv6;
7987   mp->is_add = is_add;
7988
7989   /* send it... */
7990   S (mp);
7991
7992   /* Wait for a reply... */
7993   W (ret);
7994
7995   return ret;
7996 }
7997
7998 uword
7999 unformat_fib_path (unformat_input_t * input, va_list * args)
8000 {
8001   vat_main_t *vam = va_arg (*args, vat_main_t *);
8002   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
8003   u32 weight, preference;
8004   mpls_label_t out_label;
8005
8006   clib_memset (path, 0, sizeof (*path));
8007   path->weight = 1;
8008   path->sw_if_index = ~0;
8009   path->rpf_id = ~0;
8010   path->n_labels = 0;
8011
8012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8013     {
8014       if (unformat (input, "%U %U",
8015                     unformat_vl_api_ip4_address,
8016                     &path->nh.address.ip4,
8017                     api_unformat_sw_if_index, vam, &path->sw_if_index))
8018         {
8019           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8020         }
8021       else if (unformat (input, "%U %U",
8022                          unformat_vl_api_ip6_address,
8023                          &path->nh.address.ip6,
8024                          api_unformat_sw_if_index, vam, &path->sw_if_index))
8025         {
8026           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8027         }
8028       else if (unformat (input, "weight %u", &weight))
8029         {
8030           path->weight = weight;
8031         }
8032       else if (unformat (input, "preference %u", &preference))
8033         {
8034           path->preference = preference;
8035         }
8036       else if (unformat (input, "%U next-hop-table %d",
8037                          unformat_vl_api_ip4_address,
8038                          &path->nh.address.ip4, &path->table_id))
8039         {
8040           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8041         }
8042       else if (unformat (input, "%U next-hop-table %d",
8043                          unformat_vl_api_ip6_address,
8044                          &path->nh.address.ip6, &path->table_id))
8045         {
8046           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8047         }
8048       else if (unformat (input, "%U",
8049                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8050         {
8051           /*
8052            * the recursive next-hops are by default in the default table
8053            */
8054           path->table_id = 0;
8055           path->sw_if_index = ~0;
8056           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8057         }
8058       else if (unformat (input, "%U",
8059                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8060         {
8061           /*
8062            * the recursive next-hops are by default in the default table
8063            */
8064           path->table_id = 0;
8065           path->sw_if_index = ~0;
8066           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8067         }
8068       else if (unformat (input, "resolve-via-host"))
8069         {
8070           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8071         }
8072       else if (unformat (input, "resolve-via-attached"))
8073         {
8074           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8075         }
8076       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8077         {
8078           path->type = FIB_API_PATH_TYPE_LOCAL;
8079           path->sw_if_index = ~0;
8080           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8081         }
8082       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8083         {
8084           path->type = FIB_API_PATH_TYPE_LOCAL;
8085           path->sw_if_index = ~0;
8086           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8087         }
8088       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8089         ;
8090       else if (unformat (input, "via-label %d", &path->nh.via_label))
8091         {
8092           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8093           path->sw_if_index = ~0;
8094         }
8095       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8096         {
8097           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8098           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8099         }
8100       else if (unformat (input, "local"))
8101         {
8102           path->type = FIB_API_PATH_TYPE_LOCAL;
8103         }
8104       else if (unformat (input, "out-labels"))
8105         {
8106           while (unformat (input, "%d", &out_label))
8107             {
8108               path->label_stack[path->n_labels].label = out_label;
8109               path->label_stack[path->n_labels].is_uniform = 0;
8110               path->label_stack[path->n_labels].ttl = 64;
8111               path->n_labels++;
8112             }
8113         }
8114       else if (unformat (input, "via"))
8115         {
8116           /* new path, back up and return */
8117           unformat_put_input (input);
8118           unformat_put_input (input);
8119           unformat_put_input (input);
8120           unformat_put_input (input);
8121           break;
8122         }
8123       else
8124         {
8125           return (0);
8126         }
8127     }
8128
8129   path->proto = ntohl (path->proto);
8130   path->type = ntohl (path->type);
8131   path->flags = ntohl (path->flags);
8132   path->table_id = ntohl (path->table_id);
8133   path->sw_if_index = ntohl (path->sw_if_index);
8134
8135   return (1);
8136 }
8137
8138 static int
8139 api_ip_route_add_del (vat_main_t * vam)
8140 {
8141   unformat_input_t *i = vam->input;
8142   vl_api_ip_route_add_del_t *mp;
8143   u32 vrf_id = 0;
8144   u8 is_add = 1;
8145   u8 is_multipath = 0;
8146   u8 prefix_set = 0;
8147   u8 path_count = 0;
8148   vl_api_prefix_t pfx = { };
8149   vl_api_fib_path_t paths[8];
8150   int count = 1;
8151   int j;
8152   f64 before = 0;
8153   u32 random_add_del = 0;
8154   u32 *random_vector = 0;
8155   u32 random_seed = 0xdeaddabe;
8156
8157   /* Parse args required to build the message */
8158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8159     {
8160       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8161         prefix_set = 1;
8162       else if (unformat (i, "del"))
8163         is_add = 0;
8164       else if (unformat (i, "add"))
8165         is_add = 1;
8166       else if (unformat (i, "vrf %d", &vrf_id))
8167         ;
8168       else if (unformat (i, "count %d", &count))
8169         ;
8170       else if (unformat (i, "random"))
8171         random_add_del = 1;
8172       else if (unformat (i, "multipath"))
8173         is_multipath = 1;
8174       else if (unformat (i, "seed %d", &random_seed))
8175         ;
8176       else
8177         if (unformat
8178             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8179         {
8180           path_count++;
8181           if (8 == path_count)
8182             {
8183               errmsg ("max 8 paths");
8184               return -99;
8185             }
8186         }
8187       else
8188         {
8189           clib_warning ("parse error '%U'", format_unformat_error, i);
8190           return -99;
8191         }
8192     }
8193
8194   if (!path_count)
8195     {
8196       errmsg ("specify a path; via ...");
8197       return -99;
8198     }
8199   if (prefix_set == 0)
8200     {
8201       errmsg ("missing prefix");
8202       return -99;
8203     }
8204
8205   /* Generate a pile of unique, random routes */
8206   if (random_add_del)
8207     {
8208       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8209       u32 this_random_address;
8210       uword *random_hash;
8211
8212       random_hash = hash_create (count, sizeof (uword));
8213
8214       hash_set (random_hash, i->as_u32, 1);
8215       for (j = 0; j <= count; j++)
8216         {
8217           do
8218             {
8219               this_random_address = random_u32 (&random_seed);
8220               this_random_address =
8221                 clib_host_to_net_u32 (this_random_address);
8222             }
8223           while (hash_get (random_hash, this_random_address));
8224           vec_add1 (random_vector, this_random_address);
8225           hash_set (random_hash, this_random_address, 1);
8226         }
8227       hash_free (random_hash);
8228       set_ip4_address (&pfx.address, random_vector[0]);
8229     }
8230
8231   if (count > 1)
8232     {
8233       /* Turn on async mode */
8234       vam->async_mode = 1;
8235       vam->async_errors = 0;
8236       before = vat_time_now (vam);
8237     }
8238
8239   for (j = 0; j < count; j++)
8240     {
8241       /* Construct the API message */
8242       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8243
8244       mp->is_add = is_add;
8245       mp->is_multipath = is_multipath;
8246
8247       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8248       mp->route.table_id = ntohl (vrf_id);
8249       mp->route.n_paths = path_count;
8250
8251       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8252
8253       if (random_add_del)
8254         set_ip4_address (&pfx.address, random_vector[j + 1]);
8255       else
8256         increment_address (&pfx.address);
8257       /* send it... */
8258       S (mp);
8259       /* If we receive SIGTERM, stop now... */
8260       if (vam->do_exit)
8261         break;
8262     }
8263
8264   /* When testing multiple add/del ops, use a control-ping to sync */
8265   if (count > 1)
8266     {
8267       vl_api_control_ping_t *mp_ping;
8268       f64 after;
8269       f64 timeout;
8270
8271       /* Shut off async mode */
8272       vam->async_mode = 0;
8273
8274       MPING (CONTROL_PING, mp_ping);
8275       S (mp_ping);
8276
8277       timeout = vat_time_now (vam) + 1.0;
8278       while (vat_time_now (vam) < timeout)
8279         if (vam->result_ready == 1)
8280           goto out;
8281       vam->retval = -99;
8282
8283     out:
8284       if (vam->retval == -99)
8285         errmsg ("timeout");
8286
8287       if (vam->async_errors > 0)
8288         {
8289           errmsg ("%d asynchronous errors", vam->async_errors);
8290           vam->retval = -98;
8291         }
8292       vam->async_errors = 0;
8293       after = vat_time_now (vam);
8294
8295       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8296       if (j > 0)
8297         count = j;
8298
8299       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8300              count, after - before, count / (after - before));
8301     }
8302   else
8303     {
8304       int ret;
8305
8306       /* Wait for a reply... */
8307       W (ret);
8308       return ret;
8309     }
8310
8311   /* Return the good/bad news */
8312   return (vam->retval);
8313 }
8314
8315 static int
8316 api_ip_mroute_add_del (vat_main_t * vam)
8317 {
8318   unformat_input_t *i = vam->input;
8319   u8 path_set = 0, prefix_set = 0, is_add = 1;
8320   vl_api_ip_mroute_add_del_t *mp;
8321   mfib_entry_flags_t eflags = 0;
8322   vl_api_mfib_path_t path;
8323   vl_api_mprefix_t pfx = { };
8324   u32 vrf_id = 0;
8325   int ret;
8326
8327   /* Parse args required to build the message */
8328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8329     {
8330       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8331         {
8332           prefix_set = 1;
8333           pfx.grp_address_length = htons (pfx.grp_address_length);
8334         }
8335       else if (unformat (i, "del"))
8336         is_add = 0;
8337       else if (unformat (i, "add"))
8338         is_add = 1;
8339       else if (unformat (i, "vrf %d", &vrf_id))
8340         ;
8341       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8342         path.itf_flags = htonl (path.itf_flags);
8343       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8344         ;
8345       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8346         path_set = 1;
8347       else
8348         {
8349           clib_warning ("parse error '%U'", format_unformat_error, i);
8350           return -99;
8351         }
8352     }
8353
8354   if (prefix_set == 0)
8355     {
8356       errmsg ("missing addresses\n");
8357       return -99;
8358     }
8359   if (path_set == 0)
8360     {
8361       errmsg ("missing path\n");
8362       return -99;
8363     }
8364
8365   /* Construct the API message */
8366   M (IP_MROUTE_ADD_DEL, mp);
8367
8368   mp->is_add = is_add;
8369   mp->is_multipath = 1;
8370
8371   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8372   mp->route.table_id = htonl (vrf_id);
8373   mp->route.n_paths = 1;
8374   mp->route.entry_flags = htonl (eflags);
8375
8376   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8377
8378   /* send it... */
8379   S (mp);
8380   /* Wait for a reply... */
8381   W (ret);
8382   return ret;
8383 }
8384
8385 static int
8386 api_mpls_table_add_del (vat_main_t * vam)
8387 {
8388   unformat_input_t *i = vam->input;
8389   vl_api_mpls_table_add_del_t *mp;
8390   u32 table_id = ~0;
8391   u8 is_add = 1;
8392   int ret = 0;
8393
8394   /* Parse args required to build the message */
8395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8396     {
8397       if (unformat (i, "table %d", &table_id))
8398         ;
8399       else if (unformat (i, "del"))
8400         is_add = 0;
8401       else if (unformat (i, "add"))
8402         is_add = 1;
8403       else
8404         {
8405           clib_warning ("parse error '%U'", format_unformat_error, i);
8406           return -99;
8407         }
8408     }
8409
8410   if (~0 == table_id)
8411     {
8412       errmsg ("missing table-ID");
8413       return -99;
8414     }
8415
8416   /* Construct the API message */
8417   M (MPLS_TABLE_ADD_DEL, mp);
8418
8419   mp->mt_table.mt_table_id = ntohl (table_id);
8420   mp->mt_is_add = is_add;
8421
8422   /* send it... */
8423   S (mp);
8424
8425   /* Wait for a reply... */
8426   W (ret);
8427
8428   return ret;
8429 }
8430
8431 static int
8432 api_mpls_route_add_del (vat_main_t * vam)
8433 {
8434   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8435   mpls_label_t local_label = MPLS_LABEL_INVALID;
8436   unformat_input_t *i = vam->input;
8437   vl_api_mpls_route_add_del_t *mp;
8438   vl_api_fib_path_t paths[8];
8439   int count = 1, j;
8440   f64 before = 0;
8441
8442   /* Parse args required to build the message */
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "%d", &local_label))
8446         ;
8447       else if (unformat (i, "eos"))
8448         is_eos = 1;
8449       else if (unformat (i, "non-eos"))
8450         is_eos = 0;
8451       else if (unformat (i, "del"))
8452         is_add = 0;
8453       else if (unformat (i, "add"))
8454         is_add = 1;
8455       else if (unformat (i, "multipath"))
8456         is_multipath = 1;
8457       else if (unformat (i, "count %d", &count))
8458         ;
8459       else
8460         if (unformat
8461             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8462         {
8463           path_count++;
8464           if (8 == path_count)
8465             {
8466               errmsg ("max 8 paths");
8467               return -99;
8468             }
8469         }
8470       else
8471         {
8472           clib_warning ("parse error '%U'", format_unformat_error, i);
8473           return -99;
8474         }
8475     }
8476
8477   if (!path_count)
8478     {
8479       errmsg ("specify a path; via ...");
8480       return -99;
8481     }
8482
8483   if (MPLS_LABEL_INVALID == local_label)
8484     {
8485       errmsg ("missing label");
8486       return -99;
8487     }
8488
8489   if (count > 1)
8490     {
8491       /* Turn on async mode */
8492       vam->async_mode = 1;
8493       vam->async_errors = 0;
8494       before = vat_time_now (vam);
8495     }
8496
8497   for (j = 0; j < count; j++)
8498     {
8499       /* Construct the API message */
8500       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8501
8502       mp->mr_is_add = is_add;
8503       mp->mr_is_multipath = is_multipath;
8504
8505       mp->mr_route.mr_label = local_label;
8506       mp->mr_route.mr_eos = is_eos;
8507       mp->mr_route.mr_table_id = 0;
8508       mp->mr_route.mr_n_paths = path_count;
8509
8510       clib_memcpy (&mp->mr_route.mr_paths, paths,
8511                    sizeof (paths[0]) * path_count);
8512
8513       local_label++;
8514
8515       /* send it... */
8516       S (mp);
8517       /* If we receive SIGTERM, stop now... */
8518       if (vam->do_exit)
8519         break;
8520     }
8521
8522   /* When testing multiple add/del ops, use a control-ping to sync */
8523   if (count > 1)
8524     {
8525       vl_api_control_ping_t *mp_ping;
8526       f64 after;
8527       f64 timeout;
8528
8529       /* Shut off async mode */
8530       vam->async_mode = 0;
8531
8532       MPING (CONTROL_PING, mp_ping);
8533       S (mp_ping);
8534
8535       timeout = vat_time_now (vam) + 1.0;
8536       while (vat_time_now (vam) < timeout)
8537         if (vam->result_ready == 1)
8538           goto out;
8539       vam->retval = -99;
8540
8541     out:
8542       if (vam->retval == -99)
8543         errmsg ("timeout");
8544
8545       if (vam->async_errors > 0)
8546         {
8547           errmsg ("%d asynchronous errors", vam->async_errors);
8548           vam->retval = -98;
8549         }
8550       vam->async_errors = 0;
8551       after = vat_time_now (vam);
8552
8553       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8554       if (j > 0)
8555         count = j;
8556
8557       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8558              count, after - before, count / (after - before));
8559     }
8560   else
8561     {
8562       int ret;
8563
8564       /* Wait for a reply... */
8565       W (ret);
8566       return ret;
8567     }
8568
8569   /* Return the good/bad news */
8570   return (vam->retval);
8571   return (0);
8572 }
8573
8574 static int
8575 api_mpls_ip_bind_unbind (vat_main_t * vam)
8576 {
8577   unformat_input_t *i = vam->input;
8578   vl_api_mpls_ip_bind_unbind_t *mp;
8579   u32 ip_table_id = 0;
8580   u8 is_bind = 1;
8581   vl_api_prefix_t pfx;
8582   u8 prefix_set = 0;
8583   mpls_label_t local_label = MPLS_LABEL_INVALID;
8584   int ret;
8585
8586   /* Parse args required to build the message */
8587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8588     {
8589       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8590         prefix_set = 1;
8591       else if (unformat (i, "%d", &local_label))
8592         ;
8593       else if (unformat (i, "table-id %d", &ip_table_id))
8594         ;
8595       else if (unformat (i, "unbind"))
8596         is_bind = 0;
8597       else if (unformat (i, "bind"))
8598         is_bind = 1;
8599       else
8600         {
8601           clib_warning ("parse error '%U'", format_unformat_error, i);
8602           return -99;
8603         }
8604     }
8605
8606   if (!prefix_set)
8607     {
8608       errmsg ("IP prefix not set");
8609       return -99;
8610     }
8611
8612   if (MPLS_LABEL_INVALID == local_label)
8613     {
8614       errmsg ("missing label");
8615       return -99;
8616     }
8617
8618   /* Construct the API message */
8619   M (MPLS_IP_BIND_UNBIND, mp);
8620
8621   mp->mb_is_bind = is_bind;
8622   mp->mb_ip_table_id = ntohl (ip_table_id);
8623   mp->mb_mpls_table_id = 0;
8624   mp->mb_label = ntohl (local_label);
8625   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8626
8627   /* send it... */
8628   S (mp);
8629
8630   /* Wait for a reply... */
8631   W (ret);
8632   return ret;
8633   return (0);
8634 }
8635
8636 static int
8637 api_sr_mpls_policy_add (vat_main_t * vam)
8638 {
8639   unformat_input_t *i = vam->input;
8640   vl_api_sr_mpls_policy_add_t *mp;
8641   u32 bsid = 0;
8642   u32 weight = 1;
8643   u8 type = 0;
8644   u8 n_segments = 0;
8645   u32 sid;
8646   u32 *segments = NULL;
8647   int ret;
8648
8649   /* Parse args required to build the message */
8650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8651     {
8652       if (unformat (i, "bsid %d", &bsid))
8653         ;
8654       else if (unformat (i, "weight %d", &weight))
8655         ;
8656       else if (unformat (i, "spray"))
8657         type = 1;
8658       else if (unformat (i, "next %d", &sid))
8659         {
8660           n_segments += 1;
8661           vec_add1 (segments, htonl (sid));
8662         }
8663       else
8664         {
8665           clib_warning ("parse error '%U'", format_unformat_error, i);
8666           return -99;
8667         }
8668     }
8669
8670   if (bsid == 0)
8671     {
8672       errmsg ("bsid not set");
8673       return -99;
8674     }
8675
8676   if (n_segments == 0)
8677     {
8678       errmsg ("no sid in segment stack");
8679       return -99;
8680     }
8681
8682   /* Construct the API message */
8683   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8684
8685   mp->bsid = htonl (bsid);
8686   mp->weight = htonl (weight);
8687   mp->type = type;
8688   mp->n_segments = n_segments;
8689   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8690   vec_free (segments);
8691
8692   /* send it... */
8693   S (mp);
8694
8695   /* Wait for a reply... */
8696   W (ret);
8697   return ret;
8698 }
8699
8700 static int
8701 api_sr_mpls_policy_del (vat_main_t * vam)
8702 {
8703   unformat_input_t *i = vam->input;
8704   vl_api_sr_mpls_policy_del_t *mp;
8705   u32 bsid = 0;
8706   int ret;
8707
8708   /* Parse args required to build the message */
8709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8710     {
8711       if (unformat (i, "bsid %d", &bsid))
8712         ;
8713       else
8714         {
8715           clib_warning ("parse error '%U'", format_unformat_error, i);
8716           return -99;
8717         }
8718     }
8719
8720   if (bsid == 0)
8721     {
8722       errmsg ("bsid not set");
8723       return -99;
8724     }
8725
8726   /* Construct the API message */
8727   M (SR_MPLS_POLICY_DEL, mp);
8728
8729   mp->bsid = htonl (bsid);
8730
8731   /* send it... */
8732   S (mp);
8733
8734   /* Wait for a reply... */
8735   W (ret);
8736   return ret;
8737 }
8738
8739 static int
8740 api_bier_table_add_del (vat_main_t * vam)
8741 {
8742   unformat_input_t *i = vam->input;
8743   vl_api_bier_table_add_del_t *mp;
8744   u8 is_add = 1;
8745   u32 set = 0, sub_domain = 0, hdr_len = 3;
8746   mpls_label_t local_label = MPLS_LABEL_INVALID;
8747   int ret;
8748
8749   /* Parse args required to build the message */
8750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8751     {
8752       if (unformat (i, "sub-domain %d", &sub_domain))
8753         ;
8754       else if (unformat (i, "set %d", &set))
8755         ;
8756       else if (unformat (i, "label %d", &local_label))
8757         ;
8758       else if (unformat (i, "hdr-len %d", &hdr_len))
8759         ;
8760       else if (unformat (i, "add"))
8761         is_add = 1;
8762       else if (unformat (i, "del"))
8763         is_add = 0;
8764       else
8765         {
8766           clib_warning ("parse error '%U'", format_unformat_error, i);
8767           return -99;
8768         }
8769     }
8770
8771   if (MPLS_LABEL_INVALID == local_label)
8772     {
8773       errmsg ("missing label\n");
8774       return -99;
8775     }
8776
8777   /* Construct the API message */
8778   M (BIER_TABLE_ADD_DEL, mp);
8779
8780   mp->bt_is_add = is_add;
8781   mp->bt_label = ntohl (local_label);
8782   mp->bt_tbl_id.bt_set = set;
8783   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8784   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8785
8786   /* send it... */
8787   S (mp);
8788
8789   /* Wait for a reply... */
8790   W (ret);
8791
8792   return (ret);
8793 }
8794
8795 static int
8796 api_bier_route_add_del (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   vl_api_bier_route_add_del_t *mp;
8800   u8 is_add = 1;
8801   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8802   ip4_address_t v4_next_hop_address;
8803   ip6_address_t v6_next_hop_address;
8804   u8 next_hop_set = 0;
8805   u8 next_hop_proto_is_ip4 = 1;
8806   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8807   int ret;
8808
8809   /* Parse args required to build the message */
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8813         {
8814           next_hop_proto_is_ip4 = 1;
8815           next_hop_set = 1;
8816         }
8817       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8818         {
8819           next_hop_proto_is_ip4 = 0;
8820           next_hop_set = 1;
8821         }
8822       if (unformat (i, "sub-domain %d", &sub_domain))
8823         ;
8824       else if (unformat (i, "set %d", &set))
8825         ;
8826       else if (unformat (i, "hdr-len %d", &hdr_len))
8827         ;
8828       else if (unformat (i, "bp %d", &bp))
8829         ;
8830       else if (unformat (i, "add"))
8831         is_add = 1;
8832       else if (unformat (i, "del"))
8833         is_add = 0;
8834       else if (unformat (i, "out-label %d", &next_hop_out_label))
8835         ;
8836       else
8837         {
8838           clib_warning ("parse error '%U'", format_unformat_error, i);
8839           return -99;
8840         }
8841     }
8842
8843   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8844     {
8845       errmsg ("next hop / label set\n");
8846       return -99;
8847     }
8848   if (0 == bp)
8849     {
8850       errmsg ("bit=position not set\n");
8851       return -99;
8852     }
8853
8854   /* Construct the API message */
8855   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8856
8857   mp->br_is_add = is_add;
8858   mp->br_route.br_tbl_id.bt_set = set;
8859   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8860   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8861   mp->br_route.br_bp = ntohs (bp);
8862   mp->br_route.br_n_paths = 1;
8863   mp->br_route.br_paths[0].n_labels = 1;
8864   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8865   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8866                                     FIB_API_PATH_NH_PROTO_IP4 :
8867                                     FIB_API_PATH_NH_PROTO_IP6);
8868
8869   if (next_hop_proto_is_ip4)
8870     {
8871       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8872                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8873     }
8874   else
8875     {
8876       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8877                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8878     }
8879
8880   /* send it... */
8881   S (mp);
8882
8883   /* Wait for a reply... */
8884   W (ret);
8885
8886   return (ret);
8887 }
8888
8889 static int
8890 api_proxy_arp_add_del (vat_main_t * vam)
8891 {
8892   unformat_input_t *i = vam->input;
8893   vl_api_proxy_arp_add_del_t *mp;
8894   u32 vrf_id = 0;
8895   u8 is_add = 1;
8896   vl_api_ip4_address_t lo, hi;
8897   u8 range_set = 0;
8898   int ret;
8899
8900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8901     {
8902       if (unformat (i, "vrf %d", &vrf_id))
8903         ;
8904       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8905                          unformat_vl_api_ip4_address, &hi))
8906         range_set = 1;
8907       else if (unformat (i, "del"))
8908         is_add = 0;
8909       else
8910         {
8911           clib_warning ("parse error '%U'", format_unformat_error, i);
8912           return -99;
8913         }
8914     }
8915
8916   if (range_set == 0)
8917     {
8918       errmsg ("address range not set");
8919       return -99;
8920     }
8921
8922   M (PROXY_ARP_ADD_DEL, mp);
8923
8924   mp->proxy.table_id = ntohl (vrf_id);
8925   mp->is_add = is_add;
8926   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8927   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8928
8929   S (mp);
8930   W (ret);
8931   return ret;
8932 }
8933
8934 static int
8935 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8936 {
8937   unformat_input_t *i = vam->input;
8938   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8939   u32 sw_if_index;
8940   u8 enable = 1;
8941   u8 sw_if_index_set = 0;
8942   int ret;
8943
8944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8945     {
8946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8947         sw_if_index_set = 1;
8948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8949         sw_if_index_set = 1;
8950       else if (unformat (i, "enable"))
8951         enable = 1;
8952       else if (unformat (i, "disable"))
8953         enable = 0;
8954       else
8955         {
8956           clib_warning ("parse error '%U'", format_unformat_error, i);
8957           return -99;
8958         }
8959     }
8960
8961   if (sw_if_index_set == 0)
8962     {
8963       errmsg ("missing interface name or sw_if_index");
8964       return -99;
8965     }
8966
8967   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8968
8969   mp->sw_if_index = ntohl (sw_if_index);
8970   mp->enable_disable = enable;
8971
8972   S (mp);
8973   W (ret);
8974   return ret;
8975 }
8976
8977 static int
8978 api_mpls_tunnel_add_del (vat_main_t * vam)
8979 {
8980   unformat_input_t *i = vam->input;
8981   vl_api_mpls_tunnel_add_del_t *mp;
8982
8983   vl_api_fib_path_t paths[8];
8984   u32 sw_if_index = ~0;
8985   u8 path_count = 0;
8986   u8 l2_only = 0;
8987   u8 is_add = 1;
8988   int ret;
8989
8990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8991     {
8992       if (unformat (i, "add"))
8993         is_add = 1;
8994       else
8995         if (unformat
8996             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8997         is_add = 0;
8998       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8999         is_add = 0;
9000       else if (unformat (i, "l2-only"))
9001         l2_only = 1;
9002       else
9003         if (unformat
9004             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
9005         {
9006           path_count++;
9007           if (8 == path_count)
9008             {
9009               errmsg ("max 8 paths");
9010               return -99;
9011             }
9012         }
9013       else
9014         {
9015           clib_warning ("parse error '%U'", format_unformat_error, i);
9016           return -99;
9017         }
9018     }
9019
9020   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
9021
9022   mp->mt_is_add = is_add;
9023   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
9024   mp->mt_tunnel.mt_l2_only = l2_only;
9025   mp->mt_tunnel.mt_is_multicast = 0;
9026   mp->mt_tunnel.mt_n_paths = path_count;
9027
9028   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
9029                sizeof (paths[0]) * path_count);
9030
9031   S (mp);
9032   W (ret);
9033   return ret;
9034 }
9035
9036 static int
9037 api_sw_interface_set_unnumbered (vat_main_t * vam)
9038 {
9039   unformat_input_t *i = vam->input;
9040   vl_api_sw_interface_set_unnumbered_t *mp;
9041   u32 sw_if_index;
9042   u32 unnum_sw_index = ~0;
9043   u8 is_add = 1;
9044   u8 sw_if_index_set = 0;
9045   int ret;
9046
9047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9048     {
9049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9050         sw_if_index_set = 1;
9051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9052         sw_if_index_set = 1;
9053       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9054         ;
9055       else if (unformat (i, "del"))
9056         is_add = 0;
9057       else
9058         {
9059           clib_warning ("parse error '%U'", format_unformat_error, i);
9060           return -99;
9061         }
9062     }
9063
9064   if (sw_if_index_set == 0)
9065     {
9066       errmsg ("missing interface name or sw_if_index");
9067       return -99;
9068     }
9069
9070   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9071
9072   mp->sw_if_index = ntohl (sw_if_index);
9073   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9074   mp->is_add = is_add;
9075
9076   S (mp);
9077   W (ret);
9078   return ret;
9079 }
9080
9081 static int
9082 api_ip_neighbor_add_del (vat_main_t * vam)
9083 {
9084   vl_api_mac_address_t mac_address;
9085   unformat_input_t *i = vam->input;
9086   vl_api_ip_neighbor_add_del_t *mp;
9087   vl_api_address_t ip_address;
9088   u32 sw_if_index;
9089   u8 sw_if_index_set = 0;
9090   u8 is_add = 1;
9091   u8 mac_set = 0;
9092   u8 address_set = 0;
9093   int ret;
9094   ip_neighbor_flags_t flags;
9095
9096   flags = IP_NEIGHBOR_FLAG_NONE;
9097   clib_memset (&ip_address, 0, sizeof (ip_address));
9098   clib_memset (&mac_address, 0, sizeof (mac_address));
9099
9100   /* Parse args required to build the message */
9101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9102     {
9103       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9104         {
9105           mac_set = 1;
9106         }
9107       else if (unformat (i, "del"))
9108         is_add = 0;
9109       else
9110         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9111         sw_if_index_set = 1;
9112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9113         sw_if_index_set = 1;
9114       else if (unformat (i, "static"))
9115         flags |= IP_NEIGHBOR_FLAG_STATIC;
9116       else if (unformat (i, "no-fib-entry"))
9117         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9118       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9119         address_set = 1;
9120       else
9121         {
9122           clib_warning ("parse error '%U'", format_unformat_error, i);
9123           return -99;
9124         }
9125     }
9126
9127   if (sw_if_index_set == 0)
9128     {
9129       errmsg ("missing interface name or sw_if_index");
9130       return -99;
9131     }
9132   if (!address_set)
9133     {
9134       errmsg ("no address set");
9135       return -99;
9136     }
9137
9138   /* Construct the API message */
9139   M (IP_NEIGHBOR_ADD_DEL, mp);
9140
9141   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9142   mp->is_add = is_add;
9143   mp->neighbor.flags = htonl (flags);
9144   if (mac_set)
9145     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9146                  sizeof (mac_address));
9147   if (address_set)
9148     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9149
9150   /* send it... */
9151   S (mp);
9152
9153   /* Wait for a reply, return good/bad news  */
9154   W (ret);
9155   return ret;
9156 }
9157
9158 static int
9159 api_create_vlan_subif (vat_main_t * vam)
9160 {
9161   unformat_input_t *i = vam->input;
9162   vl_api_create_vlan_subif_t *mp;
9163   u32 sw_if_index;
9164   u8 sw_if_index_set = 0;
9165   u32 vlan_id;
9166   u8 vlan_id_set = 0;
9167   int ret;
9168
9169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9170     {
9171       if (unformat (i, "sw_if_index %d", &sw_if_index))
9172         sw_if_index_set = 1;
9173       else
9174         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9175         sw_if_index_set = 1;
9176       else if (unformat (i, "vlan %d", &vlan_id))
9177         vlan_id_set = 1;
9178       else
9179         {
9180           clib_warning ("parse error '%U'", format_unformat_error, i);
9181           return -99;
9182         }
9183     }
9184
9185   if (sw_if_index_set == 0)
9186     {
9187       errmsg ("missing interface name or sw_if_index");
9188       return -99;
9189     }
9190
9191   if (vlan_id_set == 0)
9192     {
9193       errmsg ("missing vlan_id");
9194       return -99;
9195     }
9196   M (CREATE_VLAN_SUBIF, mp);
9197
9198   mp->sw_if_index = ntohl (sw_if_index);
9199   mp->vlan_id = ntohl (vlan_id);
9200
9201   S (mp);
9202   W (ret);
9203   return ret;
9204 }
9205
9206 #define foreach_create_subif_bit                \
9207 _(no_tags)                                      \
9208 _(one_tag)                                      \
9209 _(two_tags)                                     \
9210 _(dot1ad)                                       \
9211 _(exact_match)                                  \
9212 _(default_sub)                                  \
9213 _(outer_vlan_id_any)                            \
9214 _(inner_vlan_id_any)
9215
9216 #define foreach_create_subif_flag               \
9217 _(0, "no_tags")                                 \
9218 _(1, "one_tag")                                 \
9219 _(2, "two_tags")                                \
9220 _(3, "dot1ad")                                  \
9221 _(4, "exact_match")                             \
9222 _(5, "default_sub")                             \
9223 _(6, "outer_vlan_id_any")                       \
9224 _(7, "inner_vlan_id_any")
9225
9226 static int
9227 api_create_subif (vat_main_t * vam)
9228 {
9229   unformat_input_t *i = vam->input;
9230   vl_api_create_subif_t *mp;
9231   u32 sw_if_index;
9232   u8 sw_if_index_set = 0;
9233   u32 sub_id;
9234   u8 sub_id_set = 0;
9235   u32 __attribute__ ((unused)) no_tags = 0;
9236   u32 __attribute__ ((unused)) one_tag = 0;
9237   u32 __attribute__ ((unused)) two_tags = 0;
9238   u32 __attribute__ ((unused)) dot1ad = 0;
9239   u32 __attribute__ ((unused)) exact_match = 0;
9240   u32 __attribute__ ((unused)) default_sub = 0;
9241   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9242   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9243   u32 tmp;
9244   u16 outer_vlan_id = 0;
9245   u16 inner_vlan_id = 0;
9246   int ret;
9247
9248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9249     {
9250       if (unformat (i, "sw_if_index %d", &sw_if_index))
9251         sw_if_index_set = 1;
9252       else
9253         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9254         sw_if_index_set = 1;
9255       else if (unformat (i, "sub_id %d", &sub_id))
9256         sub_id_set = 1;
9257       else if (unformat (i, "outer_vlan_id %d", &tmp))
9258         outer_vlan_id = tmp;
9259       else if (unformat (i, "inner_vlan_id %d", &tmp))
9260         inner_vlan_id = tmp;
9261
9262 #define _(a) else if (unformat (i, #a)) a = 1 ;
9263       foreach_create_subif_bit
9264 #undef _
9265         else
9266         {
9267           clib_warning ("parse error '%U'", format_unformat_error, i);
9268           return -99;
9269         }
9270     }
9271
9272   if (sw_if_index_set == 0)
9273     {
9274       errmsg ("missing interface name or sw_if_index");
9275       return -99;
9276     }
9277
9278   if (sub_id_set == 0)
9279     {
9280       errmsg ("missing sub_id");
9281       return -99;
9282     }
9283   M (CREATE_SUBIF, mp);
9284
9285   mp->sw_if_index = ntohl (sw_if_index);
9286   mp->sub_id = ntohl (sub_id);
9287
9288 #define _(a,b) mp->sub_if_flags |= (1 << a);
9289   foreach_create_subif_flag;
9290 #undef _
9291
9292   mp->outer_vlan_id = ntohs (outer_vlan_id);
9293   mp->inner_vlan_id = ntohs (inner_vlan_id);
9294
9295   S (mp);
9296   W (ret);
9297   return ret;
9298 }
9299
9300 static int
9301 api_reset_fib (vat_main_t * vam)
9302 {
9303   unformat_input_t *i = vam->input;
9304   vl_api_reset_fib_t *mp;
9305   u32 vrf_id = 0;
9306   u8 is_ipv6 = 0;
9307   u8 vrf_id_set = 0;
9308
9309   int ret;
9310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9311     {
9312       if (unformat (i, "vrf %d", &vrf_id))
9313         vrf_id_set = 1;
9314       else if (unformat (i, "ipv6"))
9315         is_ipv6 = 1;
9316       else
9317         {
9318           clib_warning ("parse error '%U'", format_unformat_error, i);
9319           return -99;
9320         }
9321     }
9322
9323   if (vrf_id_set == 0)
9324     {
9325       errmsg ("missing vrf id");
9326       return -99;
9327     }
9328
9329   M (RESET_FIB, mp);
9330
9331   mp->vrf_id = ntohl (vrf_id);
9332   mp->is_ipv6 = is_ipv6;
9333
9334   S (mp);
9335   W (ret);
9336   return ret;
9337 }
9338
9339 static int
9340 api_dhcp_proxy_config (vat_main_t * vam)
9341 {
9342   unformat_input_t *i = vam->input;
9343   vl_api_dhcp_proxy_config_t *mp;
9344   u32 rx_vrf_id = 0;
9345   u32 server_vrf_id = 0;
9346   u8 is_add = 1;
9347   u8 v4_address_set = 0;
9348   u8 v6_address_set = 0;
9349   ip4_address_t v4address;
9350   ip6_address_t v6address;
9351   u8 v4_src_address_set = 0;
9352   u8 v6_src_address_set = 0;
9353   ip4_address_t v4srcaddress;
9354   ip6_address_t v6srcaddress;
9355   int ret;
9356
9357   /* Parse args required to build the message */
9358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9359     {
9360       if (unformat (i, "del"))
9361         is_add = 0;
9362       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9363         ;
9364       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9365         ;
9366       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9367         v4_address_set = 1;
9368       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9369         v6_address_set = 1;
9370       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9371         v4_src_address_set = 1;
9372       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9373         v6_src_address_set = 1;
9374       else
9375         break;
9376     }
9377
9378   if (v4_address_set && v6_address_set)
9379     {
9380       errmsg ("both v4 and v6 server addresses set");
9381       return -99;
9382     }
9383   if (!v4_address_set && !v6_address_set)
9384     {
9385       errmsg ("no server addresses set");
9386       return -99;
9387     }
9388
9389   if (v4_src_address_set && v6_src_address_set)
9390     {
9391       errmsg ("both v4 and v6  src addresses set");
9392       return -99;
9393     }
9394   if (!v4_src_address_set && !v6_src_address_set)
9395     {
9396       errmsg ("no src addresses set");
9397       return -99;
9398     }
9399
9400   if (!(v4_src_address_set && v4_address_set) &&
9401       !(v6_src_address_set && v6_address_set))
9402     {
9403       errmsg ("no matching server and src addresses set");
9404       return -99;
9405     }
9406
9407   /* Construct the API message */
9408   M (DHCP_PROXY_CONFIG, mp);
9409
9410   mp->is_add = is_add;
9411   mp->rx_vrf_id = ntohl (rx_vrf_id);
9412   mp->server_vrf_id = ntohl (server_vrf_id);
9413   if (v6_address_set)
9414     {
9415       mp->is_ipv6 = 1;
9416       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9417       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9418     }
9419   else
9420     {
9421       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9422       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9423     }
9424
9425   /* send it... */
9426   S (mp);
9427
9428   /* Wait for a reply, return good/bad news  */
9429   W (ret);
9430   return ret;
9431 }
9432
9433 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9434 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9435
9436 static void
9437 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9438 {
9439   vat_main_t *vam = &vat_main;
9440   u32 i, count = mp->count;
9441   vl_api_dhcp_server_t *s;
9442
9443   if (mp->is_ipv6)
9444     print (vam->ofp,
9445            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9446            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9447            ntohl (mp->rx_vrf_id),
9448            format_ip6_address, mp->dhcp_src_address,
9449            mp->vss_type, mp->vss_vpn_ascii_id,
9450            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9451   else
9452     print (vam->ofp,
9453            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9454            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9455            ntohl (mp->rx_vrf_id),
9456            format_ip4_address, mp->dhcp_src_address,
9457            mp->vss_type, mp->vss_vpn_ascii_id,
9458            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9459
9460   for (i = 0; i < count; i++)
9461     {
9462       s = &mp->servers[i];
9463
9464       if (mp->is_ipv6)
9465         print (vam->ofp,
9466                " Server Table-ID %d, Server Address %U",
9467                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9468       else
9469         print (vam->ofp,
9470                " Server Table-ID %d, Server Address %U",
9471                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9472     }
9473 }
9474
9475 static void vl_api_dhcp_proxy_details_t_handler_json
9476   (vl_api_dhcp_proxy_details_t * mp)
9477 {
9478   vat_main_t *vam = &vat_main;
9479   vat_json_node_t *node = NULL;
9480   u32 i, count = mp->count;
9481   struct in_addr ip4;
9482   struct in6_addr ip6;
9483   vl_api_dhcp_server_t *s;
9484
9485   if (VAT_JSON_ARRAY != vam->json_tree.type)
9486     {
9487       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9488       vat_json_init_array (&vam->json_tree);
9489     }
9490   node = vat_json_array_add (&vam->json_tree);
9491
9492   vat_json_init_object (node);
9493   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9494   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9495                              sizeof (mp->vss_type));
9496   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9497                                    mp->vss_vpn_ascii_id);
9498   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9499   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9500
9501   if (mp->is_ipv6)
9502     {
9503       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9504       vat_json_object_add_ip6 (node, "src_address", ip6);
9505     }
9506   else
9507     {
9508       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9509       vat_json_object_add_ip4 (node, "src_address", ip4);
9510     }
9511
9512   for (i = 0; i < count; i++)
9513     {
9514       s = &mp->servers[i];
9515
9516       vat_json_object_add_uint (node, "server-table-id",
9517                                 ntohl (s->server_vrf_id));
9518
9519       if (mp->is_ipv6)
9520         {
9521           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9522           vat_json_object_add_ip4 (node, "src_address", ip4);
9523         }
9524       else
9525         {
9526           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9527           vat_json_object_add_ip6 (node, "server_address", ip6);
9528         }
9529     }
9530 }
9531
9532 static int
9533 api_dhcp_proxy_dump (vat_main_t * vam)
9534 {
9535   unformat_input_t *i = vam->input;
9536   vl_api_control_ping_t *mp_ping;
9537   vl_api_dhcp_proxy_dump_t *mp;
9538   u8 is_ipv6 = 0;
9539   int ret;
9540
9541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9542     {
9543       if (unformat (i, "ipv6"))
9544         is_ipv6 = 1;
9545       else
9546         {
9547           clib_warning ("parse error '%U'", format_unformat_error, i);
9548           return -99;
9549         }
9550     }
9551
9552   M (DHCP_PROXY_DUMP, mp);
9553
9554   mp->is_ip6 = is_ipv6;
9555   S (mp);
9556
9557   /* Use a control ping for synchronization */
9558   MPING (CONTROL_PING, mp_ping);
9559   S (mp_ping);
9560
9561   W (ret);
9562   return ret;
9563 }
9564
9565 static int
9566 api_dhcp_proxy_set_vss (vat_main_t * vam)
9567 {
9568   unformat_input_t *i = vam->input;
9569   vl_api_dhcp_proxy_set_vss_t *mp;
9570   u8 is_ipv6 = 0;
9571   u8 is_add = 1;
9572   u32 tbl_id = ~0;
9573   u8 vss_type = VSS_TYPE_DEFAULT;
9574   u8 *vpn_ascii_id = 0;
9575   u32 oui = 0;
9576   u32 fib_id = 0;
9577   int ret;
9578
9579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9580     {
9581       if (unformat (i, "tbl_id %d", &tbl_id))
9582         ;
9583       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9584         vss_type = VSS_TYPE_ASCII;
9585       else if (unformat (i, "fib_id %d", &fib_id))
9586         vss_type = VSS_TYPE_VPN_ID;
9587       else if (unformat (i, "oui %d", &oui))
9588         vss_type = VSS_TYPE_VPN_ID;
9589       else if (unformat (i, "ipv6"))
9590         is_ipv6 = 1;
9591       else if (unformat (i, "del"))
9592         is_add = 0;
9593       else
9594         break;
9595     }
9596
9597   if (tbl_id == ~0)
9598     {
9599       errmsg ("missing tbl_id ");
9600       vec_free (vpn_ascii_id);
9601       return -99;
9602     }
9603
9604   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9605     {
9606       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9607       vec_free (vpn_ascii_id);
9608       return -99;
9609     }
9610
9611   M (DHCP_PROXY_SET_VSS, mp);
9612   mp->tbl_id = ntohl (tbl_id);
9613   mp->vss_type = vss_type;
9614   if (vpn_ascii_id)
9615     {
9616       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9617       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9618     }
9619   mp->vpn_index = ntohl (fib_id);
9620   mp->oui = ntohl (oui);
9621   mp->is_ipv6 = is_ipv6;
9622   mp->is_add = is_add;
9623
9624   S (mp);
9625   W (ret);
9626
9627   vec_free (vpn_ascii_id);
9628   return ret;
9629 }
9630
9631 static int
9632 api_dhcp_client_config (vat_main_t * vam)
9633 {
9634   unformat_input_t *i = vam->input;
9635   vl_api_dhcp_client_config_t *mp;
9636   u32 sw_if_index;
9637   u8 sw_if_index_set = 0;
9638   u8 is_add = 1;
9639   u8 *hostname = 0;
9640   u8 disable_event = 0;
9641   int ret;
9642
9643   /* Parse args required to build the message */
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "del"))
9647         is_add = 0;
9648       else
9649         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9650         sw_if_index_set = 1;
9651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9652         sw_if_index_set = 1;
9653       else if (unformat (i, "hostname %s", &hostname))
9654         ;
9655       else if (unformat (i, "disable_event"))
9656         disable_event = 1;
9657       else
9658         break;
9659     }
9660
9661   if (sw_if_index_set == 0)
9662     {
9663       errmsg ("missing interface name or sw_if_index");
9664       return -99;
9665     }
9666
9667   if (vec_len (hostname) > 63)
9668     {
9669       errmsg ("hostname too long");
9670     }
9671   vec_add1 (hostname, 0);
9672
9673   /* Construct the API message */
9674   M (DHCP_CLIENT_CONFIG, mp);
9675
9676   mp->is_add = is_add;
9677   mp->client.sw_if_index = htonl (sw_if_index);
9678   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9679   vec_free (hostname);
9680   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9681   mp->client.pid = htonl (getpid ());
9682
9683   /* send it... */
9684   S (mp);
9685
9686   /* Wait for a reply, return good/bad news  */
9687   W (ret);
9688   return ret;
9689 }
9690
9691 static int
9692 api_set_ip_flow_hash (vat_main_t * vam)
9693 {
9694   unformat_input_t *i = vam->input;
9695   vl_api_set_ip_flow_hash_t *mp;
9696   u32 vrf_id = 0;
9697   u8 is_ipv6 = 0;
9698   u8 vrf_id_set = 0;
9699   u8 src = 0;
9700   u8 dst = 0;
9701   u8 sport = 0;
9702   u8 dport = 0;
9703   u8 proto = 0;
9704   u8 reverse = 0;
9705   int ret;
9706
9707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (i, "vrf %d", &vrf_id))
9710         vrf_id_set = 1;
9711       else if (unformat (i, "ipv6"))
9712         is_ipv6 = 1;
9713       else if (unformat (i, "src"))
9714         src = 1;
9715       else if (unformat (i, "dst"))
9716         dst = 1;
9717       else if (unformat (i, "sport"))
9718         sport = 1;
9719       else if (unformat (i, "dport"))
9720         dport = 1;
9721       else if (unformat (i, "proto"))
9722         proto = 1;
9723       else if (unformat (i, "reverse"))
9724         reverse = 1;
9725
9726       else
9727         {
9728           clib_warning ("parse error '%U'", format_unformat_error, i);
9729           return -99;
9730         }
9731     }
9732
9733   if (vrf_id_set == 0)
9734     {
9735       errmsg ("missing vrf id");
9736       return -99;
9737     }
9738
9739   M (SET_IP_FLOW_HASH, mp);
9740   mp->src = src;
9741   mp->dst = dst;
9742   mp->sport = sport;
9743   mp->dport = dport;
9744   mp->proto = proto;
9745   mp->reverse = reverse;
9746   mp->vrf_id = ntohl (vrf_id);
9747   mp->is_ipv6 = is_ipv6;
9748
9749   S (mp);
9750   W (ret);
9751   return ret;
9752 }
9753
9754 static int
9755 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9756 {
9757   unformat_input_t *i = vam->input;
9758   vl_api_sw_interface_ip6_enable_disable_t *mp;
9759   u32 sw_if_index;
9760   u8 sw_if_index_set = 0;
9761   u8 enable = 0;
9762   int ret;
9763
9764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9765     {
9766       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9767         sw_if_index_set = 1;
9768       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9769         sw_if_index_set = 1;
9770       else if (unformat (i, "enable"))
9771         enable = 1;
9772       else if (unformat (i, "disable"))
9773         enable = 0;
9774       else
9775         {
9776           clib_warning ("parse error '%U'", format_unformat_error, i);
9777           return -99;
9778         }
9779     }
9780
9781   if (sw_if_index_set == 0)
9782     {
9783       errmsg ("missing interface name or sw_if_index");
9784       return -99;
9785     }
9786
9787   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9788
9789   mp->sw_if_index = ntohl (sw_if_index);
9790   mp->enable = enable;
9791
9792   S (mp);
9793   W (ret);
9794   return ret;
9795 }
9796
9797 static int
9798 api_ip6nd_proxy_add_del (vat_main_t * vam)
9799 {
9800   unformat_input_t *i = vam->input;
9801   vl_api_ip6nd_proxy_add_del_t *mp;
9802   u32 sw_if_index = ~0;
9803   u8 v6_address_set = 0;
9804   vl_api_ip6_address_t v6address;
9805   u8 is_del = 0;
9806   int ret;
9807
9808   /* Parse args required to build the message */
9809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9810     {
9811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9812         ;
9813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9814         ;
9815       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9816         v6_address_set = 1;
9817       if (unformat (i, "del"))
9818         is_del = 1;
9819       else
9820         {
9821           clib_warning ("parse error '%U'", format_unformat_error, i);
9822           return -99;
9823         }
9824     }
9825
9826   if (sw_if_index == ~0)
9827     {
9828       errmsg ("missing interface name or sw_if_index");
9829       return -99;
9830     }
9831   if (!v6_address_set)
9832     {
9833       errmsg ("no address set");
9834       return -99;
9835     }
9836
9837   /* Construct the API message */
9838   M (IP6ND_PROXY_ADD_DEL, mp);
9839
9840   mp->is_del = is_del;
9841   mp->sw_if_index = ntohl (sw_if_index);
9842   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9843
9844   /* send it... */
9845   S (mp);
9846
9847   /* Wait for a reply, return good/bad news  */
9848   W (ret);
9849   return ret;
9850 }
9851
9852 static int
9853 api_ip6nd_proxy_dump (vat_main_t * vam)
9854 {
9855   vl_api_ip6nd_proxy_dump_t *mp;
9856   vl_api_control_ping_t *mp_ping;
9857   int ret;
9858
9859   M (IP6ND_PROXY_DUMP, mp);
9860
9861   S (mp);
9862
9863   /* Use a control ping for synchronization */
9864   MPING (CONTROL_PING, mp_ping);
9865   S (mp_ping);
9866
9867   W (ret);
9868   return ret;
9869 }
9870
9871 static void vl_api_ip6nd_proxy_details_t_handler
9872   (vl_api_ip6nd_proxy_details_t * mp)
9873 {
9874   vat_main_t *vam = &vat_main;
9875
9876   print (vam->ofp, "host %U sw_if_index %d",
9877          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9878 }
9879
9880 static void vl_api_ip6nd_proxy_details_t_handler_json
9881   (vl_api_ip6nd_proxy_details_t * mp)
9882 {
9883   vat_main_t *vam = &vat_main;
9884   struct in6_addr ip6;
9885   vat_json_node_t *node = NULL;
9886
9887   if (VAT_JSON_ARRAY != vam->json_tree.type)
9888     {
9889       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9890       vat_json_init_array (&vam->json_tree);
9891     }
9892   node = vat_json_array_add (&vam->json_tree);
9893
9894   vat_json_init_object (node);
9895   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9896
9897   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9898   vat_json_object_add_ip6 (node, "host", ip6);
9899 }
9900
9901 static int
9902 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9903 {
9904   unformat_input_t *i = vam->input;
9905   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9906   u32 sw_if_index;
9907   u8 sw_if_index_set = 0;
9908   u8 v6_address_set = 0;
9909   vl_api_prefix_t pfx;
9910   u8 use_default = 0;
9911   u8 no_advertise = 0;
9912   u8 off_link = 0;
9913   u8 no_autoconfig = 0;
9914   u8 no_onlink = 0;
9915   u8 is_no = 0;
9916   u32 val_lifetime = 0;
9917   u32 pref_lifetime = 0;
9918   int ret;
9919
9920   /* Parse args required to build the message */
9921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9922     {
9923       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9924         sw_if_index_set = 1;
9925       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9926         sw_if_index_set = 1;
9927       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9928         v6_address_set = 1;
9929       else if (unformat (i, "val_life %d", &val_lifetime))
9930         ;
9931       else if (unformat (i, "pref_life %d", &pref_lifetime))
9932         ;
9933       else if (unformat (i, "def"))
9934         use_default = 1;
9935       else if (unformat (i, "noadv"))
9936         no_advertise = 1;
9937       else if (unformat (i, "offl"))
9938         off_link = 1;
9939       else if (unformat (i, "noauto"))
9940         no_autoconfig = 1;
9941       else if (unformat (i, "nolink"))
9942         no_onlink = 1;
9943       else if (unformat (i, "isno"))
9944         is_no = 1;
9945       else
9946         {
9947           clib_warning ("parse error '%U'", format_unformat_error, i);
9948           return -99;
9949         }
9950     }
9951
9952   if (sw_if_index_set == 0)
9953     {
9954       errmsg ("missing interface name or sw_if_index");
9955       return -99;
9956     }
9957   if (!v6_address_set)
9958     {
9959       errmsg ("no address set");
9960       return -99;
9961     }
9962
9963   /* Construct the API message */
9964   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9965
9966   mp->sw_if_index = ntohl (sw_if_index);
9967   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9968   mp->use_default = use_default;
9969   mp->no_advertise = no_advertise;
9970   mp->off_link = off_link;
9971   mp->no_autoconfig = no_autoconfig;
9972   mp->no_onlink = no_onlink;
9973   mp->is_no = is_no;
9974   mp->val_lifetime = ntohl (val_lifetime);
9975   mp->pref_lifetime = ntohl (pref_lifetime);
9976
9977   /* send it... */
9978   S (mp);
9979
9980   /* Wait for a reply, return good/bad news  */
9981   W (ret);
9982   return ret;
9983 }
9984
9985 static int
9986 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9987 {
9988   unformat_input_t *i = vam->input;
9989   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9990   u32 sw_if_index;
9991   u8 sw_if_index_set = 0;
9992   u8 suppress = 0;
9993   u8 managed = 0;
9994   u8 other = 0;
9995   u8 ll_option = 0;
9996   u8 send_unicast = 0;
9997   u8 cease = 0;
9998   u8 is_no = 0;
9999   u8 default_router = 0;
10000   u32 max_interval = 0;
10001   u32 min_interval = 0;
10002   u32 lifetime = 0;
10003   u32 initial_count = 0;
10004   u32 initial_interval = 0;
10005   int ret;
10006
10007
10008   /* Parse args required to build the message */
10009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10010     {
10011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10012         sw_if_index_set = 1;
10013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10014         sw_if_index_set = 1;
10015       else if (unformat (i, "maxint %d", &max_interval))
10016         ;
10017       else if (unformat (i, "minint %d", &min_interval))
10018         ;
10019       else if (unformat (i, "life %d", &lifetime))
10020         ;
10021       else if (unformat (i, "count %d", &initial_count))
10022         ;
10023       else if (unformat (i, "interval %d", &initial_interval))
10024         ;
10025       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10026         suppress = 1;
10027       else if (unformat (i, "managed"))
10028         managed = 1;
10029       else if (unformat (i, "other"))
10030         other = 1;
10031       else if (unformat (i, "ll"))
10032         ll_option = 1;
10033       else if (unformat (i, "send"))
10034         send_unicast = 1;
10035       else if (unformat (i, "cease"))
10036         cease = 1;
10037       else if (unformat (i, "isno"))
10038         is_no = 1;
10039       else if (unformat (i, "def"))
10040         default_router = 1;
10041       else
10042         {
10043           clib_warning ("parse error '%U'", format_unformat_error, i);
10044           return -99;
10045         }
10046     }
10047
10048   if (sw_if_index_set == 0)
10049     {
10050       errmsg ("missing interface name or sw_if_index");
10051       return -99;
10052     }
10053
10054   /* Construct the API message */
10055   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10056
10057   mp->sw_if_index = ntohl (sw_if_index);
10058   mp->max_interval = ntohl (max_interval);
10059   mp->min_interval = ntohl (min_interval);
10060   mp->lifetime = ntohl (lifetime);
10061   mp->initial_count = ntohl (initial_count);
10062   mp->initial_interval = ntohl (initial_interval);
10063   mp->suppress = suppress;
10064   mp->managed = managed;
10065   mp->other = other;
10066   mp->ll_option = ll_option;
10067   mp->send_unicast = send_unicast;
10068   mp->cease = cease;
10069   mp->is_no = is_no;
10070   mp->default_router = default_router;
10071
10072   /* send it... */
10073   S (mp);
10074
10075   /* Wait for a reply, return good/bad news  */
10076   W (ret);
10077   return ret;
10078 }
10079
10080 static int
10081 api_set_arp_neighbor_limit (vat_main_t * vam)
10082 {
10083   unformat_input_t *i = vam->input;
10084   vl_api_set_arp_neighbor_limit_t *mp;
10085   u32 arp_nbr_limit;
10086   u8 limit_set = 0;
10087   u8 is_ipv6 = 0;
10088   int ret;
10089
10090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10091     {
10092       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10093         limit_set = 1;
10094       else if (unformat (i, "ipv6"))
10095         is_ipv6 = 1;
10096       else
10097         {
10098           clib_warning ("parse error '%U'", format_unformat_error, i);
10099           return -99;
10100         }
10101     }
10102
10103   if (limit_set == 0)
10104     {
10105       errmsg ("missing limit value");
10106       return -99;
10107     }
10108
10109   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10110
10111   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10112   mp->is_ipv6 = is_ipv6;
10113
10114   S (mp);
10115   W (ret);
10116   return ret;
10117 }
10118
10119 static int
10120 api_l2_patch_add_del (vat_main_t * vam)
10121 {
10122   unformat_input_t *i = vam->input;
10123   vl_api_l2_patch_add_del_t *mp;
10124   u32 rx_sw_if_index;
10125   u8 rx_sw_if_index_set = 0;
10126   u32 tx_sw_if_index;
10127   u8 tx_sw_if_index_set = 0;
10128   u8 is_add = 1;
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, "rx_sw_if_index %d", &rx_sw_if_index))
10135         rx_sw_if_index_set = 1;
10136       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10137         tx_sw_if_index_set = 1;
10138       else if (unformat (i, "rx"))
10139         {
10140           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10141             {
10142               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10143                             &rx_sw_if_index))
10144                 rx_sw_if_index_set = 1;
10145             }
10146           else
10147             break;
10148         }
10149       else if (unformat (i, "tx"))
10150         {
10151           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10152             {
10153               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10154                             &tx_sw_if_index))
10155                 tx_sw_if_index_set = 1;
10156             }
10157           else
10158             break;
10159         }
10160       else if (unformat (i, "del"))
10161         is_add = 0;
10162       else
10163         break;
10164     }
10165
10166   if (rx_sw_if_index_set == 0)
10167     {
10168       errmsg ("missing rx interface name or rx_sw_if_index");
10169       return -99;
10170     }
10171
10172   if (tx_sw_if_index_set == 0)
10173     {
10174       errmsg ("missing tx interface name or tx_sw_if_index");
10175       return -99;
10176     }
10177
10178   M (L2_PATCH_ADD_DEL, mp);
10179
10180   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10181   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10182   mp->is_add = is_add;
10183
10184   S (mp);
10185   W (ret);
10186   return ret;
10187 }
10188
10189 u8 is_del;
10190 u8 localsid_addr[16];
10191 u8 end_psp;
10192 u8 behavior;
10193 u32 sw_if_index;
10194 u32 vlan_index;
10195 u32 fib_table;
10196 u8 nh_addr[16];
10197
10198 static int
10199 api_sr_localsid_add_del (vat_main_t * vam)
10200 {
10201   unformat_input_t *i = vam->input;
10202   vl_api_sr_localsid_add_del_t *mp;
10203
10204   u8 is_del;
10205   ip6_address_t localsid;
10206   u8 end_psp = 0;
10207   u8 behavior = ~0;
10208   u32 sw_if_index;
10209   u32 fib_table = ~(u32) 0;
10210   ip6_address_t nh_addr6;
10211   ip4_address_t nh_addr4;
10212   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10213   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10214
10215   bool nexthop_set = 0;
10216
10217   int ret;
10218
10219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (i, "del"))
10222         is_del = 1;
10223       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10224       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10225         nexthop_set = 1;
10226       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10227         nexthop_set = 1;
10228       else if (unformat (i, "behavior %u", &behavior));
10229       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10230       else if (unformat (i, "fib-table %u", &fib_table));
10231       else if (unformat (i, "end.psp %u", &behavior));
10232       else
10233         break;
10234     }
10235
10236   M (SR_LOCALSID_ADD_DEL, mp);
10237
10238   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10239   if (nexthop_set)
10240     {
10241       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10242       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10243     }
10244   mp->behavior = behavior;
10245   mp->sw_if_index = ntohl (sw_if_index);
10246   mp->fib_table = ntohl (fib_table);
10247   mp->end_psp = end_psp;
10248   mp->is_del = is_del;
10249
10250   S (mp);
10251   W (ret);
10252   return ret;
10253 }
10254
10255 static int
10256 api_ioam_enable (vat_main_t * vam)
10257 {
10258   unformat_input_t *input = vam->input;
10259   vl_api_ioam_enable_t *mp;
10260   u32 id = 0;
10261   int has_trace_option = 0;
10262   int has_pot_option = 0;
10263   int has_seqno_option = 0;
10264   int has_analyse_option = 0;
10265   int ret;
10266
10267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10268     {
10269       if (unformat (input, "trace"))
10270         has_trace_option = 1;
10271       else if (unformat (input, "pot"))
10272         has_pot_option = 1;
10273       else if (unformat (input, "seqno"))
10274         has_seqno_option = 1;
10275       else if (unformat (input, "analyse"))
10276         has_analyse_option = 1;
10277       else
10278         break;
10279     }
10280   M (IOAM_ENABLE, mp);
10281   mp->id = htons (id);
10282   mp->seqno = has_seqno_option;
10283   mp->analyse = has_analyse_option;
10284   mp->pot_enable = has_pot_option;
10285   mp->trace_enable = has_trace_option;
10286
10287   S (mp);
10288   W (ret);
10289   return ret;
10290 }
10291
10292
10293 static int
10294 api_ioam_disable (vat_main_t * vam)
10295 {
10296   vl_api_ioam_disable_t *mp;
10297   int ret;
10298
10299   M (IOAM_DISABLE, mp);
10300   S (mp);
10301   W (ret);
10302   return ret;
10303 }
10304
10305 #define foreach_tcp_proto_field                 \
10306 _(src_port)                                     \
10307 _(dst_port)
10308
10309 #define foreach_udp_proto_field                 \
10310 _(src_port)                                     \
10311 _(dst_port)
10312
10313 #define foreach_ip4_proto_field                 \
10314 _(src_address)                                  \
10315 _(dst_address)                                  \
10316 _(tos)                                          \
10317 _(length)                                       \
10318 _(fragment_id)                                  \
10319 _(ttl)                                          \
10320 _(protocol)                                     \
10321 _(checksum)
10322
10323 typedef struct
10324 {
10325   u16 src_port, dst_port;
10326 } tcpudp_header_t;
10327
10328 #if VPP_API_TEST_BUILTIN == 0
10329 uword
10330 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10331 {
10332   u8 **maskp = va_arg (*args, u8 **);
10333   u8 *mask = 0;
10334   u8 found_something = 0;
10335   tcp_header_t *tcp;
10336
10337 #define _(a) u8 a=0;
10338   foreach_tcp_proto_field;
10339 #undef _
10340
10341   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10342     {
10343       if (0);
10344 #define _(a) else if (unformat (input, #a)) a=1;
10345       foreach_tcp_proto_field
10346 #undef _
10347         else
10348         break;
10349     }
10350
10351 #define _(a) found_something += a;
10352   foreach_tcp_proto_field;
10353 #undef _
10354
10355   if (found_something == 0)
10356     return 0;
10357
10358   vec_validate (mask, sizeof (*tcp) - 1);
10359
10360   tcp = (tcp_header_t *) mask;
10361
10362 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10363   foreach_tcp_proto_field;
10364 #undef _
10365
10366   *maskp = mask;
10367   return 1;
10368 }
10369
10370 uword
10371 unformat_udp_mask (unformat_input_t * input, va_list * args)
10372 {
10373   u8 **maskp = va_arg (*args, u8 **);
10374   u8 *mask = 0;
10375   u8 found_something = 0;
10376   udp_header_t *udp;
10377
10378 #define _(a) u8 a=0;
10379   foreach_udp_proto_field;
10380 #undef _
10381
10382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10383     {
10384       if (0);
10385 #define _(a) else if (unformat (input, #a)) a=1;
10386       foreach_udp_proto_field
10387 #undef _
10388         else
10389         break;
10390     }
10391
10392 #define _(a) found_something += a;
10393   foreach_udp_proto_field;
10394 #undef _
10395
10396   if (found_something == 0)
10397     return 0;
10398
10399   vec_validate (mask, sizeof (*udp) - 1);
10400
10401   udp = (udp_header_t *) mask;
10402
10403 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10404   foreach_udp_proto_field;
10405 #undef _
10406
10407   *maskp = mask;
10408   return 1;
10409 }
10410
10411 uword
10412 unformat_l4_mask (unformat_input_t * input, va_list * args)
10413 {
10414   u8 **maskp = va_arg (*args, u8 **);
10415   u16 src_port = 0, dst_port = 0;
10416   tcpudp_header_t *tcpudp;
10417
10418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10419     {
10420       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10421         return 1;
10422       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10423         return 1;
10424       else if (unformat (input, "src_port"))
10425         src_port = 0xFFFF;
10426       else if (unformat (input, "dst_port"))
10427         dst_port = 0xFFFF;
10428       else
10429         return 0;
10430     }
10431
10432   if (!src_port && !dst_port)
10433     return 0;
10434
10435   u8 *mask = 0;
10436   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10437
10438   tcpudp = (tcpudp_header_t *) mask;
10439   tcpudp->src_port = src_port;
10440   tcpudp->dst_port = dst_port;
10441
10442   *maskp = mask;
10443
10444   return 1;
10445 }
10446
10447 uword
10448 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10449 {
10450   u8 **maskp = va_arg (*args, u8 **);
10451   u8 *mask = 0;
10452   u8 found_something = 0;
10453   ip4_header_t *ip;
10454
10455 #define _(a) u8 a=0;
10456   foreach_ip4_proto_field;
10457 #undef _
10458   u8 version = 0;
10459   u8 hdr_length = 0;
10460
10461
10462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10463     {
10464       if (unformat (input, "version"))
10465         version = 1;
10466       else if (unformat (input, "hdr_length"))
10467         hdr_length = 1;
10468       else if (unformat (input, "src"))
10469         src_address = 1;
10470       else if (unformat (input, "dst"))
10471         dst_address = 1;
10472       else if (unformat (input, "proto"))
10473         protocol = 1;
10474
10475 #define _(a) else if (unformat (input, #a)) a=1;
10476       foreach_ip4_proto_field
10477 #undef _
10478         else
10479         break;
10480     }
10481
10482 #define _(a) found_something += a;
10483   foreach_ip4_proto_field;
10484 #undef _
10485
10486   if (found_something == 0)
10487     return 0;
10488
10489   vec_validate (mask, sizeof (*ip) - 1);
10490
10491   ip = (ip4_header_t *) mask;
10492
10493 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10494   foreach_ip4_proto_field;
10495 #undef _
10496
10497   ip->ip_version_and_header_length = 0;
10498
10499   if (version)
10500     ip->ip_version_and_header_length |= 0xF0;
10501
10502   if (hdr_length)
10503     ip->ip_version_and_header_length |= 0x0F;
10504
10505   *maskp = mask;
10506   return 1;
10507 }
10508
10509 #define foreach_ip6_proto_field                 \
10510 _(src_address)                                  \
10511 _(dst_address)                                  \
10512 _(payload_length)                               \
10513 _(hop_limit)                                    \
10514 _(protocol)
10515
10516 uword
10517 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10518 {
10519   u8 **maskp = va_arg (*args, u8 **);
10520   u8 *mask = 0;
10521   u8 found_something = 0;
10522   ip6_header_t *ip;
10523   u32 ip_version_traffic_class_and_flow_label;
10524
10525 #define _(a) u8 a=0;
10526   foreach_ip6_proto_field;
10527 #undef _
10528   u8 version = 0;
10529   u8 traffic_class = 0;
10530   u8 flow_label = 0;
10531
10532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10533     {
10534       if (unformat (input, "version"))
10535         version = 1;
10536       else if (unformat (input, "traffic-class"))
10537         traffic_class = 1;
10538       else if (unformat (input, "flow-label"))
10539         flow_label = 1;
10540       else if (unformat (input, "src"))
10541         src_address = 1;
10542       else if (unformat (input, "dst"))
10543         dst_address = 1;
10544       else if (unformat (input, "proto"))
10545         protocol = 1;
10546
10547 #define _(a) else if (unformat (input, #a)) a=1;
10548       foreach_ip6_proto_field
10549 #undef _
10550         else
10551         break;
10552     }
10553
10554 #define _(a) found_something += a;
10555   foreach_ip6_proto_field;
10556 #undef _
10557
10558   if (found_something == 0)
10559     return 0;
10560
10561   vec_validate (mask, sizeof (*ip) - 1);
10562
10563   ip = (ip6_header_t *) mask;
10564
10565 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10566   foreach_ip6_proto_field;
10567 #undef _
10568
10569   ip_version_traffic_class_and_flow_label = 0;
10570
10571   if (version)
10572     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10573
10574   if (traffic_class)
10575     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10576
10577   if (flow_label)
10578     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10579
10580   ip->ip_version_traffic_class_and_flow_label =
10581     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10582
10583   *maskp = mask;
10584   return 1;
10585 }
10586
10587 uword
10588 unformat_l3_mask (unformat_input_t * input, va_list * args)
10589 {
10590   u8 **maskp = va_arg (*args, u8 **);
10591
10592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10593     {
10594       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10595         return 1;
10596       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10597         return 1;
10598       else
10599         break;
10600     }
10601   return 0;
10602 }
10603
10604 uword
10605 unformat_l2_mask (unformat_input_t * input, va_list * args)
10606 {
10607   u8 **maskp = va_arg (*args, u8 **);
10608   u8 *mask = 0;
10609   u8 src = 0;
10610   u8 dst = 0;
10611   u8 proto = 0;
10612   u8 tag1 = 0;
10613   u8 tag2 = 0;
10614   u8 ignore_tag1 = 0;
10615   u8 ignore_tag2 = 0;
10616   u8 cos1 = 0;
10617   u8 cos2 = 0;
10618   u8 dot1q = 0;
10619   u8 dot1ad = 0;
10620   int len = 14;
10621
10622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10623     {
10624       if (unformat (input, "src"))
10625         src = 1;
10626       else if (unformat (input, "dst"))
10627         dst = 1;
10628       else if (unformat (input, "proto"))
10629         proto = 1;
10630       else if (unformat (input, "tag1"))
10631         tag1 = 1;
10632       else if (unformat (input, "tag2"))
10633         tag2 = 1;
10634       else if (unformat (input, "ignore-tag1"))
10635         ignore_tag1 = 1;
10636       else if (unformat (input, "ignore-tag2"))
10637         ignore_tag2 = 1;
10638       else if (unformat (input, "cos1"))
10639         cos1 = 1;
10640       else if (unformat (input, "cos2"))
10641         cos2 = 1;
10642       else if (unformat (input, "dot1q"))
10643         dot1q = 1;
10644       else if (unformat (input, "dot1ad"))
10645         dot1ad = 1;
10646       else
10647         break;
10648     }
10649   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10650        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10651     return 0;
10652
10653   if (tag1 || ignore_tag1 || cos1 || dot1q)
10654     len = 18;
10655   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10656     len = 22;
10657
10658   vec_validate (mask, len - 1);
10659
10660   if (dst)
10661     clib_memset (mask, 0xff, 6);
10662
10663   if (src)
10664     clib_memset (mask + 6, 0xff, 6);
10665
10666   if (tag2 || dot1ad)
10667     {
10668       /* inner vlan tag */
10669       if (tag2)
10670         {
10671           mask[19] = 0xff;
10672           mask[18] = 0x0f;
10673         }
10674       if (cos2)
10675         mask[18] |= 0xe0;
10676       if (proto)
10677         mask[21] = mask[20] = 0xff;
10678       if (tag1)
10679         {
10680           mask[15] = 0xff;
10681           mask[14] = 0x0f;
10682         }
10683       if (cos1)
10684         mask[14] |= 0xe0;
10685       *maskp = mask;
10686       return 1;
10687     }
10688   if (tag1 | dot1q)
10689     {
10690       if (tag1)
10691         {
10692           mask[15] = 0xff;
10693           mask[14] = 0x0f;
10694         }
10695       if (cos1)
10696         mask[14] |= 0xe0;
10697       if (proto)
10698         mask[16] = mask[17] = 0xff;
10699
10700       *maskp = mask;
10701       return 1;
10702     }
10703   if (cos2)
10704     mask[18] |= 0xe0;
10705   if (cos1)
10706     mask[14] |= 0xe0;
10707   if (proto)
10708     mask[12] = mask[13] = 0xff;
10709
10710   *maskp = mask;
10711   return 1;
10712 }
10713
10714 uword
10715 unformat_classify_mask (unformat_input_t * input, va_list * args)
10716 {
10717   u8 **maskp = va_arg (*args, u8 **);
10718   u32 *skipp = va_arg (*args, u32 *);
10719   u32 *matchp = va_arg (*args, u32 *);
10720   u32 match;
10721   u8 *mask = 0;
10722   u8 *l2 = 0;
10723   u8 *l3 = 0;
10724   u8 *l4 = 0;
10725   int i;
10726
10727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10728     {
10729       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10730         ;
10731       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10732         ;
10733       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10734         ;
10735       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10736         ;
10737       else
10738         break;
10739     }
10740
10741   if (l4 && !l3)
10742     {
10743       vec_free (mask);
10744       vec_free (l2);
10745       vec_free (l4);
10746       return 0;
10747     }
10748
10749   if (mask || l2 || l3 || l4)
10750     {
10751       if (l2 || l3 || l4)
10752         {
10753           /* "With a free Ethernet header in every package" */
10754           if (l2 == 0)
10755             vec_validate (l2, 13);
10756           mask = l2;
10757           if (vec_len (l3))
10758             {
10759               vec_append (mask, l3);
10760               vec_free (l3);
10761             }
10762           if (vec_len (l4))
10763             {
10764               vec_append (mask, l4);
10765               vec_free (l4);
10766             }
10767         }
10768
10769       /* Scan forward looking for the first significant mask octet */
10770       for (i = 0; i < vec_len (mask); i++)
10771         if (mask[i])
10772           break;
10773
10774       /* compute (skip, match) params */
10775       *skipp = i / sizeof (u32x4);
10776       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10777
10778       /* Pad mask to an even multiple of the vector size */
10779       while (vec_len (mask) % sizeof (u32x4))
10780         vec_add1 (mask, 0);
10781
10782       match = vec_len (mask) / sizeof (u32x4);
10783
10784       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10785         {
10786           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10787           if (*tmp || *(tmp + 1))
10788             break;
10789           match--;
10790         }
10791       if (match == 0)
10792         clib_warning ("BUG: match 0");
10793
10794       _vec_len (mask) = match * sizeof (u32x4);
10795
10796       *matchp = match;
10797       *maskp = mask;
10798
10799       return 1;
10800     }
10801
10802   return 0;
10803 }
10804 #endif /* VPP_API_TEST_BUILTIN */
10805
10806 #define foreach_l2_next                         \
10807 _(drop, DROP)                                   \
10808 _(ethernet, ETHERNET_INPUT)                     \
10809 _(ip4, IP4_INPUT)                               \
10810 _(ip6, IP6_INPUT)
10811
10812 uword
10813 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10814 {
10815   u32 *miss_next_indexp = va_arg (*args, u32 *);
10816   u32 next_index = 0;
10817   u32 tmp;
10818
10819 #define _(n,N) \
10820   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10821   foreach_l2_next;
10822 #undef _
10823
10824   if (unformat (input, "%d", &tmp))
10825     {
10826       next_index = tmp;
10827       goto out;
10828     }
10829
10830   return 0;
10831
10832 out:
10833   *miss_next_indexp = next_index;
10834   return 1;
10835 }
10836
10837 #define foreach_ip_next                         \
10838 _(drop, DROP)                                   \
10839 _(local, LOCAL)                                 \
10840 _(rewrite, REWRITE)
10841
10842 uword
10843 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10844 {
10845   u32 *miss_next_indexp = va_arg (*args, u32 *);
10846   u32 next_index = 0;
10847   u32 tmp;
10848
10849 #define _(n,N) \
10850   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10851   foreach_ip_next;
10852 #undef _
10853
10854   if (unformat (input, "%d", &tmp))
10855     {
10856       next_index = tmp;
10857       goto out;
10858     }
10859
10860   return 0;
10861
10862 out:
10863   *miss_next_indexp = next_index;
10864   return 1;
10865 }
10866
10867 #define foreach_acl_next                        \
10868 _(deny, DENY)
10869
10870 uword
10871 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10872 {
10873   u32 *miss_next_indexp = va_arg (*args, u32 *);
10874   u32 next_index = 0;
10875   u32 tmp;
10876
10877 #define _(n,N) \
10878   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10879   foreach_acl_next;
10880 #undef _
10881
10882   if (unformat (input, "permit"))
10883     {
10884       next_index = ~0;
10885       goto out;
10886     }
10887   else if (unformat (input, "%d", &tmp))
10888     {
10889       next_index = tmp;
10890       goto out;
10891     }
10892
10893   return 0;
10894
10895 out:
10896   *miss_next_indexp = next_index;
10897   return 1;
10898 }
10899
10900 uword
10901 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10902 {
10903   u32 *r = va_arg (*args, u32 *);
10904
10905   if (unformat (input, "conform-color"))
10906     *r = POLICE_CONFORM;
10907   else if (unformat (input, "exceed-color"))
10908     *r = POLICE_EXCEED;
10909   else
10910     return 0;
10911
10912   return 1;
10913 }
10914
10915 static int
10916 api_classify_add_del_table (vat_main_t * vam)
10917 {
10918   unformat_input_t *i = vam->input;
10919   vl_api_classify_add_del_table_t *mp;
10920
10921   u32 nbuckets = 2;
10922   u32 skip = ~0;
10923   u32 match = ~0;
10924   int is_add = 1;
10925   int del_chain = 0;
10926   u32 table_index = ~0;
10927   u32 next_table_index = ~0;
10928   u32 miss_next_index = ~0;
10929   u32 memory_size = 32 << 20;
10930   u8 *mask = 0;
10931   u32 current_data_flag = 0;
10932   int current_data_offset = 0;
10933   int ret;
10934
10935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10936     {
10937       if (unformat (i, "del"))
10938         is_add = 0;
10939       else if (unformat (i, "del-chain"))
10940         {
10941           is_add = 0;
10942           del_chain = 1;
10943         }
10944       else if (unformat (i, "buckets %d", &nbuckets))
10945         ;
10946       else if (unformat (i, "memory_size %d", &memory_size))
10947         ;
10948       else if (unformat (i, "skip %d", &skip))
10949         ;
10950       else if (unformat (i, "match %d", &match))
10951         ;
10952       else if (unformat (i, "table %d", &table_index))
10953         ;
10954       else if (unformat (i, "mask %U", unformat_classify_mask,
10955                          &mask, &skip, &match))
10956         ;
10957       else if (unformat (i, "next-table %d", &next_table_index))
10958         ;
10959       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10960                          &miss_next_index))
10961         ;
10962       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10963                          &miss_next_index))
10964         ;
10965       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10966                          &miss_next_index))
10967         ;
10968       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10969         ;
10970       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10971         ;
10972       else
10973         break;
10974     }
10975
10976   if (is_add && mask == 0)
10977     {
10978       errmsg ("Mask required");
10979       return -99;
10980     }
10981
10982   if (is_add && skip == ~0)
10983     {
10984       errmsg ("skip count required");
10985       return -99;
10986     }
10987
10988   if (is_add && match == ~0)
10989     {
10990       errmsg ("match count required");
10991       return -99;
10992     }
10993
10994   if (!is_add && table_index == ~0)
10995     {
10996       errmsg ("table index required for delete");
10997       return -99;
10998     }
10999
11000   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11001
11002   mp->is_add = is_add;
11003   mp->del_chain = del_chain;
11004   mp->table_index = ntohl (table_index);
11005   mp->nbuckets = ntohl (nbuckets);
11006   mp->memory_size = ntohl (memory_size);
11007   mp->skip_n_vectors = ntohl (skip);
11008   mp->match_n_vectors = ntohl (match);
11009   mp->next_table_index = ntohl (next_table_index);
11010   mp->miss_next_index = ntohl (miss_next_index);
11011   mp->current_data_flag = ntohl (current_data_flag);
11012   mp->current_data_offset = ntohl (current_data_offset);
11013   mp->mask_len = ntohl (vec_len (mask));
11014   clib_memcpy (mp->mask, mask, vec_len (mask));
11015
11016   vec_free (mask);
11017
11018   S (mp);
11019   W (ret);
11020   return ret;
11021 }
11022
11023 #if VPP_API_TEST_BUILTIN == 0
11024 uword
11025 unformat_l4_match (unformat_input_t * input, va_list * args)
11026 {
11027   u8 **matchp = va_arg (*args, u8 **);
11028
11029   u8 *proto_header = 0;
11030   int src_port = 0;
11031   int dst_port = 0;
11032
11033   tcpudp_header_t h;
11034
11035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11036     {
11037       if (unformat (input, "src_port %d", &src_port))
11038         ;
11039       else if (unformat (input, "dst_port %d", &dst_port))
11040         ;
11041       else
11042         return 0;
11043     }
11044
11045   h.src_port = clib_host_to_net_u16 (src_port);
11046   h.dst_port = clib_host_to_net_u16 (dst_port);
11047   vec_validate (proto_header, sizeof (h) - 1);
11048   memcpy (proto_header, &h, sizeof (h));
11049
11050   *matchp = proto_header;
11051
11052   return 1;
11053 }
11054
11055 uword
11056 unformat_ip4_match (unformat_input_t * input, va_list * args)
11057 {
11058   u8 **matchp = va_arg (*args, u8 **);
11059   u8 *match = 0;
11060   ip4_header_t *ip;
11061   int version = 0;
11062   u32 version_val;
11063   int hdr_length = 0;
11064   u32 hdr_length_val;
11065   int src = 0, dst = 0;
11066   ip4_address_t src_val, dst_val;
11067   int proto = 0;
11068   u32 proto_val;
11069   int tos = 0;
11070   u32 tos_val;
11071   int length = 0;
11072   u32 length_val;
11073   int fragment_id = 0;
11074   u32 fragment_id_val;
11075   int ttl = 0;
11076   int ttl_val;
11077   int checksum = 0;
11078   u32 checksum_val;
11079
11080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11081     {
11082       if (unformat (input, "version %d", &version_val))
11083         version = 1;
11084       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11085         hdr_length = 1;
11086       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11087         src = 1;
11088       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11089         dst = 1;
11090       else if (unformat (input, "proto %d", &proto_val))
11091         proto = 1;
11092       else if (unformat (input, "tos %d", &tos_val))
11093         tos = 1;
11094       else if (unformat (input, "length %d", &length_val))
11095         length = 1;
11096       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11097         fragment_id = 1;
11098       else if (unformat (input, "ttl %d", &ttl_val))
11099         ttl = 1;
11100       else if (unformat (input, "checksum %d", &checksum_val))
11101         checksum = 1;
11102       else
11103         break;
11104     }
11105
11106   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11107       + ttl + checksum == 0)
11108     return 0;
11109
11110   /*
11111    * Aligned because we use the real comparison functions
11112    */
11113   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11114
11115   ip = (ip4_header_t *) match;
11116
11117   /* These are realistically matched in practice */
11118   if (src)
11119     ip->src_address.as_u32 = src_val.as_u32;
11120
11121   if (dst)
11122     ip->dst_address.as_u32 = dst_val.as_u32;
11123
11124   if (proto)
11125     ip->protocol = proto_val;
11126
11127
11128   /* These are not, but they're included for completeness */
11129   if (version)
11130     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11131
11132   if (hdr_length)
11133     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11134
11135   if (tos)
11136     ip->tos = tos_val;
11137
11138   if (length)
11139     ip->length = clib_host_to_net_u16 (length_val);
11140
11141   if (ttl)
11142     ip->ttl = ttl_val;
11143
11144   if (checksum)
11145     ip->checksum = clib_host_to_net_u16 (checksum_val);
11146
11147   *matchp = match;
11148   return 1;
11149 }
11150
11151 uword
11152 unformat_ip6_match (unformat_input_t * input, va_list * args)
11153 {
11154   u8 **matchp = va_arg (*args, u8 **);
11155   u8 *match = 0;
11156   ip6_header_t *ip;
11157   int version = 0;
11158   u32 version_val;
11159   u8 traffic_class = 0;
11160   u32 traffic_class_val = 0;
11161   u8 flow_label = 0;
11162   u8 flow_label_val;
11163   int src = 0, dst = 0;
11164   ip6_address_t src_val, dst_val;
11165   int proto = 0;
11166   u32 proto_val;
11167   int payload_length = 0;
11168   u32 payload_length_val;
11169   int hop_limit = 0;
11170   int hop_limit_val;
11171   u32 ip_version_traffic_class_and_flow_label;
11172
11173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11174     {
11175       if (unformat (input, "version %d", &version_val))
11176         version = 1;
11177       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11178         traffic_class = 1;
11179       else if (unformat (input, "flow_label %d", &flow_label_val))
11180         flow_label = 1;
11181       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11182         src = 1;
11183       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11184         dst = 1;
11185       else if (unformat (input, "proto %d", &proto_val))
11186         proto = 1;
11187       else if (unformat (input, "payload_length %d", &payload_length_val))
11188         payload_length = 1;
11189       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11190         hop_limit = 1;
11191       else
11192         break;
11193     }
11194
11195   if (version + traffic_class + flow_label + src + dst + proto +
11196       payload_length + hop_limit == 0)
11197     return 0;
11198
11199   /*
11200    * Aligned because we use the real comparison functions
11201    */
11202   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11203
11204   ip = (ip6_header_t *) match;
11205
11206   if (src)
11207     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11208
11209   if (dst)
11210     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11211
11212   if (proto)
11213     ip->protocol = proto_val;
11214
11215   ip_version_traffic_class_and_flow_label = 0;
11216
11217   if (version)
11218     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11219
11220   if (traffic_class)
11221     ip_version_traffic_class_and_flow_label |=
11222       (traffic_class_val & 0xFF) << 20;
11223
11224   if (flow_label)
11225     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11226
11227   ip->ip_version_traffic_class_and_flow_label =
11228     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11229
11230   if (payload_length)
11231     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11232
11233   if (hop_limit)
11234     ip->hop_limit = hop_limit_val;
11235
11236   *matchp = match;
11237   return 1;
11238 }
11239
11240 uword
11241 unformat_l3_match (unformat_input_t * input, va_list * args)
11242 {
11243   u8 **matchp = va_arg (*args, u8 **);
11244
11245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11246     {
11247       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11248         return 1;
11249       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11250         return 1;
11251       else
11252         break;
11253     }
11254   return 0;
11255 }
11256
11257 uword
11258 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11259 {
11260   u8 *tagp = va_arg (*args, u8 *);
11261   u32 tag;
11262
11263   if (unformat (input, "%d", &tag))
11264     {
11265       tagp[0] = (tag >> 8) & 0x0F;
11266       tagp[1] = tag & 0xFF;
11267       return 1;
11268     }
11269
11270   return 0;
11271 }
11272
11273 uword
11274 unformat_l2_match (unformat_input_t * input, va_list * args)
11275 {
11276   u8 **matchp = va_arg (*args, u8 **);
11277   u8 *match = 0;
11278   u8 src = 0;
11279   u8 src_val[6];
11280   u8 dst = 0;
11281   u8 dst_val[6];
11282   u8 proto = 0;
11283   u16 proto_val;
11284   u8 tag1 = 0;
11285   u8 tag1_val[2];
11286   u8 tag2 = 0;
11287   u8 tag2_val[2];
11288   int len = 14;
11289   u8 ignore_tag1 = 0;
11290   u8 ignore_tag2 = 0;
11291   u8 cos1 = 0;
11292   u8 cos2 = 0;
11293   u32 cos1_val = 0;
11294   u32 cos2_val = 0;
11295
11296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11297     {
11298       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11299         src = 1;
11300       else
11301         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11302         dst = 1;
11303       else if (unformat (input, "proto %U",
11304                          unformat_ethernet_type_host_byte_order, &proto_val))
11305         proto = 1;
11306       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11307         tag1 = 1;
11308       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11309         tag2 = 1;
11310       else if (unformat (input, "ignore-tag1"))
11311         ignore_tag1 = 1;
11312       else if (unformat (input, "ignore-tag2"))
11313         ignore_tag2 = 1;
11314       else if (unformat (input, "cos1 %d", &cos1_val))
11315         cos1 = 1;
11316       else if (unformat (input, "cos2 %d", &cos2_val))
11317         cos2 = 1;
11318       else
11319         break;
11320     }
11321   if ((src + dst + proto + tag1 + tag2 +
11322        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11323     return 0;
11324
11325   if (tag1 || ignore_tag1 || cos1)
11326     len = 18;
11327   if (tag2 || ignore_tag2 || cos2)
11328     len = 22;
11329
11330   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11331
11332   if (dst)
11333     clib_memcpy (match, dst_val, 6);
11334
11335   if (src)
11336     clib_memcpy (match + 6, src_val, 6);
11337
11338   if (tag2)
11339     {
11340       /* inner vlan tag */
11341       match[19] = tag2_val[1];
11342       match[18] = tag2_val[0];
11343       if (cos2)
11344         match[18] |= (cos2_val & 0x7) << 5;
11345       if (proto)
11346         {
11347           match[21] = proto_val & 0xff;
11348           match[20] = proto_val >> 8;
11349         }
11350       if (tag1)
11351         {
11352           match[15] = tag1_val[1];
11353           match[14] = tag1_val[0];
11354         }
11355       if (cos1)
11356         match[14] |= (cos1_val & 0x7) << 5;
11357       *matchp = match;
11358       return 1;
11359     }
11360   if (tag1)
11361     {
11362       match[15] = tag1_val[1];
11363       match[14] = tag1_val[0];
11364       if (proto)
11365         {
11366           match[17] = proto_val & 0xff;
11367           match[16] = proto_val >> 8;
11368         }
11369       if (cos1)
11370         match[14] |= (cos1_val & 0x7) << 5;
11371
11372       *matchp = match;
11373       return 1;
11374     }
11375   if (cos2)
11376     match[18] |= (cos2_val & 0x7) << 5;
11377   if (cos1)
11378     match[14] |= (cos1_val & 0x7) << 5;
11379   if (proto)
11380     {
11381       match[13] = proto_val & 0xff;
11382       match[12] = proto_val >> 8;
11383     }
11384
11385   *matchp = match;
11386   return 1;
11387 }
11388
11389 uword
11390 unformat_qos_source (unformat_input_t * input, va_list * args)
11391 {
11392   int *qs = va_arg (*args, int *);
11393
11394   if (unformat (input, "ip"))
11395     *qs = QOS_SOURCE_IP;
11396   else if (unformat (input, "mpls"))
11397     *qs = QOS_SOURCE_MPLS;
11398   else if (unformat (input, "ext"))
11399     *qs = QOS_SOURCE_EXT;
11400   else if (unformat (input, "vlan"))
11401     *qs = QOS_SOURCE_VLAN;
11402   else
11403     return 0;
11404
11405   return 1;
11406 }
11407 #endif
11408
11409 uword
11410 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11411 {
11412   u8 **matchp = va_arg (*args, u8 **);
11413   u32 skip_n_vectors = va_arg (*args, u32);
11414   u32 match_n_vectors = va_arg (*args, u32);
11415
11416   u8 *match = 0;
11417   u8 *l2 = 0;
11418   u8 *l3 = 0;
11419   u8 *l4 = 0;
11420
11421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11422     {
11423       if (unformat (input, "hex %U", unformat_hex_string, &match))
11424         ;
11425       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11426         ;
11427       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11428         ;
11429       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11430         ;
11431       else
11432         break;
11433     }
11434
11435   if (l4 && !l3)
11436     {
11437       vec_free (match);
11438       vec_free (l2);
11439       vec_free (l4);
11440       return 0;
11441     }
11442
11443   if (match || l2 || l3 || l4)
11444     {
11445       if (l2 || l3 || l4)
11446         {
11447           /* "Win a free Ethernet header in every packet" */
11448           if (l2 == 0)
11449             vec_validate_aligned (l2, 13, sizeof (u32x4));
11450           match = l2;
11451           if (vec_len (l3))
11452             {
11453               vec_append_aligned (match, l3, sizeof (u32x4));
11454               vec_free (l3);
11455             }
11456           if (vec_len (l4))
11457             {
11458               vec_append_aligned (match, l4, sizeof (u32x4));
11459               vec_free (l4);
11460             }
11461         }
11462
11463       /* Make sure the vector is big enough even if key is all 0's */
11464       vec_validate_aligned
11465         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11466          sizeof (u32x4));
11467
11468       /* Set size, include skipped vectors */
11469       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11470
11471       *matchp = match;
11472
11473       return 1;
11474     }
11475
11476   return 0;
11477 }
11478
11479 static int
11480 api_classify_add_del_session (vat_main_t * vam)
11481 {
11482   unformat_input_t *i = vam->input;
11483   vl_api_classify_add_del_session_t *mp;
11484   int is_add = 1;
11485   u32 table_index = ~0;
11486   u32 hit_next_index = ~0;
11487   u32 opaque_index = ~0;
11488   u8 *match = 0;
11489   i32 advance = 0;
11490   u32 skip_n_vectors = 0;
11491   u32 match_n_vectors = 0;
11492   u32 action = 0;
11493   u32 metadata = 0;
11494   int ret;
11495
11496   /*
11497    * Warning: you have to supply skip_n and match_n
11498    * because the API client cant simply look at the classify
11499    * table object.
11500    */
11501
11502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11503     {
11504       if (unformat (i, "del"))
11505         is_add = 0;
11506       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11507                          &hit_next_index))
11508         ;
11509       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11510                          &hit_next_index))
11511         ;
11512       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11513                          &hit_next_index))
11514         ;
11515       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11516         ;
11517       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11518         ;
11519       else if (unformat (i, "opaque-index %d", &opaque_index))
11520         ;
11521       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11522         ;
11523       else if (unformat (i, "match_n %d", &match_n_vectors))
11524         ;
11525       else if (unformat (i, "match %U", api_unformat_classify_match,
11526                          &match, skip_n_vectors, match_n_vectors))
11527         ;
11528       else if (unformat (i, "advance %d", &advance))
11529         ;
11530       else if (unformat (i, "table-index %d", &table_index))
11531         ;
11532       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11533         action = 1;
11534       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11535         action = 2;
11536       else if (unformat (i, "action %d", &action))
11537         ;
11538       else if (unformat (i, "metadata %d", &metadata))
11539         ;
11540       else
11541         break;
11542     }
11543
11544   if (table_index == ~0)
11545     {
11546       errmsg ("Table index required");
11547       return -99;
11548     }
11549
11550   if (is_add && match == 0)
11551     {
11552       errmsg ("Match value required");
11553       return -99;
11554     }
11555
11556   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11557
11558   mp->is_add = is_add;
11559   mp->table_index = ntohl (table_index);
11560   mp->hit_next_index = ntohl (hit_next_index);
11561   mp->opaque_index = ntohl (opaque_index);
11562   mp->advance = ntohl (advance);
11563   mp->action = action;
11564   mp->metadata = ntohl (metadata);
11565   mp->match_len = ntohl (vec_len (match));
11566   clib_memcpy (mp->match, match, vec_len (match));
11567   vec_free (match);
11568
11569   S (mp);
11570   W (ret);
11571   return ret;
11572 }
11573
11574 static int
11575 api_classify_set_interface_ip_table (vat_main_t * vam)
11576 {
11577   unformat_input_t *i = vam->input;
11578   vl_api_classify_set_interface_ip_table_t *mp;
11579   u32 sw_if_index;
11580   int sw_if_index_set;
11581   u32 table_index = ~0;
11582   u8 is_ipv6 = 0;
11583   int ret;
11584
11585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11588         sw_if_index_set = 1;
11589       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11590         sw_if_index_set = 1;
11591       else if (unformat (i, "table %d", &table_index))
11592         ;
11593       else
11594         {
11595           clib_warning ("parse error '%U'", format_unformat_error, i);
11596           return -99;
11597         }
11598     }
11599
11600   if (sw_if_index_set == 0)
11601     {
11602       errmsg ("missing interface name or sw_if_index");
11603       return -99;
11604     }
11605
11606
11607   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11608
11609   mp->sw_if_index = ntohl (sw_if_index);
11610   mp->table_index = ntohl (table_index);
11611   mp->is_ipv6 = is_ipv6;
11612
11613   S (mp);
11614   W (ret);
11615   return ret;
11616 }
11617
11618 static int
11619 api_classify_set_interface_l2_tables (vat_main_t * vam)
11620 {
11621   unformat_input_t *i = vam->input;
11622   vl_api_classify_set_interface_l2_tables_t *mp;
11623   u32 sw_if_index;
11624   int sw_if_index_set;
11625   u32 ip4_table_index = ~0;
11626   u32 ip6_table_index = ~0;
11627   u32 other_table_index = ~0;
11628   u32 is_input = 1;
11629   int ret;
11630
11631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11632     {
11633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11634         sw_if_index_set = 1;
11635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11636         sw_if_index_set = 1;
11637       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11638         ;
11639       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11640         ;
11641       else if (unformat (i, "other-table %d", &other_table_index))
11642         ;
11643       else if (unformat (i, "is-input %d", &is_input))
11644         ;
11645       else
11646         {
11647           clib_warning ("parse error '%U'", format_unformat_error, i);
11648           return -99;
11649         }
11650     }
11651
11652   if (sw_if_index_set == 0)
11653     {
11654       errmsg ("missing interface name or sw_if_index");
11655       return -99;
11656     }
11657
11658
11659   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11660
11661   mp->sw_if_index = ntohl (sw_if_index);
11662   mp->ip4_table_index = ntohl (ip4_table_index);
11663   mp->ip6_table_index = ntohl (ip6_table_index);
11664   mp->other_table_index = ntohl (other_table_index);
11665   mp->is_input = (u8) is_input;
11666
11667   S (mp);
11668   W (ret);
11669   return ret;
11670 }
11671
11672 static int
11673 api_set_ipfix_exporter (vat_main_t * vam)
11674 {
11675   unformat_input_t *i = vam->input;
11676   vl_api_set_ipfix_exporter_t *mp;
11677   ip4_address_t collector_address;
11678   u8 collector_address_set = 0;
11679   u32 collector_port = ~0;
11680   ip4_address_t src_address;
11681   u8 src_address_set = 0;
11682   u32 vrf_id = ~0;
11683   u32 path_mtu = ~0;
11684   u32 template_interval = ~0;
11685   u8 udp_checksum = 0;
11686   int ret;
11687
11688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (i, "collector_address %U", unformat_ip4_address,
11691                     &collector_address))
11692         collector_address_set = 1;
11693       else if (unformat (i, "collector_port %d", &collector_port))
11694         ;
11695       else if (unformat (i, "src_address %U", unformat_ip4_address,
11696                          &src_address))
11697         src_address_set = 1;
11698       else if (unformat (i, "vrf_id %d", &vrf_id))
11699         ;
11700       else if (unformat (i, "path_mtu %d", &path_mtu))
11701         ;
11702       else if (unformat (i, "template_interval %d", &template_interval))
11703         ;
11704       else if (unformat (i, "udp_checksum"))
11705         udp_checksum = 1;
11706       else
11707         break;
11708     }
11709
11710   if (collector_address_set == 0)
11711     {
11712       errmsg ("collector_address required");
11713       return -99;
11714     }
11715
11716   if (src_address_set == 0)
11717     {
11718       errmsg ("src_address required");
11719       return -99;
11720     }
11721
11722   M (SET_IPFIX_EXPORTER, mp);
11723
11724   memcpy (mp->collector_address, collector_address.data,
11725           sizeof (collector_address.data));
11726   mp->collector_port = htons ((u16) collector_port);
11727   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11728   mp->vrf_id = htonl (vrf_id);
11729   mp->path_mtu = htonl (path_mtu);
11730   mp->template_interval = htonl (template_interval);
11731   mp->udp_checksum = udp_checksum;
11732
11733   S (mp);
11734   W (ret);
11735   return ret;
11736 }
11737
11738 static int
11739 api_set_ipfix_classify_stream (vat_main_t * vam)
11740 {
11741   unformat_input_t *i = vam->input;
11742   vl_api_set_ipfix_classify_stream_t *mp;
11743   u32 domain_id = 0;
11744   u32 src_port = UDP_DST_PORT_ipfix;
11745   int ret;
11746
11747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11748     {
11749       if (unformat (i, "domain %d", &domain_id))
11750         ;
11751       else if (unformat (i, "src_port %d", &src_port))
11752         ;
11753       else
11754         {
11755           errmsg ("unknown input `%U'", format_unformat_error, i);
11756           return -99;
11757         }
11758     }
11759
11760   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11761
11762   mp->domain_id = htonl (domain_id);
11763   mp->src_port = htons ((u16) src_port);
11764
11765   S (mp);
11766   W (ret);
11767   return ret;
11768 }
11769
11770 static int
11771 api_ipfix_classify_table_add_del (vat_main_t * vam)
11772 {
11773   unformat_input_t *i = vam->input;
11774   vl_api_ipfix_classify_table_add_del_t *mp;
11775   int is_add = -1;
11776   u32 classify_table_index = ~0;
11777   u8 ip_version = 0;
11778   u8 transport_protocol = 255;
11779   int ret;
11780
11781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11782     {
11783       if (unformat (i, "add"))
11784         is_add = 1;
11785       else if (unformat (i, "del"))
11786         is_add = 0;
11787       else if (unformat (i, "table %d", &classify_table_index))
11788         ;
11789       else if (unformat (i, "ip4"))
11790         ip_version = 4;
11791       else if (unformat (i, "ip6"))
11792         ip_version = 6;
11793       else if (unformat (i, "tcp"))
11794         transport_protocol = 6;
11795       else if (unformat (i, "udp"))
11796         transport_protocol = 17;
11797       else
11798         {
11799           errmsg ("unknown input `%U'", format_unformat_error, i);
11800           return -99;
11801         }
11802     }
11803
11804   if (is_add == -1)
11805     {
11806       errmsg ("expecting: add|del");
11807       return -99;
11808     }
11809   if (classify_table_index == ~0)
11810     {
11811       errmsg ("classifier table not specified");
11812       return -99;
11813     }
11814   if (ip_version == 0)
11815     {
11816       errmsg ("IP version not specified");
11817       return -99;
11818     }
11819
11820   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11821
11822   mp->is_add = is_add;
11823   mp->table_id = htonl (classify_table_index);
11824   mp->ip_version = ip_version;
11825   mp->transport_protocol = transport_protocol;
11826
11827   S (mp);
11828   W (ret);
11829   return ret;
11830 }
11831
11832 static int
11833 api_get_node_index (vat_main_t * vam)
11834 {
11835   unformat_input_t *i = vam->input;
11836   vl_api_get_node_index_t *mp;
11837   u8 *name = 0;
11838   int ret;
11839
11840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11841     {
11842       if (unformat (i, "node %s", &name))
11843         ;
11844       else
11845         break;
11846     }
11847   if (name == 0)
11848     {
11849       errmsg ("node name required");
11850       return -99;
11851     }
11852   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11853     {
11854       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11855       return -99;
11856     }
11857
11858   M (GET_NODE_INDEX, mp);
11859   clib_memcpy (mp->node_name, name, vec_len (name));
11860   vec_free (name);
11861
11862   S (mp);
11863   W (ret);
11864   return ret;
11865 }
11866
11867 static int
11868 api_get_next_index (vat_main_t * vam)
11869 {
11870   unformat_input_t *i = vam->input;
11871   vl_api_get_next_index_t *mp;
11872   u8 *node_name = 0, *next_node_name = 0;
11873   int ret;
11874
11875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11876     {
11877       if (unformat (i, "node-name %s", &node_name))
11878         ;
11879       else if (unformat (i, "next-node-name %s", &next_node_name))
11880         break;
11881     }
11882
11883   if (node_name == 0)
11884     {
11885       errmsg ("node name required");
11886       return -99;
11887     }
11888   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11889     {
11890       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11891       return -99;
11892     }
11893
11894   if (next_node_name == 0)
11895     {
11896       errmsg ("next node name required");
11897       return -99;
11898     }
11899   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11900     {
11901       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11902       return -99;
11903     }
11904
11905   M (GET_NEXT_INDEX, mp);
11906   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11907   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11908   vec_free (node_name);
11909   vec_free (next_node_name);
11910
11911   S (mp);
11912   W (ret);
11913   return ret;
11914 }
11915
11916 static int
11917 api_add_node_next (vat_main_t * vam)
11918 {
11919   unformat_input_t *i = vam->input;
11920   vl_api_add_node_next_t *mp;
11921   u8 *name = 0;
11922   u8 *next = 0;
11923   int ret;
11924
11925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11926     {
11927       if (unformat (i, "node %s", &name))
11928         ;
11929       else if (unformat (i, "next %s", &next))
11930         ;
11931       else
11932         break;
11933     }
11934   if (name == 0)
11935     {
11936       errmsg ("node name required");
11937       return -99;
11938     }
11939   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11940     {
11941       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11942       return -99;
11943     }
11944   if (next == 0)
11945     {
11946       errmsg ("next node required");
11947       return -99;
11948     }
11949   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11950     {
11951       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11952       return -99;
11953     }
11954
11955   M (ADD_NODE_NEXT, mp);
11956   clib_memcpy (mp->node_name, name, vec_len (name));
11957   clib_memcpy (mp->next_name, next, vec_len (next));
11958   vec_free (name);
11959   vec_free (next);
11960
11961   S (mp);
11962   W (ret);
11963   return ret;
11964 }
11965
11966 static int
11967 api_l2tpv3_create_tunnel (vat_main_t * vam)
11968 {
11969   unformat_input_t *i = vam->input;
11970   ip6_address_t client_address, our_address;
11971   int client_address_set = 0;
11972   int our_address_set = 0;
11973   u32 local_session_id = 0;
11974   u32 remote_session_id = 0;
11975   u64 local_cookie = 0;
11976   u64 remote_cookie = 0;
11977   u8 l2_sublayer_present = 0;
11978   vl_api_l2tpv3_create_tunnel_t *mp;
11979   int ret;
11980
11981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11982     {
11983       if (unformat (i, "client_address %U", unformat_ip6_address,
11984                     &client_address))
11985         client_address_set = 1;
11986       else if (unformat (i, "our_address %U", unformat_ip6_address,
11987                          &our_address))
11988         our_address_set = 1;
11989       else if (unformat (i, "local_session_id %d", &local_session_id))
11990         ;
11991       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11992         ;
11993       else if (unformat (i, "local_cookie %lld", &local_cookie))
11994         ;
11995       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11996         ;
11997       else if (unformat (i, "l2-sublayer-present"))
11998         l2_sublayer_present = 1;
11999       else
12000         break;
12001     }
12002
12003   if (client_address_set == 0)
12004     {
12005       errmsg ("client_address required");
12006       return -99;
12007     }
12008
12009   if (our_address_set == 0)
12010     {
12011       errmsg ("our_address required");
12012       return -99;
12013     }
12014
12015   M (L2TPV3_CREATE_TUNNEL, mp);
12016
12017   clib_memcpy (mp->client_address, client_address.as_u8,
12018                sizeof (mp->client_address));
12019
12020   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12021
12022   mp->local_session_id = ntohl (local_session_id);
12023   mp->remote_session_id = ntohl (remote_session_id);
12024   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12025   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12026   mp->l2_sublayer_present = l2_sublayer_present;
12027   mp->is_ipv6 = 1;
12028
12029   S (mp);
12030   W (ret);
12031   return ret;
12032 }
12033
12034 static int
12035 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12036 {
12037   unformat_input_t *i = vam->input;
12038   u32 sw_if_index;
12039   u8 sw_if_index_set = 0;
12040   u64 new_local_cookie = 0;
12041   u64 new_remote_cookie = 0;
12042   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12043   int ret;
12044
12045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12046     {
12047       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12048         sw_if_index_set = 1;
12049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12050         sw_if_index_set = 1;
12051       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12052         ;
12053       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12054         ;
12055       else
12056         break;
12057     }
12058
12059   if (sw_if_index_set == 0)
12060     {
12061       errmsg ("missing interface name or sw_if_index");
12062       return -99;
12063     }
12064
12065   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12066
12067   mp->sw_if_index = ntohl (sw_if_index);
12068   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12069   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12070
12071   S (mp);
12072   W (ret);
12073   return ret;
12074 }
12075
12076 static int
12077 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12078 {
12079   unformat_input_t *i = vam->input;
12080   vl_api_l2tpv3_interface_enable_disable_t *mp;
12081   u32 sw_if_index;
12082   u8 sw_if_index_set = 0;
12083   u8 enable_disable = 1;
12084   int ret;
12085
12086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12087     {
12088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12089         sw_if_index_set = 1;
12090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12091         sw_if_index_set = 1;
12092       else if (unformat (i, "enable"))
12093         enable_disable = 1;
12094       else if (unformat (i, "disable"))
12095         enable_disable = 0;
12096       else
12097         break;
12098     }
12099
12100   if (sw_if_index_set == 0)
12101     {
12102       errmsg ("missing interface name or sw_if_index");
12103       return -99;
12104     }
12105
12106   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12107
12108   mp->sw_if_index = ntohl (sw_if_index);
12109   mp->enable_disable = enable_disable;
12110
12111   S (mp);
12112   W (ret);
12113   return ret;
12114 }
12115
12116 static int
12117 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12118 {
12119   unformat_input_t *i = vam->input;
12120   vl_api_l2tpv3_set_lookup_key_t *mp;
12121   u8 key = ~0;
12122   int ret;
12123
12124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12125     {
12126       if (unformat (i, "lookup_v6_src"))
12127         key = L2T_LOOKUP_SRC_ADDRESS;
12128       else if (unformat (i, "lookup_v6_dst"))
12129         key = L2T_LOOKUP_DST_ADDRESS;
12130       else if (unformat (i, "lookup_session_id"))
12131         key = L2T_LOOKUP_SESSION_ID;
12132       else
12133         break;
12134     }
12135
12136   if (key == (u8) ~ 0)
12137     {
12138       errmsg ("l2tp session lookup key unset");
12139       return -99;
12140     }
12141
12142   M (L2TPV3_SET_LOOKUP_KEY, mp);
12143
12144   mp->key = key;
12145
12146   S (mp);
12147   W (ret);
12148   return ret;
12149 }
12150
12151 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12152   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12153 {
12154   vat_main_t *vam = &vat_main;
12155
12156   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12157          format_ip6_address, mp->our_address,
12158          format_ip6_address, mp->client_address,
12159          clib_net_to_host_u32 (mp->sw_if_index));
12160
12161   print (vam->ofp,
12162          "   local cookies %016llx %016llx remote cookie %016llx",
12163          clib_net_to_host_u64 (mp->local_cookie[0]),
12164          clib_net_to_host_u64 (mp->local_cookie[1]),
12165          clib_net_to_host_u64 (mp->remote_cookie));
12166
12167   print (vam->ofp, "   local session-id %d remote session-id %d",
12168          clib_net_to_host_u32 (mp->local_session_id),
12169          clib_net_to_host_u32 (mp->remote_session_id));
12170
12171   print (vam->ofp, "   l2 specific sublayer %s\n",
12172          mp->l2_sublayer_present ? "preset" : "absent");
12173
12174 }
12175
12176 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12177   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12178 {
12179   vat_main_t *vam = &vat_main;
12180   vat_json_node_t *node = NULL;
12181   struct in6_addr addr;
12182
12183   if (VAT_JSON_ARRAY != vam->json_tree.type)
12184     {
12185       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12186       vat_json_init_array (&vam->json_tree);
12187     }
12188   node = vat_json_array_add (&vam->json_tree);
12189
12190   vat_json_init_object (node);
12191
12192   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12193   vat_json_object_add_ip6 (node, "our_address", addr);
12194   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12195   vat_json_object_add_ip6 (node, "client_address", addr);
12196
12197   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12198   vat_json_init_array (lc);
12199   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12200   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12201   vat_json_object_add_uint (node, "remote_cookie",
12202                             clib_net_to_host_u64 (mp->remote_cookie));
12203
12204   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12205   vat_json_object_add_uint (node, "local_session_id",
12206                             clib_net_to_host_u32 (mp->local_session_id));
12207   vat_json_object_add_uint (node, "remote_session_id",
12208                             clib_net_to_host_u32 (mp->remote_session_id));
12209   vat_json_object_add_string_copy (node, "l2_sublayer",
12210                                    mp->l2_sublayer_present ? (u8 *) "present"
12211                                    : (u8 *) "absent");
12212 }
12213
12214 static int
12215 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12216 {
12217   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12218   vl_api_control_ping_t *mp_ping;
12219   int ret;
12220
12221   /* Get list of l2tpv3-tunnel interfaces */
12222   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12223   S (mp);
12224
12225   /* Use a control ping for synchronization */
12226   MPING (CONTROL_PING, mp_ping);
12227   S (mp_ping);
12228
12229   W (ret);
12230   return ret;
12231 }
12232
12233
12234 static void vl_api_sw_interface_tap_v2_details_t_handler
12235   (vl_api_sw_interface_tap_v2_details_t * mp)
12236 {
12237   vat_main_t *vam = &vat_main;
12238
12239   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12240                     mp->host_ip4_prefix_len);
12241   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12242                     mp->host_ip6_prefix_len);
12243
12244   print (vam->ofp,
12245          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12246          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12247          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12248          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12249          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12250
12251   vec_free (ip4);
12252   vec_free (ip6);
12253 }
12254
12255 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12256   (vl_api_sw_interface_tap_v2_details_t * mp)
12257 {
12258   vat_main_t *vam = &vat_main;
12259   vat_json_node_t *node = NULL;
12260
12261   if (VAT_JSON_ARRAY != vam->json_tree.type)
12262     {
12263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12264       vat_json_init_array (&vam->json_tree);
12265     }
12266   node = vat_json_array_add (&vam->json_tree);
12267
12268   vat_json_init_object (node);
12269   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12270   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12271   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12272   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12273   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12274   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12275   vat_json_object_add_string_copy (node, "host_mac_addr",
12276                                    format (0, "%U", format_ethernet_address,
12277                                            &mp->host_mac_addr));
12278   vat_json_object_add_string_copy (node, "host_namespace",
12279                                    mp->host_namespace);
12280   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12281   vat_json_object_add_string_copy (node, "host_ip4_addr",
12282                                    format (0, "%U/%d", format_ip4_address,
12283                                            mp->host_ip4_addr,
12284                                            mp->host_ip4_prefix_len));
12285   vat_json_object_add_string_copy (node, "host_ip6_addr",
12286                                    format (0, "%U/%d", format_ip6_address,
12287                                            mp->host_ip6_addr,
12288                                            mp->host_ip6_prefix_len));
12289
12290 }
12291
12292 static int
12293 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12294 {
12295   vl_api_sw_interface_tap_v2_dump_t *mp;
12296   vl_api_control_ping_t *mp_ping;
12297   int ret;
12298
12299   print (vam->ofp,
12300          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12301          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12302          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12303          "host_ip6_addr");
12304
12305   /* Get list of tap interfaces */
12306   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12307   S (mp);
12308
12309   /* Use a control ping for synchronization */
12310   MPING (CONTROL_PING, mp_ping);
12311   S (mp_ping);
12312
12313   W (ret);
12314   return ret;
12315 }
12316
12317 static void vl_api_sw_interface_virtio_pci_details_t_handler
12318   (vl_api_sw_interface_virtio_pci_details_t * mp)
12319 {
12320   vat_main_t *vam = &vat_main;
12321
12322   typedef union
12323   {
12324     struct
12325     {
12326       u16 domain;
12327       u8 bus;
12328       u8 slot:5;
12329       u8 function:3;
12330     };
12331     u32 as_u32;
12332   } pci_addr_t;
12333   pci_addr_t addr;
12334   addr.as_u32 = ntohl (mp->pci_addr);
12335   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12336                          addr.slot, addr.function);
12337
12338   print (vam->ofp,
12339          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12340          pci_addr, ntohl (mp->sw_if_index),
12341          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12342          format_ethernet_address, mp->mac_addr,
12343          clib_net_to_host_u64 (mp->features));
12344   vec_free (pci_addr);
12345 }
12346
12347 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12348   (vl_api_sw_interface_virtio_pci_details_t * mp)
12349 {
12350   vat_main_t *vam = &vat_main;
12351   vat_json_node_t *node = NULL;
12352
12353   if (VAT_JSON_ARRAY != vam->json_tree.type)
12354     {
12355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12356       vat_json_init_array (&vam->json_tree);
12357     }
12358   node = vat_json_array_add (&vam->json_tree);
12359
12360   vat_json_init_object (node);
12361   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12363   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12364   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12365   vat_json_object_add_uint (node, "features",
12366                             clib_net_to_host_u64 (mp->features));
12367   vat_json_object_add_string_copy (node, "mac_addr",
12368                                    format (0, "%U", format_ethernet_address,
12369                                            &mp->mac_addr));
12370 }
12371
12372 static int
12373 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12374 {
12375   vl_api_sw_interface_virtio_pci_dump_t *mp;
12376   vl_api_control_ping_t *mp_ping;
12377   int ret;
12378
12379   print (vam->ofp,
12380          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12381          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12382          "mac_addr", "features");
12383
12384   /* Get list of tap interfaces */
12385   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12386   S (mp);
12387
12388   /* Use a control ping for synchronization */
12389   MPING (CONTROL_PING, mp_ping);
12390   S (mp_ping);
12391
12392   W (ret);
12393   return ret;
12394 }
12395
12396 static int
12397 api_vxlan_offload_rx (vat_main_t * vam)
12398 {
12399   unformat_input_t *line_input = vam->input;
12400   vl_api_vxlan_offload_rx_t *mp;
12401   u32 hw_if_index = ~0, rx_if_index = ~0;
12402   u8 is_add = 1;
12403   int ret;
12404
12405   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12406     {
12407       if (unformat (line_input, "del"))
12408         is_add = 0;
12409       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12410                          &hw_if_index))
12411         ;
12412       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12413         ;
12414       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12415                          &rx_if_index))
12416         ;
12417       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12418         ;
12419       else
12420         {
12421           errmsg ("parse error '%U'", format_unformat_error, line_input);
12422           return -99;
12423         }
12424     }
12425
12426   if (hw_if_index == ~0)
12427     {
12428       errmsg ("no hw interface");
12429       return -99;
12430     }
12431
12432   if (rx_if_index == ~0)
12433     {
12434       errmsg ("no rx tunnel");
12435       return -99;
12436     }
12437
12438   M (VXLAN_OFFLOAD_RX, mp);
12439
12440   mp->hw_if_index = ntohl (hw_if_index);
12441   mp->sw_if_index = ntohl (rx_if_index);
12442   mp->enable = is_add;
12443
12444   S (mp);
12445   W (ret);
12446   return ret;
12447 }
12448
12449 static uword unformat_vxlan_decap_next
12450   (unformat_input_t * input, va_list * args)
12451 {
12452   u32 *result = va_arg (*args, u32 *);
12453   u32 tmp;
12454
12455   if (unformat (input, "l2"))
12456     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12457   else if (unformat (input, "%d", &tmp))
12458     *result = tmp;
12459   else
12460     return 0;
12461   return 1;
12462 }
12463
12464 static int
12465 api_vxlan_add_del_tunnel (vat_main_t * vam)
12466 {
12467   unformat_input_t *line_input = vam->input;
12468   vl_api_vxlan_add_del_tunnel_t *mp;
12469   ip46_address_t src, dst;
12470   u8 is_add = 1;
12471   u8 ipv4_set = 0, ipv6_set = 0;
12472   u8 src_set = 0;
12473   u8 dst_set = 0;
12474   u8 grp_set = 0;
12475   u32 instance = ~0;
12476   u32 mcast_sw_if_index = ~0;
12477   u32 encap_vrf_id = 0;
12478   u32 decap_next_index = ~0;
12479   u32 vni = 0;
12480   int ret;
12481
12482   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12483   clib_memset (&src, 0, sizeof src);
12484   clib_memset (&dst, 0, sizeof dst);
12485
12486   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12487     {
12488       if (unformat (line_input, "del"))
12489         is_add = 0;
12490       else if (unformat (line_input, "instance %d", &instance))
12491         ;
12492       else
12493         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12494         {
12495           ipv4_set = 1;
12496           src_set = 1;
12497         }
12498       else
12499         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12500         {
12501           ipv4_set = 1;
12502           dst_set = 1;
12503         }
12504       else
12505         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12506         {
12507           ipv6_set = 1;
12508           src_set = 1;
12509         }
12510       else
12511         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12512         {
12513           ipv6_set = 1;
12514           dst_set = 1;
12515         }
12516       else if (unformat (line_input, "group %U %U",
12517                          unformat_ip4_address, &dst.ip4,
12518                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12519         {
12520           grp_set = dst_set = 1;
12521           ipv4_set = 1;
12522         }
12523       else if (unformat (line_input, "group %U",
12524                          unformat_ip4_address, &dst.ip4))
12525         {
12526           grp_set = dst_set = 1;
12527           ipv4_set = 1;
12528         }
12529       else if (unformat (line_input, "group %U %U",
12530                          unformat_ip6_address, &dst.ip6,
12531                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12532         {
12533           grp_set = dst_set = 1;
12534           ipv6_set = 1;
12535         }
12536       else if (unformat (line_input, "group %U",
12537                          unformat_ip6_address, &dst.ip6))
12538         {
12539           grp_set = dst_set = 1;
12540           ipv6_set = 1;
12541         }
12542       else
12543         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12544         ;
12545       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12546         ;
12547       else if (unformat (line_input, "decap-next %U",
12548                          unformat_vxlan_decap_next, &decap_next_index))
12549         ;
12550       else if (unformat (line_input, "vni %d", &vni))
12551         ;
12552       else
12553         {
12554           errmsg ("parse error '%U'", format_unformat_error, line_input);
12555           return -99;
12556         }
12557     }
12558
12559   if (src_set == 0)
12560     {
12561       errmsg ("tunnel src address not specified");
12562       return -99;
12563     }
12564   if (dst_set == 0)
12565     {
12566       errmsg ("tunnel dst address not specified");
12567       return -99;
12568     }
12569
12570   if (grp_set && !ip46_address_is_multicast (&dst))
12571     {
12572       errmsg ("tunnel group address not multicast");
12573       return -99;
12574     }
12575   if (grp_set && mcast_sw_if_index == ~0)
12576     {
12577       errmsg ("tunnel nonexistent multicast device");
12578       return -99;
12579     }
12580   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12581     {
12582       errmsg ("tunnel dst address must be unicast");
12583       return -99;
12584     }
12585
12586
12587   if (ipv4_set && ipv6_set)
12588     {
12589       errmsg ("both IPv4 and IPv6 addresses specified");
12590       return -99;
12591     }
12592
12593   if ((vni == 0) || (vni >> 24))
12594     {
12595       errmsg ("vni not specified or out of range");
12596       return -99;
12597     }
12598
12599   M (VXLAN_ADD_DEL_TUNNEL, mp);
12600
12601   if (ipv6_set)
12602     {
12603       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12604       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12605     }
12606   else
12607     {
12608       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12609       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12610     }
12611
12612   mp->instance = htonl (instance);
12613   mp->encap_vrf_id = ntohl (encap_vrf_id);
12614   mp->decap_next_index = ntohl (decap_next_index);
12615   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12616   mp->vni = ntohl (vni);
12617   mp->is_add = is_add;
12618   mp->is_ipv6 = ipv6_set;
12619
12620   S (mp);
12621   W (ret);
12622   return ret;
12623 }
12624
12625 static void vl_api_vxlan_tunnel_details_t_handler
12626   (vl_api_vxlan_tunnel_details_t * mp)
12627 {
12628   vat_main_t *vam = &vat_main;
12629   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12630   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12631
12632   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12633          ntohl (mp->sw_if_index),
12634          ntohl (mp->instance),
12635          format_ip46_address, &src, IP46_TYPE_ANY,
12636          format_ip46_address, &dst, IP46_TYPE_ANY,
12637          ntohl (mp->encap_vrf_id),
12638          ntohl (mp->decap_next_index), ntohl (mp->vni),
12639          ntohl (mp->mcast_sw_if_index));
12640 }
12641
12642 static void vl_api_vxlan_tunnel_details_t_handler_json
12643   (vl_api_vxlan_tunnel_details_t * mp)
12644 {
12645   vat_main_t *vam = &vat_main;
12646   vat_json_node_t *node = NULL;
12647
12648   if (VAT_JSON_ARRAY != vam->json_tree.type)
12649     {
12650       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12651       vat_json_init_array (&vam->json_tree);
12652     }
12653   node = vat_json_array_add (&vam->json_tree);
12654
12655   vat_json_init_object (node);
12656   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12657
12658   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12659
12660   if (mp->is_ipv6)
12661     {
12662       struct in6_addr ip6;
12663
12664       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12665       vat_json_object_add_ip6 (node, "src_address", ip6);
12666       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12667       vat_json_object_add_ip6 (node, "dst_address", ip6);
12668     }
12669   else
12670     {
12671       struct in_addr ip4;
12672
12673       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12674       vat_json_object_add_ip4 (node, "src_address", ip4);
12675       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12676       vat_json_object_add_ip4 (node, "dst_address", ip4);
12677     }
12678   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12679   vat_json_object_add_uint (node, "decap_next_index",
12680                             ntohl (mp->decap_next_index));
12681   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12682   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12683   vat_json_object_add_uint (node, "mcast_sw_if_index",
12684                             ntohl (mp->mcast_sw_if_index));
12685 }
12686
12687 static int
12688 api_vxlan_tunnel_dump (vat_main_t * vam)
12689 {
12690   unformat_input_t *i = vam->input;
12691   vl_api_vxlan_tunnel_dump_t *mp;
12692   vl_api_control_ping_t *mp_ping;
12693   u32 sw_if_index;
12694   u8 sw_if_index_set = 0;
12695   int ret;
12696
12697   /* Parse args required to build the message */
12698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12699     {
12700       if (unformat (i, "sw_if_index %d", &sw_if_index))
12701         sw_if_index_set = 1;
12702       else
12703         break;
12704     }
12705
12706   if (sw_if_index_set == 0)
12707     {
12708       sw_if_index = ~0;
12709     }
12710
12711   if (!vam->json_output)
12712     {
12713       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12714              "sw_if_index", "instance", "src_address", "dst_address",
12715              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12716     }
12717
12718   /* Get list of vxlan-tunnel interfaces */
12719   M (VXLAN_TUNNEL_DUMP, mp);
12720
12721   mp->sw_if_index = htonl (sw_if_index);
12722
12723   S (mp);
12724
12725   /* Use a control ping for synchronization */
12726   MPING (CONTROL_PING, mp_ping);
12727   S (mp_ping);
12728
12729   W (ret);
12730   return ret;
12731 }
12732
12733 static uword unformat_geneve_decap_next
12734   (unformat_input_t * input, va_list * args)
12735 {
12736   u32 *result = va_arg (*args, u32 *);
12737   u32 tmp;
12738
12739   if (unformat (input, "l2"))
12740     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12741   else if (unformat (input, "%d", &tmp))
12742     *result = tmp;
12743   else
12744     return 0;
12745   return 1;
12746 }
12747
12748 static int
12749 api_geneve_add_del_tunnel (vat_main_t * vam)
12750 {
12751   unformat_input_t *line_input = vam->input;
12752   vl_api_geneve_add_del_tunnel_t *mp;
12753   ip46_address_t src, dst;
12754   u8 is_add = 1;
12755   u8 ipv4_set = 0, ipv6_set = 0;
12756   u8 src_set = 0;
12757   u8 dst_set = 0;
12758   u8 grp_set = 0;
12759   u32 mcast_sw_if_index = ~0;
12760   u32 encap_vrf_id = 0;
12761   u32 decap_next_index = ~0;
12762   u32 vni = 0;
12763   int ret;
12764
12765   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12766   clib_memset (&src, 0, sizeof src);
12767   clib_memset (&dst, 0, sizeof dst);
12768
12769   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12770     {
12771       if (unformat (line_input, "del"))
12772         is_add = 0;
12773       else
12774         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12775         {
12776           ipv4_set = 1;
12777           src_set = 1;
12778         }
12779       else
12780         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12781         {
12782           ipv4_set = 1;
12783           dst_set = 1;
12784         }
12785       else
12786         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12787         {
12788           ipv6_set = 1;
12789           src_set = 1;
12790         }
12791       else
12792         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12793         {
12794           ipv6_set = 1;
12795           dst_set = 1;
12796         }
12797       else if (unformat (line_input, "group %U %U",
12798                          unformat_ip4_address, &dst.ip4,
12799                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12800         {
12801           grp_set = dst_set = 1;
12802           ipv4_set = 1;
12803         }
12804       else if (unformat (line_input, "group %U",
12805                          unformat_ip4_address, &dst.ip4))
12806         {
12807           grp_set = dst_set = 1;
12808           ipv4_set = 1;
12809         }
12810       else if (unformat (line_input, "group %U %U",
12811                          unformat_ip6_address, &dst.ip6,
12812                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12813         {
12814           grp_set = dst_set = 1;
12815           ipv6_set = 1;
12816         }
12817       else if (unformat (line_input, "group %U",
12818                          unformat_ip6_address, &dst.ip6))
12819         {
12820           grp_set = dst_set = 1;
12821           ipv6_set = 1;
12822         }
12823       else
12824         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12825         ;
12826       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12827         ;
12828       else if (unformat (line_input, "decap-next %U",
12829                          unformat_geneve_decap_next, &decap_next_index))
12830         ;
12831       else if (unformat (line_input, "vni %d", &vni))
12832         ;
12833       else
12834         {
12835           errmsg ("parse error '%U'", format_unformat_error, line_input);
12836           return -99;
12837         }
12838     }
12839
12840   if (src_set == 0)
12841     {
12842       errmsg ("tunnel src address not specified");
12843       return -99;
12844     }
12845   if (dst_set == 0)
12846     {
12847       errmsg ("tunnel dst address not specified");
12848       return -99;
12849     }
12850
12851   if (grp_set && !ip46_address_is_multicast (&dst))
12852     {
12853       errmsg ("tunnel group address not multicast");
12854       return -99;
12855     }
12856   if (grp_set && mcast_sw_if_index == ~0)
12857     {
12858       errmsg ("tunnel nonexistent multicast device");
12859       return -99;
12860     }
12861   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12862     {
12863       errmsg ("tunnel dst address must be unicast");
12864       return -99;
12865     }
12866
12867
12868   if (ipv4_set && ipv6_set)
12869     {
12870       errmsg ("both IPv4 and IPv6 addresses specified");
12871       return -99;
12872     }
12873
12874   if ((vni == 0) || (vni >> 24))
12875     {
12876       errmsg ("vni not specified or out of range");
12877       return -99;
12878     }
12879
12880   M (GENEVE_ADD_DEL_TUNNEL, mp);
12881
12882   if (ipv6_set)
12883     {
12884       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12885       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12886     }
12887   else
12888     {
12889       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12890       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12891     }
12892   mp->encap_vrf_id = ntohl (encap_vrf_id);
12893   mp->decap_next_index = ntohl (decap_next_index);
12894   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12895   mp->vni = ntohl (vni);
12896   mp->is_add = is_add;
12897   mp->is_ipv6 = ipv6_set;
12898
12899   S (mp);
12900   W (ret);
12901   return ret;
12902 }
12903
12904 static void vl_api_geneve_tunnel_details_t_handler
12905   (vl_api_geneve_tunnel_details_t * mp)
12906 {
12907   vat_main_t *vam = &vat_main;
12908   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12909   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12910
12911   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12912          ntohl (mp->sw_if_index),
12913          format_ip46_address, &src, IP46_TYPE_ANY,
12914          format_ip46_address, &dst, IP46_TYPE_ANY,
12915          ntohl (mp->encap_vrf_id),
12916          ntohl (mp->decap_next_index), ntohl (mp->vni),
12917          ntohl (mp->mcast_sw_if_index));
12918 }
12919
12920 static void vl_api_geneve_tunnel_details_t_handler_json
12921   (vl_api_geneve_tunnel_details_t * mp)
12922 {
12923   vat_main_t *vam = &vat_main;
12924   vat_json_node_t *node = NULL;
12925
12926   if (VAT_JSON_ARRAY != vam->json_tree.type)
12927     {
12928       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12929       vat_json_init_array (&vam->json_tree);
12930     }
12931   node = vat_json_array_add (&vam->json_tree);
12932
12933   vat_json_init_object (node);
12934   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12935   if (mp->is_ipv6)
12936     {
12937       struct in6_addr ip6;
12938
12939       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12940       vat_json_object_add_ip6 (node, "src_address", ip6);
12941       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12942       vat_json_object_add_ip6 (node, "dst_address", ip6);
12943     }
12944   else
12945     {
12946       struct in_addr ip4;
12947
12948       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12949       vat_json_object_add_ip4 (node, "src_address", ip4);
12950       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12951       vat_json_object_add_ip4 (node, "dst_address", ip4);
12952     }
12953   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12954   vat_json_object_add_uint (node, "decap_next_index",
12955                             ntohl (mp->decap_next_index));
12956   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12957   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12958   vat_json_object_add_uint (node, "mcast_sw_if_index",
12959                             ntohl (mp->mcast_sw_if_index));
12960 }
12961
12962 static int
12963 api_geneve_tunnel_dump (vat_main_t * vam)
12964 {
12965   unformat_input_t *i = vam->input;
12966   vl_api_geneve_tunnel_dump_t *mp;
12967   vl_api_control_ping_t *mp_ping;
12968   u32 sw_if_index;
12969   u8 sw_if_index_set = 0;
12970   int ret;
12971
12972   /* Parse args required to build the message */
12973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12974     {
12975       if (unformat (i, "sw_if_index %d", &sw_if_index))
12976         sw_if_index_set = 1;
12977       else
12978         break;
12979     }
12980
12981   if (sw_if_index_set == 0)
12982     {
12983       sw_if_index = ~0;
12984     }
12985
12986   if (!vam->json_output)
12987     {
12988       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12989              "sw_if_index", "local_address", "remote_address",
12990              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12991     }
12992
12993   /* Get list of geneve-tunnel interfaces */
12994   M (GENEVE_TUNNEL_DUMP, mp);
12995
12996   mp->sw_if_index = htonl (sw_if_index);
12997
12998   S (mp);
12999
13000   /* Use a control ping for synchronization */
13001   M (CONTROL_PING, mp_ping);
13002   S (mp_ping);
13003
13004   W (ret);
13005   return ret;
13006 }
13007
13008 static int
13009 api_gre_tunnel_add_del (vat_main_t * vam)
13010 {
13011   unformat_input_t *line_input = vam->input;
13012   vl_api_address_t src = { }, dst =
13013   {
13014   };
13015   vl_api_gre_tunnel_add_del_t *mp;
13016   vl_api_gre_tunnel_type_t t_type;
13017   u8 is_add = 1;
13018   u8 src_set = 0;
13019   u8 dst_set = 0;
13020   u32 outer_fib_id = 0;
13021   u32 session_id = 0;
13022   u32 instance = ~0;
13023   int ret;
13024
13025   t_type = GRE_API_TUNNEL_TYPE_L3;
13026
13027   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13028     {
13029       if (unformat (line_input, "del"))
13030         is_add = 0;
13031       else if (unformat (line_input, "instance %d", &instance))
13032         ;
13033       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13034         {
13035           src_set = 1;
13036         }
13037       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13038         {
13039           dst_set = 1;
13040         }
13041       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13042         ;
13043       else if (unformat (line_input, "teb"))
13044         t_type = GRE_API_TUNNEL_TYPE_TEB;
13045       else if (unformat (line_input, "erspan %d", &session_id))
13046         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13047       else
13048         {
13049           errmsg ("parse error '%U'", format_unformat_error, line_input);
13050           return -99;
13051         }
13052     }
13053
13054   if (src_set == 0)
13055     {
13056       errmsg ("tunnel src address not specified");
13057       return -99;
13058     }
13059   if (dst_set == 0)
13060     {
13061       errmsg ("tunnel dst address not specified");
13062       return -99;
13063     }
13064
13065   M (GRE_TUNNEL_ADD_DEL, mp);
13066
13067   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13068   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13069
13070   mp->tunnel.instance = htonl (instance);
13071   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13072   mp->is_add = is_add;
13073   mp->tunnel.session_id = htons ((u16) session_id);
13074   mp->tunnel.type = htonl (t_type);
13075
13076   S (mp);
13077   W (ret);
13078   return ret;
13079 }
13080
13081 static void vl_api_gre_tunnel_details_t_handler
13082   (vl_api_gre_tunnel_details_t * mp)
13083 {
13084   vat_main_t *vam = &vat_main;
13085
13086   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13087          ntohl (mp->tunnel.sw_if_index),
13088          ntohl (mp->tunnel.instance),
13089          format_vl_api_address, &mp->tunnel.src,
13090          format_vl_api_address, &mp->tunnel.dst,
13091          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13092          ntohl (mp->tunnel.session_id));
13093 }
13094
13095 static void vl_api_gre_tunnel_details_t_handler_json
13096   (vl_api_gre_tunnel_details_t * mp)
13097 {
13098   vat_main_t *vam = &vat_main;
13099   vat_json_node_t *node = NULL;
13100
13101   if (VAT_JSON_ARRAY != vam->json_tree.type)
13102     {
13103       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13104       vat_json_init_array (&vam->json_tree);
13105     }
13106   node = vat_json_array_add (&vam->json_tree);
13107
13108   vat_json_init_object (node);
13109   vat_json_object_add_uint (node, "sw_if_index",
13110                             ntohl (mp->tunnel.sw_if_index));
13111   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13112
13113   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13114   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13115   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13116   vat_json_object_add_uint (node, "outer_fib_id",
13117                             ntohl (mp->tunnel.outer_fib_id));
13118   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13119 }
13120
13121 static int
13122 api_gre_tunnel_dump (vat_main_t * vam)
13123 {
13124   unformat_input_t *i = vam->input;
13125   vl_api_gre_tunnel_dump_t *mp;
13126   vl_api_control_ping_t *mp_ping;
13127   u32 sw_if_index;
13128   u8 sw_if_index_set = 0;
13129   int ret;
13130
13131   /* Parse args required to build the message */
13132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13133     {
13134       if (unformat (i, "sw_if_index %d", &sw_if_index))
13135         sw_if_index_set = 1;
13136       else
13137         break;
13138     }
13139
13140   if (sw_if_index_set == 0)
13141     {
13142       sw_if_index = ~0;
13143     }
13144
13145   if (!vam->json_output)
13146     {
13147       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13148              "sw_if_index", "instance", "src_address", "dst_address",
13149              "tunnel_type", "outer_fib_id", "session_id");
13150     }
13151
13152   /* Get list of gre-tunnel interfaces */
13153   M (GRE_TUNNEL_DUMP, mp);
13154
13155   mp->sw_if_index = htonl (sw_if_index);
13156
13157   S (mp);
13158
13159   /* Use a control ping for synchronization */
13160   MPING (CONTROL_PING, mp_ping);
13161   S (mp_ping);
13162
13163   W (ret);
13164   return ret;
13165 }
13166
13167 static int
13168 api_l2_fib_clear_table (vat_main_t * vam)
13169 {
13170 //  unformat_input_t * i = vam->input;
13171   vl_api_l2_fib_clear_table_t *mp;
13172   int ret;
13173
13174   M (L2_FIB_CLEAR_TABLE, mp);
13175
13176   S (mp);
13177   W (ret);
13178   return ret;
13179 }
13180
13181 static int
13182 api_l2_interface_efp_filter (vat_main_t * vam)
13183 {
13184   unformat_input_t *i = vam->input;
13185   vl_api_l2_interface_efp_filter_t *mp;
13186   u32 sw_if_index;
13187   u8 enable = 1;
13188   u8 sw_if_index_set = 0;
13189   int ret;
13190
13191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13192     {
13193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13194         sw_if_index_set = 1;
13195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13196         sw_if_index_set = 1;
13197       else if (unformat (i, "enable"))
13198         enable = 1;
13199       else if (unformat (i, "disable"))
13200         enable = 0;
13201       else
13202         {
13203           clib_warning ("parse error '%U'", format_unformat_error, i);
13204           return -99;
13205         }
13206     }
13207
13208   if (sw_if_index_set == 0)
13209     {
13210       errmsg ("missing sw_if_index");
13211       return -99;
13212     }
13213
13214   M (L2_INTERFACE_EFP_FILTER, mp);
13215
13216   mp->sw_if_index = ntohl (sw_if_index);
13217   mp->enable_disable = enable;
13218
13219   S (mp);
13220   W (ret);
13221   return ret;
13222 }
13223
13224 #define foreach_vtr_op                          \
13225 _("disable",  L2_VTR_DISABLED)                  \
13226 _("push-1",  L2_VTR_PUSH_1)                     \
13227 _("push-2",  L2_VTR_PUSH_2)                     \
13228 _("pop-1",  L2_VTR_POP_1)                       \
13229 _("pop-2",  L2_VTR_POP_2)                       \
13230 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13231 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13232 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13233 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13234
13235 static int
13236 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13237 {
13238   unformat_input_t *i = vam->input;
13239   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13240   u32 sw_if_index;
13241   u8 sw_if_index_set = 0;
13242   u8 vtr_op_set = 0;
13243   u32 vtr_op = 0;
13244   u32 push_dot1q = 1;
13245   u32 tag1 = ~0;
13246   u32 tag2 = ~0;
13247   int ret;
13248
13249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13250     {
13251       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13252         sw_if_index_set = 1;
13253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13254         sw_if_index_set = 1;
13255       else if (unformat (i, "vtr_op %d", &vtr_op))
13256         vtr_op_set = 1;
13257 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13258       foreach_vtr_op
13259 #undef _
13260         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13261         ;
13262       else if (unformat (i, "tag1 %d", &tag1))
13263         ;
13264       else if (unformat (i, "tag2 %d", &tag2))
13265         ;
13266       else
13267         {
13268           clib_warning ("parse error '%U'", format_unformat_error, i);
13269           return -99;
13270         }
13271     }
13272
13273   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13274     {
13275       errmsg ("missing vtr operation or sw_if_index");
13276       return -99;
13277     }
13278
13279   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13280   mp->sw_if_index = ntohl (sw_if_index);
13281   mp->vtr_op = ntohl (vtr_op);
13282   mp->push_dot1q = ntohl (push_dot1q);
13283   mp->tag1 = ntohl (tag1);
13284   mp->tag2 = ntohl (tag2);
13285
13286   S (mp);
13287   W (ret);
13288   return ret;
13289 }
13290
13291 static int
13292 api_create_vhost_user_if (vat_main_t * vam)
13293 {
13294   unformat_input_t *i = vam->input;
13295   vl_api_create_vhost_user_if_t *mp;
13296   u8 *file_name;
13297   u8 is_server = 0;
13298   u8 file_name_set = 0;
13299   u32 custom_dev_instance = ~0;
13300   u8 hwaddr[6];
13301   u8 use_custom_mac = 0;
13302   u8 disable_mrg_rxbuf = 0;
13303   u8 disable_indirect_desc = 0;
13304   u8 *tag = 0;
13305   u8 enable_gso = 0;
13306   int ret;
13307
13308   /* Shut up coverity */
13309   clib_memset (hwaddr, 0, sizeof (hwaddr));
13310
13311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13312     {
13313       if (unformat (i, "socket %s", &file_name))
13314         {
13315           file_name_set = 1;
13316         }
13317       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13318         ;
13319       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13320         use_custom_mac = 1;
13321       else if (unformat (i, "server"))
13322         is_server = 1;
13323       else if (unformat (i, "disable_mrg_rxbuf"))
13324         disable_mrg_rxbuf = 1;
13325       else if (unformat (i, "disable_indirect_desc"))
13326         disable_indirect_desc = 1;
13327       else if (unformat (i, "gso"))
13328         enable_gso = 1;
13329       else if (unformat (i, "tag %s", &tag))
13330         ;
13331       else
13332         break;
13333     }
13334
13335   if (file_name_set == 0)
13336     {
13337       errmsg ("missing socket file name");
13338       return -99;
13339     }
13340
13341   if (vec_len (file_name) > 255)
13342     {
13343       errmsg ("socket file name too long");
13344       return -99;
13345     }
13346   vec_add1 (file_name, 0);
13347
13348   M (CREATE_VHOST_USER_IF, mp);
13349
13350   mp->is_server = is_server;
13351   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13352   mp->disable_indirect_desc = disable_indirect_desc;
13353   mp->enable_gso = enable_gso;
13354   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13355   vec_free (file_name);
13356   if (custom_dev_instance != ~0)
13357     {
13358       mp->renumber = 1;
13359       mp->custom_dev_instance = ntohl (custom_dev_instance);
13360     }
13361
13362   mp->use_custom_mac = use_custom_mac;
13363   clib_memcpy (mp->mac_address, hwaddr, 6);
13364   if (tag)
13365     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13366   vec_free (tag);
13367
13368   S (mp);
13369   W (ret);
13370   return ret;
13371 }
13372
13373 static int
13374 api_modify_vhost_user_if (vat_main_t * vam)
13375 {
13376   unformat_input_t *i = vam->input;
13377   vl_api_modify_vhost_user_if_t *mp;
13378   u8 *file_name;
13379   u8 is_server = 0;
13380   u8 file_name_set = 0;
13381   u32 custom_dev_instance = ~0;
13382   u8 sw_if_index_set = 0;
13383   u32 sw_if_index = (u32) ~ 0;
13384   u8 enable_gso = 0;
13385   int ret;
13386
13387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13388     {
13389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13390         sw_if_index_set = 1;
13391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13392         sw_if_index_set = 1;
13393       else if (unformat (i, "socket %s", &file_name))
13394         {
13395           file_name_set = 1;
13396         }
13397       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13398         ;
13399       else if (unformat (i, "server"))
13400         is_server = 1;
13401       else if (unformat (i, "gso"))
13402         enable_gso = 1;
13403       else
13404         break;
13405     }
13406
13407   if (sw_if_index_set == 0)
13408     {
13409       errmsg ("missing sw_if_index or interface name");
13410       return -99;
13411     }
13412
13413   if (file_name_set == 0)
13414     {
13415       errmsg ("missing socket file name");
13416       return -99;
13417     }
13418
13419   if (vec_len (file_name) > 255)
13420     {
13421       errmsg ("socket file name too long");
13422       return -99;
13423     }
13424   vec_add1 (file_name, 0);
13425
13426   M (MODIFY_VHOST_USER_IF, mp);
13427
13428   mp->sw_if_index = ntohl (sw_if_index);
13429   mp->is_server = is_server;
13430   mp->enable_gso = enable_gso;
13431   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13432   vec_free (file_name);
13433   if (custom_dev_instance != ~0)
13434     {
13435       mp->renumber = 1;
13436       mp->custom_dev_instance = ntohl (custom_dev_instance);
13437     }
13438
13439   S (mp);
13440   W (ret);
13441   return ret;
13442 }
13443
13444 static int
13445 api_delete_vhost_user_if (vat_main_t * vam)
13446 {
13447   unformat_input_t *i = vam->input;
13448   vl_api_delete_vhost_user_if_t *mp;
13449   u32 sw_if_index = ~0;
13450   u8 sw_if_index_set = 0;
13451   int ret;
13452
13453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13454     {
13455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13456         sw_if_index_set = 1;
13457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13458         sw_if_index_set = 1;
13459       else
13460         break;
13461     }
13462
13463   if (sw_if_index_set == 0)
13464     {
13465       errmsg ("missing sw_if_index or interface name");
13466       return -99;
13467     }
13468
13469
13470   M (DELETE_VHOST_USER_IF, mp);
13471
13472   mp->sw_if_index = ntohl (sw_if_index);
13473
13474   S (mp);
13475   W (ret);
13476   return ret;
13477 }
13478
13479 static void vl_api_sw_interface_vhost_user_details_t_handler
13480   (vl_api_sw_interface_vhost_user_details_t * mp)
13481 {
13482   vat_main_t *vam = &vat_main;
13483
13484   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13485          (char *) mp->interface_name,
13486          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13487          clib_net_to_host_u64 (mp->features), mp->is_server,
13488          ntohl (mp->num_regions), (char *) mp->sock_filename);
13489   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13490 }
13491
13492 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13493   (vl_api_sw_interface_vhost_user_details_t * mp)
13494 {
13495   vat_main_t *vam = &vat_main;
13496   vat_json_node_t *node = NULL;
13497
13498   if (VAT_JSON_ARRAY != vam->json_tree.type)
13499     {
13500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13501       vat_json_init_array (&vam->json_tree);
13502     }
13503   node = vat_json_array_add (&vam->json_tree);
13504
13505   vat_json_init_object (node);
13506   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13507   vat_json_object_add_string_copy (node, "interface_name",
13508                                    mp->interface_name);
13509   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13510                             ntohl (mp->virtio_net_hdr_sz));
13511   vat_json_object_add_uint (node, "features",
13512                             clib_net_to_host_u64 (mp->features));
13513   vat_json_object_add_uint (node, "is_server", mp->is_server);
13514   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13515   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13516   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13517 }
13518
13519 static int
13520 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13521 {
13522   vl_api_sw_interface_vhost_user_dump_t *mp;
13523   vl_api_control_ping_t *mp_ping;
13524   int ret;
13525   print (vam->ofp,
13526          "Interface name            idx hdr_sz features server regions filename");
13527
13528   /* Get list of vhost-user interfaces */
13529   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13530   S (mp);
13531
13532   /* Use a control ping for synchronization */
13533   MPING (CONTROL_PING, mp_ping);
13534   S (mp_ping);
13535
13536   W (ret);
13537   return ret;
13538 }
13539
13540 static int
13541 api_show_version (vat_main_t * vam)
13542 {
13543   vl_api_show_version_t *mp;
13544   int ret;
13545
13546   M (SHOW_VERSION, mp);
13547
13548   S (mp);
13549   W (ret);
13550   return ret;
13551 }
13552
13553
13554 static int
13555 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13556 {
13557   unformat_input_t *line_input = vam->input;
13558   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13559   ip4_address_t local4, remote4;
13560   ip6_address_t local6, remote6;
13561   u8 is_add = 1;
13562   u8 ipv4_set = 0, ipv6_set = 0;
13563   u8 local_set = 0;
13564   u8 remote_set = 0;
13565   u8 grp_set = 0;
13566   u32 mcast_sw_if_index = ~0;
13567   u32 encap_vrf_id = 0;
13568   u32 decap_vrf_id = 0;
13569   u8 protocol = ~0;
13570   u32 vni;
13571   u8 vni_set = 0;
13572   int ret;
13573
13574   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13575   clib_memset (&local4, 0, sizeof local4);
13576   clib_memset (&remote4, 0, sizeof remote4);
13577   clib_memset (&local6, 0, sizeof local6);
13578   clib_memset (&remote6, 0, sizeof remote6);
13579
13580   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13581     {
13582       if (unformat (line_input, "del"))
13583         is_add = 0;
13584       else if (unformat (line_input, "local %U",
13585                          unformat_ip4_address, &local4))
13586         {
13587           local_set = 1;
13588           ipv4_set = 1;
13589         }
13590       else if (unformat (line_input, "remote %U",
13591                          unformat_ip4_address, &remote4))
13592         {
13593           remote_set = 1;
13594           ipv4_set = 1;
13595         }
13596       else if (unformat (line_input, "local %U",
13597                          unformat_ip6_address, &local6))
13598         {
13599           local_set = 1;
13600           ipv6_set = 1;
13601         }
13602       else if (unformat (line_input, "remote %U",
13603                          unformat_ip6_address, &remote6))
13604         {
13605           remote_set = 1;
13606           ipv6_set = 1;
13607         }
13608       else if (unformat (line_input, "group %U %U",
13609                          unformat_ip4_address, &remote4,
13610                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13611         {
13612           grp_set = remote_set = 1;
13613           ipv4_set = 1;
13614         }
13615       else if (unformat (line_input, "group %U",
13616                          unformat_ip4_address, &remote4))
13617         {
13618           grp_set = remote_set = 1;
13619           ipv4_set = 1;
13620         }
13621       else if (unformat (line_input, "group %U %U",
13622                          unformat_ip6_address, &remote6,
13623                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13624         {
13625           grp_set = remote_set = 1;
13626           ipv6_set = 1;
13627         }
13628       else if (unformat (line_input, "group %U",
13629                          unformat_ip6_address, &remote6))
13630         {
13631           grp_set = remote_set = 1;
13632           ipv6_set = 1;
13633         }
13634       else
13635         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13636         ;
13637       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13638         ;
13639       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13640         ;
13641       else if (unformat (line_input, "vni %d", &vni))
13642         vni_set = 1;
13643       else if (unformat (line_input, "next-ip4"))
13644         protocol = 1;
13645       else if (unformat (line_input, "next-ip6"))
13646         protocol = 2;
13647       else if (unformat (line_input, "next-ethernet"))
13648         protocol = 3;
13649       else if (unformat (line_input, "next-nsh"))
13650         protocol = 4;
13651       else
13652         {
13653           errmsg ("parse error '%U'", format_unformat_error, line_input);
13654           return -99;
13655         }
13656     }
13657
13658   if (local_set == 0)
13659     {
13660       errmsg ("tunnel local address not specified");
13661       return -99;
13662     }
13663   if (remote_set == 0)
13664     {
13665       errmsg ("tunnel remote address not specified");
13666       return -99;
13667     }
13668   if (grp_set && mcast_sw_if_index == ~0)
13669     {
13670       errmsg ("tunnel nonexistent multicast device");
13671       return -99;
13672     }
13673   if (ipv4_set && ipv6_set)
13674     {
13675       errmsg ("both IPv4 and IPv6 addresses specified");
13676       return -99;
13677     }
13678
13679   if (vni_set == 0)
13680     {
13681       errmsg ("vni not specified");
13682       return -99;
13683     }
13684
13685   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13686
13687
13688   if (ipv6_set)
13689     {
13690       clib_memcpy (&mp->local, &local6, sizeof (local6));
13691       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13692     }
13693   else
13694     {
13695       clib_memcpy (&mp->local, &local4, sizeof (local4));
13696       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13697     }
13698
13699   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13700   mp->encap_vrf_id = ntohl (encap_vrf_id);
13701   mp->decap_vrf_id = ntohl (decap_vrf_id);
13702   mp->protocol = protocol;
13703   mp->vni = ntohl (vni);
13704   mp->is_add = is_add;
13705   mp->is_ipv6 = ipv6_set;
13706
13707   S (mp);
13708   W (ret);
13709   return ret;
13710 }
13711
13712 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13713   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13714 {
13715   vat_main_t *vam = &vat_main;
13716   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13717   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13718
13719   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13720          ntohl (mp->sw_if_index),
13721          format_ip46_address, &local, IP46_TYPE_ANY,
13722          format_ip46_address, &remote, IP46_TYPE_ANY,
13723          ntohl (mp->vni), mp->protocol,
13724          ntohl (mp->mcast_sw_if_index),
13725          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13726 }
13727
13728
13729 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13730   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13731 {
13732   vat_main_t *vam = &vat_main;
13733   vat_json_node_t *node = NULL;
13734   struct in_addr ip4;
13735   struct in6_addr ip6;
13736
13737   if (VAT_JSON_ARRAY != vam->json_tree.type)
13738     {
13739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13740       vat_json_init_array (&vam->json_tree);
13741     }
13742   node = vat_json_array_add (&vam->json_tree);
13743
13744   vat_json_init_object (node);
13745   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13746   if (mp->is_ipv6)
13747     {
13748       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13749       vat_json_object_add_ip6 (node, "local", ip6);
13750       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13751       vat_json_object_add_ip6 (node, "remote", ip6);
13752     }
13753   else
13754     {
13755       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13756       vat_json_object_add_ip4 (node, "local", ip4);
13757       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13758       vat_json_object_add_ip4 (node, "remote", ip4);
13759     }
13760   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13761   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13762   vat_json_object_add_uint (node, "mcast_sw_if_index",
13763                             ntohl (mp->mcast_sw_if_index));
13764   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13765   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13766   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13767 }
13768
13769 static int
13770 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13771 {
13772   unformat_input_t *i = vam->input;
13773   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13774   vl_api_control_ping_t *mp_ping;
13775   u32 sw_if_index;
13776   u8 sw_if_index_set = 0;
13777   int ret;
13778
13779   /* Parse args required to build the message */
13780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13781     {
13782       if (unformat (i, "sw_if_index %d", &sw_if_index))
13783         sw_if_index_set = 1;
13784       else
13785         break;
13786     }
13787
13788   if (sw_if_index_set == 0)
13789     {
13790       sw_if_index = ~0;
13791     }
13792
13793   if (!vam->json_output)
13794     {
13795       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13796              "sw_if_index", "local", "remote", "vni",
13797              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13798     }
13799
13800   /* Get list of vxlan-tunnel interfaces */
13801   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13802
13803   mp->sw_if_index = htonl (sw_if_index);
13804
13805   S (mp);
13806
13807   /* Use a control ping for synchronization */
13808   MPING (CONTROL_PING, mp_ping);
13809   S (mp_ping);
13810
13811   W (ret);
13812   return ret;
13813 }
13814
13815 static void vl_api_l2_fib_table_details_t_handler
13816   (vl_api_l2_fib_table_details_t * mp)
13817 {
13818   vat_main_t *vam = &vat_main;
13819
13820   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13821          "       %d       %d     %d",
13822          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13823          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13824          mp->bvi_mac);
13825 }
13826
13827 static void vl_api_l2_fib_table_details_t_handler_json
13828   (vl_api_l2_fib_table_details_t * mp)
13829 {
13830   vat_main_t *vam = &vat_main;
13831   vat_json_node_t *node = NULL;
13832
13833   if (VAT_JSON_ARRAY != vam->json_tree.type)
13834     {
13835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13836       vat_json_init_array (&vam->json_tree);
13837     }
13838   node = vat_json_array_add (&vam->json_tree);
13839
13840   vat_json_init_object (node);
13841   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13842   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13843   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13844   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13845   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13846   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13847 }
13848
13849 static int
13850 api_l2_fib_table_dump (vat_main_t * vam)
13851 {
13852   unformat_input_t *i = vam->input;
13853   vl_api_l2_fib_table_dump_t *mp;
13854   vl_api_control_ping_t *mp_ping;
13855   u32 bd_id;
13856   u8 bd_id_set = 0;
13857   int ret;
13858
13859   /* Parse args required to build the message */
13860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13861     {
13862       if (unformat (i, "bd_id %d", &bd_id))
13863         bd_id_set = 1;
13864       else
13865         break;
13866     }
13867
13868   if (bd_id_set == 0)
13869     {
13870       errmsg ("missing bridge domain");
13871       return -99;
13872     }
13873
13874   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13875
13876   /* Get list of l2 fib entries */
13877   M (L2_FIB_TABLE_DUMP, mp);
13878
13879   mp->bd_id = ntohl (bd_id);
13880   S (mp);
13881
13882   /* Use a control ping for synchronization */
13883   MPING (CONTROL_PING, mp_ping);
13884   S (mp_ping);
13885
13886   W (ret);
13887   return ret;
13888 }
13889
13890
13891 static int
13892 api_interface_name_renumber (vat_main_t * vam)
13893 {
13894   unformat_input_t *line_input = vam->input;
13895   vl_api_interface_name_renumber_t *mp;
13896   u32 sw_if_index = ~0;
13897   u32 new_show_dev_instance = ~0;
13898   int ret;
13899
13900   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13901     {
13902       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13903                     &sw_if_index))
13904         ;
13905       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13906         ;
13907       else if (unformat (line_input, "new_show_dev_instance %d",
13908                          &new_show_dev_instance))
13909         ;
13910       else
13911         break;
13912     }
13913
13914   if (sw_if_index == ~0)
13915     {
13916       errmsg ("missing interface name or sw_if_index");
13917       return -99;
13918     }
13919
13920   if (new_show_dev_instance == ~0)
13921     {
13922       errmsg ("missing new_show_dev_instance");
13923       return -99;
13924     }
13925
13926   M (INTERFACE_NAME_RENUMBER, mp);
13927
13928   mp->sw_if_index = ntohl (sw_if_index);
13929   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13930
13931   S (mp);
13932   W (ret);
13933   return ret;
13934 }
13935
13936 static int
13937 api_ip_probe_neighbor (vat_main_t * vam)
13938 {
13939   unformat_input_t *i = vam->input;
13940   vl_api_ip_probe_neighbor_t *mp;
13941   vl_api_address_t dst_adr = { };
13942   u8 int_set = 0;
13943   u8 adr_set = 0;
13944   u32 sw_if_index;
13945   int ret;
13946
13947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13948     {
13949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13950         int_set = 1;
13951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13952         int_set = 1;
13953       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13954         adr_set = 1;
13955       else
13956         break;
13957     }
13958
13959   if (int_set == 0)
13960     {
13961       errmsg ("missing interface");
13962       return -99;
13963     }
13964
13965   if (adr_set == 0)
13966     {
13967       errmsg ("missing addresses");
13968       return -99;
13969     }
13970
13971   M (IP_PROBE_NEIGHBOR, mp);
13972
13973   mp->sw_if_index = ntohl (sw_if_index);
13974   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13975
13976   S (mp);
13977   W (ret);
13978   return ret;
13979 }
13980
13981 static int
13982 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13983 {
13984   unformat_input_t *i = vam->input;
13985   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13986   u8 mode = IP_SCAN_V46_NEIGHBORS;
13987   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13988   int ret;
13989
13990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13991     {
13992       if (unformat (i, "ip4"))
13993         mode = IP_SCAN_V4_NEIGHBORS;
13994       else if (unformat (i, "ip6"))
13995         mode = IP_SCAN_V6_NEIGHBORS;
13996       if (unformat (i, "both"))
13997         mode = IP_SCAN_V46_NEIGHBORS;
13998       else if (unformat (i, "disable"))
13999         mode = IP_SCAN_DISABLED;
14000       else if (unformat (i, "interval %d", &interval))
14001         ;
14002       else if (unformat (i, "max-time %d", &time))
14003         ;
14004       else if (unformat (i, "max-update %d", &update))
14005         ;
14006       else if (unformat (i, "delay %d", &delay))
14007         ;
14008       else if (unformat (i, "stale %d", &stale))
14009         ;
14010       else
14011         break;
14012     }
14013
14014   if (interval > 255)
14015     {
14016       errmsg ("interval cannot exceed 255 minutes.");
14017       return -99;
14018     }
14019   if (time > 255)
14020     {
14021       errmsg ("max-time cannot exceed 255 usec.");
14022       return -99;
14023     }
14024   if (update > 255)
14025     {
14026       errmsg ("max-update cannot exceed 255.");
14027       return -99;
14028     }
14029   if (delay > 255)
14030     {
14031       errmsg ("delay cannot exceed 255 msec.");
14032       return -99;
14033     }
14034   if (stale > 255)
14035     {
14036       errmsg ("stale cannot exceed 255 minutes.");
14037       return -99;
14038     }
14039
14040   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14041   mp->mode = mode;
14042   mp->scan_interval = interval;
14043   mp->max_proc_time = time;
14044   mp->max_update = update;
14045   mp->scan_int_delay = delay;
14046   mp->stale_threshold = stale;
14047
14048   S (mp);
14049   W (ret);
14050   return ret;
14051 }
14052
14053 static int
14054 api_want_ip4_arp_events (vat_main_t * vam)
14055 {
14056   unformat_input_t *line_input = vam->input;
14057   vl_api_want_ip4_arp_events_t *mp;
14058   ip4_address_t address;
14059   int address_set = 0;
14060   u32 enable_disable = 1;
14061   int ret;
14062
14063   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14064     {
14065       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14066         address_set = 1;
14067       else if (unformat (line_input, "del"))
14068         enable_disable = 0;
14069       else
14070         break;
14071     }
14072
14073   if (address_set == 0)
14074     {
14075       errmsg ("missing addresses");
14076       return -99;
14077     }
14078
14079   M (WANT_IP4_ARP_EVENTS, mp);
14080   mp->enable_disable = enable_disable;
14081   mp->pid = htonl (getpid ());
14082   clib_memcpy (mp->ip, &address, sizeof (address));
14083
14084   S (mp);
14085   W (ret);
14086   return ret;
14087 }
14088
14089 static int
14090 api_want_ip6_nd_events (vat_main_t * vam)
14091 {
14092   unformat_input_t *line_input = vam->input;
14093   vl_api_want_ip6_nd_events_t *mp;
14094   vl_api_ip6_address_t address;
14095   int address_set = 0;
14096   u32 enable_disable = 1;
14097   int ret;
14098
14099   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14100     {
14101       if (unformat
14102           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14103         address_set = 1;
14104       else if (unformat (line_input, "del"))
14105         enable_disable = 0;
14106       else
14107         break;
14108     }
14109
14110   if (address_set == 0)
14111     {
14112       errmsg ("missing addresses");
14113       return -99;
14114     }
14115
14116   M (WANT_IP6_ND_EVENTS, mp);
14117   mp->enable_disable = enable_disable;
14118   mp->pid = htonl (getpid ());
14119   clib_memcpy (&mp->ip, &address, sizeof (address));
14120
14121   S (mp);
14122   W (ret);
14123   return ret;
14124 }
14125
14126 static int
14127 api_want_l2_macs_events (vat_main_t * vam)
14128 {
14129   unformat_input_t *line_input = vam->input;
14130   vl_api_want_l2_macs_events_t *mp;
14131   u8 enable_disable = 1;
14132   u32 scan_delay = 0;
14133   u32 max_macs_in_event = 0;
14134   u32 learn_limit = 0;
14135   int ret;
14136
14137   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14138     {
14139       if (unformat (line_input, "learn-limit %d", &learn_limit))
14140         ;
14141       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14142         ;
14143       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14144         ;
14145       else if (unformat (line_input, "disable"))
14146         enable_disable = 0;
14147       else
14148         break;
14149     }
14150
14151   M (WANT_L2_MACS_EVENTS, mp);
14152   mp->enable_disable = enable_disable;
14153   mp->pid = htonl (getpid ());
14154   mp->learn_limit = htonl (learn_limit);
14155   mp->scan_delay = (u8) scan_delay;
14156   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14157   S (mp);
14158   W (ret);
14159   return ret;
14160 }
14161
14162 static int
14163 api_input_acl_set_interface (vat_main_t * vam)
14164 {
14165   unformat_input_t *i = vam->input;
14166   vl_api_input_acl_set_interface_t *mp;
14167   u32 sw_if_index;
14168   int sw_if_index_set;
14169   u32 ip4_table_index = ~0;
14170   u32 ip6_table_index = ~0;
14171   u32 l2_table_index = ~0;
14172   u8 is_add = 1;
14173   int ret;
14174
14175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14176     {
14177       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14178         sw_if_index_set = 1;
14179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14180         sw_if_index_set = 1;
14181       else if (unformat (i, "del"))
14182         is_add = 0;
14183       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14184         ;
14185       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14186         ;
14187       else if (unformat (i, "l2-table %d", &l2_table_index))
14188         ;
14189       else
14190         {
14191           clib_warning ("parse error '%U'", format_unformat_error, i);
14192           return -99;
14193         }
14194     }
14195
14196   if (sw_if_index_set == 0)
14197     {
14198       errmsg ("missing interface name or sw_if_index");
14199       return -99;
14200     }
14201
14202   M (INPUT_ACL_SET_INTERFACE, mp);
14203
14204   mp->sw_if_index = ntohl (sw_if_index);
14205   mp->ip4_table_index = ntohl (ip4_table_index);
14206   mp->ip6_table_index = ntohl (ip6_table_index);
14207   mp->l2_table_index = ntohl (l2_table_index);
14208   mp->is_add = is_add;
14209
14210   S (mp);
14211   W (ret);
14212   return ret;
14213 }
14214
14215 static int
14216 api_output_acl_set_interface (vat_main_t * vam)
14217 {
14218   unformat_input_t *i = vam->input;
14219   vl_api_output_acl_set_interface_t *mp;
14220   u32 sw_if_index;
14221   int sw_if_index_set;
14222   u32 ip4_table_index = ~0;
14223   u32 ip6_table_index = ~0;
14224   u32 l2_table_index = ~0;
14225   u8 is_add = 1;
14226   int ret;
14227
14228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14229     {
14230       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14231         sw_if_index_set = 1;
14232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14233         sw_if_index_set = 1;
14234       else if (unformat (i, "del"))
14235         is_add = 0;
14236       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14237         ;
14238       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14239         ;
14240       else if (unformat (i, "l2-table %d", &l2_table_index))
14241         ;
14242       else
14243         {
14244           clib_warning ("parse error '%U'", format_unformat_error, i);
14245           return -99;
14246         }
14247     }
14248
14249   if (sw_if_index_set == 0)
14250     {
14251       errmsg ("missing interface name or sw_if_index");
14252       return -99;
14253     }
14254
14255   M (OUTPUT_ACL_SET_INTERFACE, mp);
14256
14257   mp->sw_if_index = ntohl (sw_if_index);
14258   mp->ip4_table_index = ntohl (ip4_table_index);
14259   mp->ip6_table_index = ntohl (ip6_table_index);
14260   mp->l2_table_index = ntohl (l2_table_index);
14261   mp->is_add = is_add;
14262
14263   S (mp);
14264   W (ret);
14265   return ret;
14266 }
14267
14268 static int
14269 api_ip_address_dump (vat_main_t * vam)
14270 {
14271   unformat_input_t *i = vam->input;
14272   vl_api_ip_address_dump_t *mp;
14273   vl_api_control_ping_t *mp_ping;
14274   u32 sw_if_index = ~0;
14275   u8 sw_if_index_set = 0;
14276   u8 ipv4_set = 0;
14277   u8 ipv6_set = 0;
14278   int ret;
14279
14280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14281     {
14282       if (unformat (i, "sw_if_index %d", &sw_if_index))
14283         sw_if_index_set = 1;
14284       else
14285         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14286         sw_if_index_set = 1;
14287       else if (unformat (i, "ipv4"))
14288         ipv4_set = 1;
14289       else if (unformat (i, "ipv6"))
14290         ipv6_set = 1;
14291       else
14292         break;
14293     }
14294
14295   if (ipv4_set && ipv6_set)
14296     {
14297       errmsg ("ipv4 and ipv6 flags cannot be both set");
14298       return -99;
14299     }
14300
14301   if ((!ipv4_set) && (!ipv6_set))
14302     {
14303       errmsg ("no ipv4 nor ipv6 flag set");
14304       return -99;
14305     }
14306
14307   if (sw_if_index_set == 0)
14308     {
14309       errmsg ("missing interface name or sw_if_index");
14310       return -99;
14311     }
14312
14313   vam->current_sw_if_index = sw_if_index;
14314   vam->is_ipv6 = ipv6_set;
14315
14316   M (IP_ADDRESS_DUMP, mp);
14317   mp->sw_if_index = ntohl (sw_if_index);
14318   mp->is_ipv6 = ipv6_set;
14319   S (mp);
14320
14321   /* Use a control ping for synchronization */
14322   MPING (CONTROL_PING, mp_ping);
14323   S (mp_ping);
14324
14325   W (ret);
14326   return ret;
14327 }
14328
14329 static int
14330 api_ip_dump (vat_main_t * vam)
14331 {
14332   vl_api_ip_dump_t *mp;
14333   vl_api_control_ping_t *mp_ping;
14334   unformat_input_t *in = vam->input;
14335   int ipv4_set = 0;
14336   int ipv6_set = 0;
14337   int is_ipv6;
14338   int i;
14339   int ret;
14340
14341   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14342     {
14343       if (unformat (in, "ipv4"))
14344         ipv4_set = 1;
14345       else if (unformat (in, "ipv6"))
14346         ipv6_set = 1;
14347       else
14348         break;
14349     }
14350
14351   if (ipv4_set && ipv6_set)
14352     {
14353       errmsg ("ipv4 and ipv6 flags cannot be both set");
14354       return -99;
14355     }
14356
14357   if ((!ipv4_set) && (!ipv6_set))
14358     {
14359       errmsg ("no ipv4 nor ipv6 flag set");
14360       return -99;
14361     }
14362
14363   is_ipv6 = ipv6_set;
14364   vam->is_ipv6 = is_ipv6;
14365
14366   /* free old data */
14367   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14368     {
14369       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14370     }
14371   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14372
14373   M (IP_DUMP, mp);
14374   mp->is_ipv6 = ipv6_set;
14375   S (mp);
14376
14377   /* Use a control ping for synchronization */
14378   MPING (CONTROL_PING, mp_ping);
14379   S (mp_ping);
14380
14381   W (ret);
14382   return ret;
14383 }
14384
14385 static int
14386 api_ipsec_spd_add_del (vat_main_t * vam)
14387 {
14388   unformat_input_t *i = vam->input;
14389   vl_api_ipsec_spd_add_del_t *mp;
14390   u32 spd_id = ~0;
14391   u8 is_add = 1;
14392   int ret;
14393
14394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14395     {
14396       if (unformat (i, "spd_id %d", &spd_id))
14397         ;
14398       else if (unformat (i, "del"))
14399         is_add = 0;
14400       else
14401         {
14402           clib_warning ("parse error '%U'", format_unformat_error, i);
14403           return -99;
14404         }
14405     }
14406   if (spd_id == ~0)
14407     {
14408       errmsg ("spd_id must be set");
14409       return -99;
14410     }
14411
14412   M (IPSEC_SPD_ADD_DEL, mp);
14413
14414   mp->spd_id = ntohl (spd_id);
14415   mp->is_add = is_add;
14416
14417   S (mp);
14418   W (ret);
14419   return ret;
14420 }
14421
14422 static int
14423 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14424 {
14425   unformat_input_t *i = vam->input;
14426   vl_api_ipsec_interface_add_del_spd_t *mp;
14427   u32 sw_if_index;
14428   u8 sw_if_index_set = 0;
14429   u32 spd_id = (u32) ~ 0;
14430   u8 is_add = 1;
14431   int ret;
14432
14433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14434     {
14435       if (unformat (i, "del"))
14436         is_add = 0;
14437       else if (unformat (i, "spd_id %d", &spd_id))
14438         ;
14439       else
14440         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14441         sw_if_index_set = 1;
14442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14443         sw_if_index_set = 1;
14444       else
14445         {
14446           clib_warning ("parse error '%U'", format_unformat_error, i);
14447           return -99;
14448         }
14449
14450     }
14451
14452   if (spd_id == (u32) ~ 0)
14453     {
14454       errmsg ("spd_id must be set");
14455       return -99;
14456     }
14457
14458   if (sw_if_index_set == 0)
14459     {
14460       errmsg ("missing interface name or sw_if_index");
14461       return -99;
14462     }
14463
14464   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14465
14466   mp->spd_id = ntohl (spd_id);
14467   mp->sw_if_index = ntohl (sw_if_index);
14468   mp->is_add = is_add;
14469
14470   S (mp);
14471   W (ret);
14472   return ret;
14473 }
14474
14475 static int
14476 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14477 {
14478   unformat_input_t *i = vam->input;
14479   vl_api_ipsec_spd_entry_add_del_t *mp;
14480   u8 is_add = 1, is_outbound = 0;
14481   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14482   i32 priority = 0;
14483   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14484   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14485   vl_api_address_t laddr_start = { }, laddr_stop =
14486   {
14487   }, raddr_start =
14488   {
14489   }, raddr_stop =
14490   {
14491   };
14492   int ret;
14493
14494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14495     {
14496       if (unformat (i, "del"))
14497         is_add = 0;
14498       if (unformat (i, "outbound"))
14499         is_outbound = 1;
14500       if (unformat (i, "inbound"))
14501         is_outbound = 0;
14502       else if (unformat (i, "spd_id %d", &spd_id))
14503         ;
14504       else if (unformat (i, "sa_id %d", &sa_id))
14505         ;
14506       else if (unformat (i, "priority %d", &priority))
14507         ;
14508       else if (unformat (i, "protocol %d", &protocol))
14509         ;
14510       else if (unformat (i, "lport_start %d", &lport_start))
14511         ;
14512       else if (unformat (i, "lport_stop %d", &lport_stop))
14513         ;
14514       else if (unformat (i, "rport_start %d", &rport_start))
14515         ;
14516       else if (unformat (i, "rport_stop %d", &rport_stop))
14517         ;
14518       else if (unformat (i, "laddr_start %U",
14519                          unformat_vl_api_address, &laddr_start))
14520         ;
14521       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14522                          &laddr_stop))
14523         ;
14524       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14525                          &raddr_start))
14526         ;
14527       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14528                          &raddr_stop))
14529         ;
14530       else
14531         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14532         {
14533           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14534             {
14535               clib_warning ("unsupported action: 'resolve'");
14536               return -99;
14537             }
14538         }
14539       else
14540         {
14541           clib_warning ("parse error '%U'", format_unformat_error, i);
14542           return -99;
14543         }
14544
14545     }
14546
14547   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14548
14549   mp->is_add = is_add;
14550
14551   mp->entry.spd_id = ntohl (spd_id);
14552   mp->entry.priority = ntohl (priority);
14553   mp->entry.is_outbound = is_outbound;
14554
14555   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14556                sizeof (vl_api_address_t));
14557   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14558                sizeof (vl_api_address_t));
14559   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14560                sizeof (vl_api_address_t));
14561   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14562                sizeof (vl_api_address_t));
14563
14564   mp->entry.protocol = (u8) protocol;
14565   mp->entry.local_port_start = ntohs ((u16) lport_start);
14566   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14567   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14568   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14569   mp->entry.policy = (u8) policy;
14570   mp->entry.sa_id = ntohl (sa_id);
14571
14572   S (mp);
14573   W (ret);
14574   return ret;
14575 }
14576
14577 static int
14578 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14579 {
14580   unformat_input_t *i = vam->input;
14581   vl_api_ipsec_sad_entry_add_del_t *mp;
14582   u32 sad_id = 0, spi = 0;
14583   u8 *ck = 0, *ik = 0;
14584   u8 is_add = 1;
14585
14586   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14587   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14588   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14589   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14590   vl_api_address_t tun_src, tun_dst;
14591   int ret;
14592
14593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14594     {
14595       if (unformat (i, "del"))
14596         is_add = 0;
14597       else if (unformat (i, "sad_id %d", &sad_id))
14598         ;
14599       else if (unformat (i, "spi %d", &spi))
14600         ;
14601       else if (unformat (i, "esp"))
14602         protocol = IPSEC_API_PROTO_ESP;
14603       else
14604         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14605         {
14606           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14607           if (ADDRESS_IP6 == tun_src.af)
14608             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14609         }
14610       else
14611         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14612         {
14613           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14614           if (ADDRESS_IP6 == tun_src.af)
14615             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14616         }
14617       else
14618         if (unformat (i, "crypto_alg %U",
14619                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14620         ;
14621       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14622         ;
14623       else if (unformat (i, "integ_alg %U",
14624                          unformat_ipsec_api_integ_alg, &integ_alg))
14625         ;
14626       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14627         ;
14628       else
14629         {
14630           clib_warning ("parse error '%U'", format_unformat_error, i);
14631           return -99;
14632         }
14633
14634     }
14635
14636   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14637
14638   mp->is_add = is_add;
14639   mp->entry.sad_id = ntohl (sad_id);
14640   mp->entry.protocol = protocol;
14641   mp->entry.spi = ntohl (spi);
14642   mp->entry.flags = flags;
14643
14644   mp->entry.crypto_algorithm = crypto_alg;
14645   mp->entry.integrity_algorithm = integ_alg;
14646   mp->entry.crypto_key.length = vec_len (ck);
14647   mp->entry.integrity_key.length = vec_len (ik);
14648
14649   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14650     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14651
14652   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14653     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14654
14655   if (ck)
14656     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14657   if (ik)
14658     clib_memcpy (mp->entry.integrity_key.data, ik,
14659                  mp->entry.integrity_key.length);
14660
14661   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14662     {
14663       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14664                    sizeof (mp->entry.tunnel_src));
14665       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14666                    sizeof (mp->entry.tunnel_dst));
14667     }
14668
14669   S (mp);
14670   W (ret);
14671   return ret;
14672 }
14673
14674 static int
14675 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14676 {
14677   unformat_input_t *i = vam->input;
14678   vl_api_ipsec_tunnel_if_add_del_t *mp;
14679   u32 local_spi = 0, remote_spi = 0;
14680   u32 crypto_alg = 0, integ_alg = 0;
14681   u8 *lck = NULL, *rck = NULL;
14682   u8 *lik = NULL, *rik = NULL;
14683   vl_api_address_t local_ip = { 0 };
14684   vl_api_address_t remote_ip = { 0 };
14685   f64 before = 0;
14686   u8 is_add = 1;
14687   u8 esn = 0;
14688   u8 anti_replay = 0;
14689   u8 renumber = 0;
14690   u32 instance = ~0;
14691   u32 count = 1, jj;
14692   int ret = -1;
14693
14694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14695     {
14696       if (unformat (i, "del"))
14697         is_add = 0;
14698       else if (unformat (i, "esn"))
14699         esn = 1;
14700       else if (unformat (i, "anti-replay"))
14701         anti_replay = 1;
14702       else if (unformat (i, "count %d", &count))
14703         ;
14704       else if (unformat (i, "local_spi %d", &local_spi))
14705         ;
14706       else if (unformat (i, "remote_spi %d", &remote_spi))
14707         ;
14708       else
14709         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14710         ;
14711       else
14712         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14713         ;
14714       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14715         ;
14716       else
14717         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14718         ;
14719       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14720         ;
14721       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14722         ;
14723       else
14724         if (unformat
14725             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14726         {
14727           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14728             {
14729               errmsg ("unsupported crypto-alg: '%U'\n",
14730                       format_ipsec_crypto_alg, crypto_alg);
14731               return -99;
14732             }
14733         }
14734       else
14735         if (unformat
14736             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14737         {
14738           if (integ_alg >= IPSEC_INTEG_N_ALG)
14739             {
14740               errmsg ("unsupported integ-alg: '%U'\n",
14741                       format_ipsec_integ_alg, integ_alg);
14742               return -99;
14743             }
14744         }
14745       else if (unformat (i, "instance %u", &instance))
14746         renumber = 1;
14747       else
14748         {
14749           errmsg ("parse error '%U'\n", format_unformat_error, i);
14750           return -99;
14751         }
14752     }
14753
14754   if (count > 1)
14755     {
14756       /* Turn on async mode */
14757       vam->async_mode = 1;
14758       vam->async_errors = 0;
14759       before = vat_time_now (vam);
14760     }
14761
14762   for (jj = 0; jj < count; jj++)
14763     {
14764       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14765
14766       mp->is_add = is_add;
14767       mp->esn = esn;
14768       mp->anti_replay = anti_replay;
14769
14770       if (jj > 0)
14771         increment_address (&remote_ip);
14772
14773       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14774       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14775
14776       mp->local_spi = htonl (local_spi + jj);
14777       mp->remote_spi = htonl (remote_spi + jj);
14778       mp->crypto_alg = (u8) crypto_alg;
14779
14780       mp->local_crypto_key_len = 0;
14781       if (lck)
14782         {
14783           mp->local_crypto_key_len = vec_len (lck);
14784           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14785             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14786           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14787         }
14788
14789       mp->remote_crypto_key_len = 0;
14790       if (rck)
14791         {
14792           mp->remote_crypto_key_len = vec_len (rck);
14793           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14794             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14795           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14796         }
14797
14798       mp->integ_alg = (u8) integ_alg;
14799
14800       mp->local_integ_key_len = 0;
14801       if (lik)
14802         {
14803           mp->local_integ_key_len = vec_len (lik);
14804           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14805             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14806           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14807         }
14808
14809       mp->remote_integ_key_len = 0;
14810       if (rik)
14811         {
14812           mp->remote_integ_key_len = vec_len (rik);
14813           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14814             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14815           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14816         }
14817
14818       if (renumber)
14819         {
14820           mp->renumber = renumber;
14821           mp->show_instance = ntohl (instance);
14822         }
14823       S (mp);
14824     }
14825
14826   /* When testing multiple add/del ops, use a control-ping to sync */
14827   if (count > 1)
14828     {
14829       vl_api_control_ping_t *mp_ping;
14830       f64 after;
14831       f64 timeout;
14832
14833       /* Shut off async mode */
14834       vam->async_mode = 0;
14835
14836       MPING (CONTROL_PING, mp_ping);
14837       S (mp_ping);
14838
14839       timeout = vat_time_now (vam) + 1.0;
14840       while (vat_time_now (vam) < timeout)
14841         if (vam->result_ready == 1)
14842           goto out;
14843       vam->retval = -99;
14844
14845     out:
14846       if (vam->retval == -99)
14847         errmsg ("timeout");
14848
14849       if (vam->async_errors > 0)
14850         {
14851           errmsg ("%d asynchronous errors", vam->async_errors);
14852           vam->retval = -98;
14853         }
14854       vam->async_errors = 0;
14855       after = vat_time_now (vam);
14856
14857       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14858       if (jj > 0)
14859         count = jj;
14860
14861       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14862              count, after - before, count / (after - before));
14863     }
14864   else
14865     {
14866       /* Wait for a reply... */
14867       W (ret);
14868       return ret;
14869     }
14870
14871   return ret;
14872 }
14873
14874 static void
14875 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14876 {
14877   vat_main_t *vam = &vat_main;
14878
14879   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14880          "crypto_key %U integ_alg %u integ_key %U flags %x "
14881          "tunnel_src_addr %U tunnel_dst_addr %U "
14882          "salt %u seq_outbound %lu last_seq_inbound %lu "
14883          "replay_window %lu\n",
14884          ntohl (mp->entry.sad_id),
14885          ntohl (mp->sw_if_index),
14886          ntohl (mp->entry.spi),
14887          ntohl (mp->entry.protocol),
14888          ntohl (mp->entry.crypto_algorithm),
14889          format_hex_bytes, mp->entry.crypto_key.data,
14890          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14891          format_hex_bytes, mp->entry.integrity_key.data,
14892          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14893          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14894          &mp->entry.tunnel_dst, ntohl (mp->salt),
14895          clib_net_to_host_u64 (mp->seq_outbound),
14896          clib_net_to_host_u64 (mp->last_seq_inbound),
14897          clib_net_to_host_u64 (mp->replay_window));
14898 }
14899
14900 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14901 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14902
14903 static void vl_api_ipsec_sa_details_t_handler_json
14904   (vl_api_ipsec_sa_details_t * mp)
14905 {
14906   vat_main_t *vam = &vat_main;
14907   vat_json_node_t *node = NULL;
14908   vl_api_ipsec_sad_flags_t flags;
14909
14910   if (VAT_JSON_ARRAY != vam->json_tree.type)
14911     {
14912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14913       vat_json_init_array (&vam->json_tree);
14914     }
14915   node = vat_json_array_add (&vam->json_tree);
14916
14917   vat_json_init_object (node);
14918   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14919   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14920   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14921   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14922   vat_json_object_add_uint (node, "crypto_alg",
14923                             ntohl (mp->entry.crypto_algorithm));
14924   vat_json_object_add_uint (node, "integ_alg",
14925                             ntohl (mp->entry.integrity_algorithm));
14926   flags = ntohl (mp->entry.flags);
14927   vat_json_object_add_uint (node, "use_esn",
14928                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14929   vat_json_object_add_uint (node, "use_anti_replay",
14930                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14931   vat_json_object_add_uint (node, "is_tunnel",
14932                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14933   vat_json_object_add_uint (node, "is_tunnel_ip6",
14934                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14935   vat_json_object_add_uint (node, "udp_encap",
14936                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14937   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14938                              mp->entry.crypto_key.length);
14939   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14940                              mp->entry.integrity_key.length);
14941   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14942   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14943   vat_json_object_add_uint (node, "replay_window",
14944                             clib_net_to_host_u64 (mp->replay_window));
14945 }
14946
14947 static int
14948 api_ipsec_sa_dump (vat_main_t * vam)
14949 {
14950   unformat_input_t *i = vam->input;
14951   vl_api_ipsec_sa_dump_t *mp;
14952   vl_api_control_ping_t *mp_ping;
14953   u32 sa_id = ~0;
14954   int ret;
14955
14956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14957     {
14958       if (unformat (i, "sa_id %d", &sa_id))
14959         ;
14960       else
14961         {
14962           clib_warning ("parse error '%U'", format_unformat_error, i);
14963           return -99;
14964         }
14965     }
14966
14967   M (IPSEC_SA_DUMP, mp);
14968
14969   mp->sa_id = ntohl (sa_id);
14970
14971   S (mp);
14972
14973   /* Use a control ping for synchronization */
14974   M (CONTROL_PING, mp_ping);
14975   S (mp_ping);
14976
14977   W (ret);
14978   return ret;
14979 }
14980
14981 static int
14982 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14983 {
14984   unformat_input_t *i = vam->input;
14985   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14986   u32 sw_if_index = ~0;
14987   u32 sa_id = ~0;
14988   u8 is_outbound = (u8) ~ 0;
14989   int ret;
14990
14991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14992     {
14993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14994         ;
14995       else if (unformat (i, "sa_id %d", &sa_id))
14996         ;
14997       else if (unformat (i, "outbound"))
14998         is_outbound = 1;
14999       else if (unformat (i, "inbound"))
15000         is_outbound = 0;
15001       else
15002         {
15003           clib_warning ("parse error '%U'", format_unformat_error, i);
15004           return -99;
15005         }
15006     }
15007
15008   if (sw_if_index == ~0)
15009     {
15010       errmsg ("interface must be specified");
15011       return -99;
15012     }
15013
15014   if (sa_id == ~0)
15015     {
15016       errmsg ("SA ID must be specified");
15017       return -99;
15018     }
15019
15020   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15021
15022   mp->sw_if_index = htonl (sw_if_index);
15023   mp->sa_id = htonl (sa_id);
15024   mp->is_outbound = is_outbound;
15025
15026   S (mp);
15027   W (ret);
15028
15029   return ret;
15030 }
15031
15032 static int
15033 api_get_first_msg_id (vat_main_t * vam)
15034 {
15035   vl_api_get_first_msg_id_t *mp;
15036   unformat_input_t *i = vam->input;
15037   u8 *name;
15038   u8 name_set = 0;
15039   int ret;
15040
15041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15042     {
15043       if (unformat (i, "client %s", &name))
15044         name_set = 1;
15045       else
15046         break;
15047     }
15048
15049   if (name_set == 0)
15050     {
15051       errmsg ("missing client name");
15052       return -99;
15053     }
15054   vec_add1 (name, 0);
15055
15056   if (vec_len (name) > 63)
15057     {
15058       errmsg ("client name too long");
15059       return -99;
15060     }
15061
15062   M (GET_FIRST_MSG_ID, mp);
15063   clib_memcpy (mp->name, name, vec_len (name));
15064   S (mp);
15065   W (ret);
15066   return ret;
15067 }
15068
15069 static int
15070 api_cop_interface_enable_disable (vat_main_t * vam)
15071 {
15072   unformat_input_t *line_input = vam->input;
15073   vl_api_cop_interface_enable_disable_t *mp;
15074   u32 sw_if_index = ~0;
15075   u8 enable_disable = 1;
15076   int ret;
15077
15078   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15079     {
15080       if (unformat (line_input, "disable"))
15081         enable_disable = 0;
15082       if (unformat (line_input, "enable"))
15083         enable_disable = 1;
15084       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15085                          vam, &sw_if_index))
15086         ;
15087       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15088         ;
15089       else
15090         break;
15091     }
15092
15093   if (sw_if_index == ~0)
15094     {
15095       errmsg ("missing interface name or sw_if_index");
15096       return -99;
15097     }
15098
15099   /* Construct the API message */
15100   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15101   mp->sw_if_index = ntohl (sw_if_index);
15102   mp->enable_disable = enable_disable;
15103
15104   /* send it... */
15105   S (mp);
15106   /* Wait for the reply */
15107   W (ret);
15108   return ret;
15109 }
15110
15111 static int
15112 api_cop_whitelist_enable_disable (vat_main_t * vam)
15113 {
15114   unformat_input_t *line_input = vam->input;
15115   vl_api_cop_whitelist_enable_disable_t *mp;
15116   u32 sw_if_index = ~0;
15117   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15118   u32 fib_id = 0;
15119   int ret;
15120
15121   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15122     {
15123       if (unformat (line_input, "ip4"))
15124         ip4 = 1;
15125       else if (unformat (line_input, "ip6"))
15126         ip6 = 1;
15127       else if (unformat (line_input, "default"))
15128         default_cop = 1;
15129       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15130                          vam, &sw_if_index))
15131         ;
15132       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15133         ;
15134       else if (unformat (line_input, "fib-id %d", &fib_id))
15135         ;
15136       else
15137         break;
15138     }
15139
15140   if (sw_if_index == ~0)
15141     {
15142       errmsg ("missing interface name or sw_if_index");
15143       return -99;
15144     }
15145
15146   /* Construct the API message */
15147   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15148   mp->sw_if_index = ntohl (sw_if_index);
15149   mp->fib_id = ntohl (fib_id);
15150   mp->ip4 = ip4;
15151   mp->ip6 = ip6;
15152   mp->default_cop = default_cop;
15153
15154   /* send it... */
15155   S (mp);
15156   /* Wait for the reply */
15157   W (ret);
15158   return ret;
15159 }
15160
15161 static int
15162 api_get_node_graph (vat_main_t * vam)
15163 {
15164   vl_api_get_node_graph_t *mp;
15165   int ret;
15166
15167   M (GET_NODE_GRAPH, mp);
15168
15169   /* send it... */
15170   S (mp);
15171   /* Wait for the reply */
15172   W (ret);
15173   return ret;
15174 }
15175
15176 /* *INDENT-OFF* */
15177 /** Used for parsing LISP eids */
15178 typedef CLIB_PACKED(struct{
15179   u8 addr[16];   /**< eid address */
15180   u32 len;       /**< prefix length if IP */
15181   u8 type;      /**< type of eid */
15182 }) lisp_eid_vat_t;
15183 /* *INDENT-ON* */
15184
15185 static uword
15186 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15187 {
15188   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15189
15190   clib_memset (a, 0, sizeof (a[0]));
15191
15192   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15193     {
15194       a->type = 0;              /* ipv4 type */
15195     }
15196   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15197     {
15198       a->type = 1;              /* ipv6 type */
15199     }
15200   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15201     {
15202       a->type = 2;              /* mac type */
15203     }
15204   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15205     {
15206       a->type = 3;              /* NSH type */
15207       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15208       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15209     }
15210   else
15211     {
15212       return 0;
15213     }
15214
15215   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15216     {
15217       return 0;
15218     }
15219
15220   return 1;
15221 }
15222
15223 static int
15224 lisp_eid_size_vat (u8 type)
15225 {
15226   switch (type)
15227     {
15228     case 0:
15229       return 4;
15230     case 1:
15231       return 16;
15232     case 2:
15233       return 6;
15234     case 3:
15235       return 5;
15236     }
15237   return 0;
15238 }
15239
15240 static void
15241 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15242 {
15243   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15244 }
15245
15246 static int
15247 api_one_add_del_locator_set (vat_main_t * vam)
15248 {
15249   unformat_input_t *input = vam->input;
15250   vl_api_one_add_del_locator_set_t *mp;
15251   u8 is_add = 1;
15252   u8 *locator_set_name = NULL;
15253   u8 locator_set_name_set = 0;
15254   vl_api_local_locator_t locator, *locators = 0;
15255   u32 sw_if_index, priority, weight;
15256   u32 data_len = 0;
15257
15258   int ret;
15259   /* Parse args required to build the message */
15260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15261     {
15262       if (unformat (input, "del"))
15263         {
15264           is_add = 0;
15265         }
15266       else if (unformat (input, "locator-set %s", &locator_set_name))
15267         {
15268           locator_set_name_set = 1;
15269         }
15270       else if (unformat (input, "sw_if_index %u p %u w %u",
15271                          &sw_if_index, &priority, &weight))
15272         {
15273           locator.sw_if_index = htonl (sw_if_index);
15274           locator.priority = priority;
15275           locator.weight = weight;
15276           vec_add1 (locators, locator);
15277         }
15278       else
15279         if (unformat
15280             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15281              &sw_if_index, &priority, &weight))
15282         {
15283           locator.sw_if_index = htonl (sw_if_index);
15284           locator.priority = priority;
15285           locator.weight = weight;
15286           vec_add1 (locators, locator);
15287         }
15288       else
15289         break;
15290     }
15291
15292   if (locator_set_name_set == 0)
15293     {
15294       errmsg ("missing locator-set name");
15295       vec_free (locators);
15296       return -99;
15297     }
15298
15299   if (vec_len (locator_set_name) > 64)
15300     {
15301       errmsg ("locator-set name too long");
15302       vec_free (locator_set_name);
15303       vec_free (locators);
15304       return -99;
15305     }
15306   vec_add1 (locator_set_name, 0);
15307
15308   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15309
15310   /* Construct the API message */
15311   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15312
15313   mp->is_add = is_add;
15314   clib_memcpy (mp->locator_set_name, locator_set_name,
15315                vec_len (locator_set_name));
15316   vec_free (locator_set_name);
15317
15318   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15319   if (locators)
15320     clib_memcpy (mp->locators, locators, data_len);
15321   vec_free (locators);
15322
15323   /* send it... */
15324   S (mp);
15325
15326   /* Wait for a reply... */
15327   W (ret);
15328   return ret;
15329 }
15330
15331 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15332
15333 static int
15334 api_one_add_del_locator (vat_main_t * vam)
15335 {
15336   unformat_input_t *input = vam->input;
15337   vl_api_one_add_del_locator_t *mp;
15338   u32 tmp_if_index = ~0;
15339   u32 sw_if_index = ~0;
15340   u8 sw_if_index_set = 0;
15341   u8 sw_if_index_if_name_set = 0;
15342   u32 priority = ~0;
15343   u8 priority_set = 0;
15344   u32 weight = ~0;
15345   u8 weight_set = 0;
15346   u8 is_add = 1;
15347   u8 *locator_set_name = NULL;
15348   u8 locator_set_name_set = 0;
15349   int ret;
15350
15351   /* Parse args required to build the message */
15352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15353     {
15354       if (unformat (input, "del"))
15355         {
15356           is_add = 0;
15357         }
15358       else if (unformat (input, "locator-set %s", &locator_set_name))
15359         {
15360           locator_set_name_set = 1;
15361         }
15362       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15363                          &tmp_if_index))
15364         {
15365           sw_if_index_if_name_set = 1;
15366           sw_if_index = tmp_if_index;
15367         }
15368       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15369         {
15370           sw_if_index_set = 1;
15371           sw_if_index = tmp_if_index;
15372         }
15373       else if (unformat (input, "p %d", &priority))
15374         {
15375           priority_set = 1;
15376         }
15377       else if (unformat (input, "w %d", &weight))
15378         {
15379           weight_set = 1;
15380         }
15381       else
15382         break;
15383     }
15384
15385   if (locator_set_name_set == 0)
15386     {
15387       errmsg ("missing locator-set name");
15388       return -99;
15389     }
15390
15391   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15392     {
15393       errmsg ("missing sw_if_index");
15394       vec_free (locator_set_name);
15395       return -99;
15396     }
15397
15398   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15399     {
15400       errmsg ("cannot use both params interface name and sw_if_index");
15401       vec_free (locator_set_name);
15402       return -99;
15403     }
15404
15405   if (priority_set == 0)
15406     {
15407       errmsg ("missing locator-set priority");
15408       vec_free (locator_set_name);
15409       return -99;
15410     }
15411
15412   if (weight_set == 0)
15413     {
15414       errmsg ("missing locator-set weight");
15415       vec_free (locator_set_name);
15416       return -99;
15417     }
15418
15419   if (vec_len (locator_set_name) > 64)
15420     {
15421       errmsg ("locator-set name too long");
15422       vec_free (locator_set_name);
15423       return -99;
15424     }
15425   vec_add1 (locator_set_name, 0);
15426
15427   /* Construct the API message */
15428   M (ONE_ADD_DEL_LOCATOR, mp);
15429
15430   mp->is_add = is_add;
15431   mp->sw_if_index = ntohl (sw_if_index);
15432   mp->priority = priority;
15433   mp->weight = weight;
15434   clib_memcpy (mp->locator_set_name, locator_set_name,
15435                vec_len (locator_set_name));
15436   vec_free (locator_set_name);
15437
15438   /* send it... */
15439   S (mp);
15440
15441   /* Wait for a reply... */
15442   W (ret);
15443   return ret;
15444 }
15445
15446 #define api_lisp_add_del_locator api_one_add_del_locator
15447
15448 uword
15449 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15450 {
15451   u32 *key_id = va_arg (*args, u32 *);
15452   u8 *s = 0;
15453
15454   if (unformat (input, "%s", &s))
15455     {
15456       if (!strcmp ((char *) s, "sha1"))
15457         key_id[0] = HMAC_SHA_1_96;
15458       else if (!strcmp ((char *) s, "sha256"))
15459         key_id[0] = HMAC_SHA_256_128;
15460       else
15461         {
15462           clib_warning ("invalid key_id: '%s'", s);
15463           key_id[0] = HMAC_NO_KEY;
15464         }
15465     }
15466   else
15467     return 0;
15468
15469   vec_free (s);
15470   return 1;
15471 }
15472
15473 static int
15474 api_one_add_del_local_eid (vat_main_t * vam)
15475 {
15476   unformat_input_t *input = vam->input;
15477   vl_api_one_add_del_local_eid_t *mp;
15478   u8 is_add = 1;
15479   u8 eid_set = 0;
15480   lisp_eid_vat_t _eid, *eid = &_eid;
15481   u8 *locator_set_name = 0;
15482   u8 locator_set_name_set = 0;
15483   u32 vni = 0;
15484   u16 key_id = 0;
15485   u8 *key = 0;
15486   int ret;
15487
15488   /* Parse args required to build the message */
15489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15490     {
15491       if (unformat (input, "del"))
15492         {
15493           is_add = 0;
15494         }
15495       else if (unformat (input, "vni %d", &vni))
15496         {
15497           ;
15498         }
15499       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15500         {
15501           eid_set = 1;
15502         }
15503       else if (unformat (input, "locator-set %s", &locator_set_name))
15504         {
15505           locator_set_name_set = 1;
15506         }
15507       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15508         ;
15509       else if (unformat (input, "secret-key %_%v%_", &key))
15510         ;
15511       else
15512         break;
15513     }
15514
15515   if (locator_set_name_set == 0)
15516     {
15517       errmsg ("missing locator-set name");
15518       return -99;
15519     }
15520
15521   if (0 == eid_set)
15522     {
15523       errmsg ("EID address not set!");
15524       vec_free (locator_set_name);
15525       return -99;
15526     }
15527
15528   if (key && (0 == key_id))
15529     {
15530       errmsg ("invalid key_id!");
15531       return -99;
15532     }
15533
15534   if (vec_len (key) > 64)
15535     {
15536       errmsg ("key too long");
15537       vec_free (key);
15538       return -99;
15539     }
15540
15541   if (vec_len (locator_set_name) > 64)
15542     {
15543       errmsg ("locator-set name too long");
15544       vec_free (locator_set_name);
15545       return -99;
15546     }
15547   vec_add1 (locator_set_name, 0);
15548
15549   /* Construct the API message */
15550   M (ONE_ADD_DEL_LOCAL_EID, mp);
15551
15552   mp->is_add = is_add;
15553   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15554   mp->eid_type = eid->type;
15555   mp->prefix_len = eid->len;
15556   mp->vni = clib_host_to_net_u32 (vni);
15557   mp->key_id = clib_host_to_net_u16 (key_id);
15558   clib_memcpy (mp->locator_set_name, locator_set_name,
15559                vec_len (locator_set_name));
15560   clib_memcpy (mp->key, key, vec_len (key));
15561
15562   vec_free (locator_set_name);
15563   vec_free (key);
15564
15565   /* send it... */
15566   S (mp);
15567
15568   /* Wait for a reply... */
15569   W (ret);
15570   return ret;
15571 }
15572
15573 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15574
15575 static int
15576 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15577 {
15578   u32 dp_table = 0, vni = 0;;
15579   unformat_input_t *input = vam->input;
15580   vl_api_gpe_add_del_fwd_entry_t *mp;
15581   u8 is_add = 1;
15582   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15583   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15584   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15585   u32 action = ~0, w;
15586   ip4_address_t rmt_rloc4, lcl_rloc4;
15587   ip6_address_t rmt_rloc6, lcl_rloc6;
15588   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15589   int ret;
15590
15591   clib_memset (&rloc, 0, sizeof (rloc));
15592
15593   /* Parse args required to build the message */
15594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15595     {
15596       if (unformat (input, "del"))
15597         is_add = 0;
15598       else if (unformat (input, "add"))
15599         is_add = 1;
15600       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15601         {
15602           rmt_eid_set = 1;
15603         }
15604       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15605         {
15606           lcl_eid_set = 1;
15607         }
15608       else if (unformat (input, "vrf %d", &dp_table))
15609         ;
15610       else if (unformat (input, "bd %d", &dp_table))
15611         ;
15612       else if (unformat (input, "vni %d", &vni))
15613         ;
15614       else if (unformat (input, "w %d", &w))
15615         {
15616           if (!curr_rloc)
15617             {
15618               errmsg ("No RLOC configured for setting priority/weight!");
15619               return -99;
15620             }
15621           curr_rloc->weight = w;
15622         }
15623       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15624                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15625         {
15626           rloc.is_ip4 = 1;
15627
15628           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15629           rloc.weight = 0;
15630           vec_add1 (lcl_locs, rloc);
15631
15632           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15633           vec_add1 (rmt_locs, rloc);
15634           /* weight saved in rmt loc */
15635           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15636         }
15637       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15638                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15639         {
15640           rloc.is_ip4 = 0;
15641           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15642           rloc.weight = 0;
15643           vec_add1 (lcl_locs, rloc);
15644
15645           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15646           vec_add1 (rmt_locs, rloc);
15647           /* weight saved in rmt loc */
15648           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15649         }
15650       else if (unformat (input, "action %d", &action))
15651         {
15652           ;
15653         }
15654       else
15655         {
15656           clib_warning ("parse error '%U'", format_unformat_error, input);
15657           return -99;
15658         }
15659     }
15660
15661   if (!rmt_eid_set)
15662     {
15663       errmsg ("remote eid addresses not set");
15664       return -99;
15665     }
15666
15667   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15668     {
15669       errmsg ("eid types don't match");
15670       return -99;
15671     }
15672
15673   if (0 == rmt_locs && (u32) ~ 0 == action)
15674     {
15675       errmsg ("action not set for negative mapping");
15676       return -99;
15677     }
15678
15679   /* Construct the API message */
15680   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15681       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15682
15683   mp->is_add = is_add;
15684   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15685   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15686   mp->eid_type = rmt_eid->type;
15687   mp->dp_table = clib_host_to_net_u32 (dp_table);
15688   mp->vni = clib_host_to_net_u32 (vni);
15689   mp->rmt_len = rmt_eid->len;
15690   mp->lcl_len = lcl_eid->len;
15691   mp->action = action;
15692
15693   if (0 != rmt_locs && 0 != lcl_locs)
15694     {
15695       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15696       clib_memcpy (mp->locs, lcl_locs,
15697                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15698
15699       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15700       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15701                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15702     }
15703   vec_free (lcl_locs);
15704   vec_free (rmt_locs);
15705
15706   /* send it... */
15707   S (mp);
15708
15709   /* Wait for a reply... */
15710   W (ret);
15711   return ret;
15712 }
15713
15714 static int
15715 api_one_add_del_map_server (vat_main_t * vam)
15716 {
15717   unformat_input_t *input = vam->input;
15718   vl_api_one_add_del_map_server_t *mp;
15719   u8 is_add = 1;
15720   u8 ipv4_set = 0;
15721   u8 ipv6_set = 0;
15722   ip4_address_t ipv4;
15723   ip6_address_t ipv6;
15724   int ret;
15725
15726   /* Parse args required to build the message */
15727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15728     {
15729       if (unformat (input, "del"))
15730         {
15731           is_add = 0;
15732         }
15733       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15734         {
15735           ipv4_set = 1;
15736         }
15737       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15738         {
15739           ipv6_set = 1;
15740         }
15741       else
15742         break;
15743     }
15744
15745   if (ipv4_set && ipv6_set)
15746     {
15747       errmsg ("both eid v4 and v6 addresses set");
15748       return -99;
15749     }
15750
15751   if (!ipv4_set && !ipv6_set)
15752     {
15753       errmsg ("eid addresses not set");
15754       return -99;
15755     }
15756
15757   /* Construct the API message */
15758   M (ONE_ADD_DEL_MAP_SERVER, mp);
15759
15760   mp->is_add = is_add;
15761   if (ipv6_set)
15762     {
15763       mp->is_ipv6 = 1;
15764       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15765     }
15766   else
15767     {
15768       mp->is_ipv6 = 0;
15769       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15770     }
15771
15772   /* send it... */
15773   S (mp);
15774
15775   /* Wait for a reply... */
15776   W (ret);
15777   return ret;
15778 }
15779
15780 #define api_lisp_add_del_map_server api_one_add_del_map_server
15781
15782 static int
15783 api_one_add_del_map_resolver (vat_main_t * vam)
15784 {
15785   unformat_input_t *input = vam->input;
15786   vl_api_one_add_del_map_resolver_t *mp;
15787   u8 is_add = 1;
15788   u8 ipv4_set = 0;
15789   u8 ipv6_set = 0;
15790   ip4_address_t ipv4;
15791   ip6_address_t ipv6;
15792   int ret;
15793
15794   /* Parse args required to build the message */
15795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15796     {
15797       if (unformat (input, "del"))
15798         {
15799           is_add = 0;
15800         }
15801       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15802         {
15803           ipv4_set = 1;
15804         }
15805       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15806         {
15807           ipv6_set = 1;
15808         }
15809       else
15810         break;
15811     }
15812
15813   if (ipv4_set && ipv6_set)
15814     {
15815       errmsg ("both eid v4 and v6 addresses set");
15816       return -99;
15817     }
15818
15819   if (!ipv4_set && !ipv6_set)
15820     {
15821       errmsg ("eid addresses not set");
15822       return -99;
15823     }
15824
15825   /* Construct the API message */
15826   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15827
15828   mp->is_add = is_add;
15829   if (ipv6_set)
15830     {
15831       mp->is_ipv6 = 1;
15832       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15833     }
15834   else
15835     {
15836       mp->is_ipv6 = 0;
15837       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15838     }
15839
15840   /* send it... */
15841   S (mp);
15842
15843   /* Wait for a reply... */
15844   W (ret);
15845   return ret;
15846 }
15847
15848 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15849
15850 static int
15851 api_lisp_gpe_enable_disable (vat_main_t * vam)
15852 {
15853   unformat_input_t *input = vam->input;
15854   vl_api_gpe_enable_disable_t *mp;
15855   u8 is_set = 0;
15856   u8 is_en = 1;
15857   int ret;
15858
15859   /* Parse args required to build the message */
15860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15861     {
15862       if (unformat (input, "enable"))
15863         {
15864           is_set = 1;
15865           is_en = 1;
15866         }
15867       else if (unformat (input, "disable"))
15868         {
15869           is_set = 1;
15870           is_en = 0;
15871         }
15872       else
15873         break;
15874     }
15875
15876   if (is_set == 0)
15877     {
15878       errmsg ("Value not set");
15879       return -99;
15880     }
15881
15882   /* Construct the API message */
15883   M (GPE_ENABLE_DISABLE, mp);
15884
15885   mp->is_en = is_en;
15886
15887   /* send it... */
15888   S (mp);
15889
15890   /* Wait for a reply... */
15891   W (ret);
15892   return ret;
15893 }
15894
15895 static int
15896 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15897 {
15898   unformat_input_t *input = vam->input;
15899   vl_api_one_rloc_probe_enable_disable_t *mp;
15900   u8 is_set = 0;
15901   u8 is_en = 0;
15902   int ret;
15903
15904   /* Parse args required to build the message */
15905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15906     {
15907       if (unformat (input, "enable"))
15908         {
15909           is_set = 1;
15910           is_en = 1;
15911         }
15912       else if (unformat (input, "disable"))
15913         is_set = 1;
15914       else
15915         break;
15916     }
15917
15918   if (!is_set)
15919     {
15920       errmsg ("Value not set");
15921       return -99;
15922     }
15923
15924   /* Construct the API message */
15925   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15926
15927   mp->is_enabled = is_en;
15928
15929   /* send it... */
15930   S (mp);
15931
15932   /* Wait for a reply... */
15933   W (ret);
15934   return ret;
15935 }
15936
15937 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15938
15939 static int
15940 api_one_map_register_enable_disable (vat_main_t * vam)
15941 {
15942   unformat_input_t *input = vam->input;
15943   vl_api_one_map_register_enable_disable_t *mp;
15944   u8 is_set = 0;
15945   u8 is_en = 0;
15946   int ret;
15947
15948   /* Parse args required to build the message */
15949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15950     {
15951       if (unformat (input, "enable"))
15952         {
15953           is_set = 1;
15954           is_en = 1;
15955         }
15956       else if (unformat (input, "disable"))
15957         is_set = 1;
15958       else
15959         break;
15960     }
15961
15962   if (!is_set)
15963     {
15964       errmsg ("Value not set");
15965       return -99;
15966     }
15967
15968   /* Construct the API message */
15969   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15970
15971   mp->is_enabled = is_en;
15972
15973   /* send it... */
15974   S (mp);
15975
15976   /* Wait for a reply... */
15977   W (ret);
15978   return ret;
15979 }
15980
15981 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15982
15983 static int
15984 api_one_enable_disable (vat_main_t * vam)
15985 {
15986   unformat_input_t *input = vam->input;
15987   vl_api_one_enable_disable_t *mp;
15988   u8 is_set = 0;
15989   u8 is_en = 0;
15990   int ret;
15991
15992   /* Parse args required to build the message */
15993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15994     {
15995       if (unformat (input, "enable"))
15996         {
15997           is_set = 1;
15998           is_en = 1;
15999         }
16000       else if (unformat (input, "disable"))
16001         {
16002           is_set = 1;
16003         }
16004       else
16005         break;
16006     }
16007
16008   if (!is_set)
16009     {
16010       errmsg ("Value not set");
16011       return -99;
16012     }
16013
16014   /* Construct the API message */
16015   M (ONE_ENABLE_DISABLE, mp);
16016
16017   mp->is_en = is_en;
16018
16019   /* send it... */
16020   S (mp);
16021
16022   /* Wait for a reply... */
16023   W (ret);
16024   return ret;
16025 }
16026
16027 #define api_lisp_enable_disable api_one_enable_disable
16028
16029 static int
16030 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16031 {
16032   unformat_input_t *input = vam->input;
16033   vl_api_one_enable_disable_xtr_mode_t *mp;
16034   u8 is_set = 0;
16035   u8 is_en = 0;
16036   int ret;
16037
16038   /* Parse args required to build the message */
16039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16040     {
16041       if (unformat (input, "enable"))
16042         {
16043           is_set = 1;
16044           is_en = 1;
16045         }
16046       else if (unformat (input, "disable"))
16047         {
16048           is_set = 1;
16049         }
16050       else
16051         break;
16052     }
16053
16054   if (!is_set)
16055     {
16056       errmsg ("Value not set");
16057       return -99;
16058     }
16059
16060   /* Construct the API message */
16061   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16062
16063   mp->is_en = is_en;
16064
16065   /* send it... */
16066   S (mp);
16067
16068   /* Wait for a reply... */
16069   W (ret);
16070   return ret;
16071 }
16072
16073 static int
16074 api_one_show_xtr_mode (vat_main_t * vam)
16075 {
16076   vl_api_one_show_xtr_mode_t *mp;
16077   int ret;
16078
16079   /* Construct the API message */
16080   M (ONE_SHOW_XTR_MODE, mp);
16081
16082   /* send it... */
16083   S (mp);
16084
16085   /* Wait for a reply... */
16086   W (ret);
16087   return ret;
16088 }
16089
16090 static int
16091 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16092 {
16093   unformat_input_t *input = vam->input;
16094   vl_api_one_enable_disable_pitr_mode_t *mp;
16095   u8 is_set = 0;
16096   u8 is_en = 0;
16097   int ret;
16098
16099   /* Parse args required to build the message */
16100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16101     {
16102       if (unformat (input, "enable"))
16103         {
16104           is_set = 1;
16105           is_en = 1;
16106         }
16107       else if (unformat (input, "disable"))
16108         {
16109           is_set = 1;
16110         }
16111       else
16112         break;
16113     }
16114
16115   if (!is_set)
16116     {
16117       errmsg ("Value not set");
16118       return -99;
16119     }
16120
16121   /* Construct the API message */
16122   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16123
16124   mp->is_en = is_en;
16125
16126   /* send it... */
16127   S (mp);
16128
16129   /* Wait for a reply... */
16130   W (ret);
16131   return ret;
16132 }
16133
16134 static int
16135 api_one_show_pitr_mode (vat_main_t * vam)
16136 {
16137   vl_api_one_show_pitr_mode_t *mp;
16138   int ret;
16139
16140   /* Construct the API message */
16141   M (ONE_SHOW_PITR_MODE, mp);
16142
16143   /* send it... */
16144   S (mp);
16145
16146   /* Wait for a reply... */
16147   W (ret);
16148   return ret;
16149 }
16150
16151 static int
16152 api_one_enable_disable_petr_mode (vat_main_t * vam)
16153 {
16154   unformat_input_t *input = vam->input;
16155   vl_api_one_enable_disable_petr_mode_t *mp;
16156   u8 is_set = 0;
16157   u8 is_en = 0;
16158   int ret;
16159
16160   /* Parse args required to build the message */
16161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16162     {
16163       if (unformat (input, "enable"))
16164         {
16165           is_set = 1;
16166           is_en = 1;
16167         }
16168       else if (unformat (input, "disable"))
16169         {
16170           is_set = 1;
16171         }
16172       else
16173         break;
16174     }
16175
16176   if (!is_set)
16177     {
16178       errmsg ("Value not set");
16179       return -99;
16180     }
16181
16182   /* Construct the API message */
16183   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16184
16185   mp->is_en = is_en;
16186
16187   /* send it... */
16188   S (mp);
16189
16190   /* Wait for a reply... */
16191   W (ret);
16192   return ret;
16193 }
16194
16195 static int
16196 api_one_show_petr_mode (vat_main_t * vam)
16197 {
16198   vl_api_one_show_petr_mode_t *mp;
16199   int ret;
16200
16201   /* Construct the API message */
16202   M (ONE_SHOW_PETR_MODE, mp);
16203
16204   /* send it... */
16205   S (mp);
16206
16207   /* Wait for a reply... */
16208   W (ret);
16209   return ret;
16210 }
16211
16212 static int
16213 api_show_one_map_register_state (vat_main_t * vam)
16214 {
16215   vl_api_show_one_map_register_state_t *mp;
16216   int ret;
16217
16218   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16219
16220   /* send */
16221   S (mp);
16222
16223   /* wait for reply */
16224   W (ret);
16225   return ret;
16226 }
16227
16228 #define api_show_lisp_map_register_state api_show_one_map_register_state
16229
16230 static int
16231 api_show_one_rloc_probe_state (vat_main_t * vam)
16232 {
16233   vl_api_show_one_rloc_probe_state_t *mp;
16234   int ret;
16235
16236   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16237
16238   /* send */
16239   S (mp);
16240
16241   /* wait for reply */
16242   W (ret);
16243   return ret;
16244 }
16245
16246 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16247
16248 static int
16249 api_one_add_del_ndp_entry (vat_main_t * vam)
16250 {
16251   vl_api_one_add_del_ndp_entry_t *mp;
16252   unformat_input_t *input = vam->input;
16253   u8 is_add = 1;
16254   u8 mac_set = 0;
16255   u8 bd_set = 0;
16256   u8 ip_set = 0;
16257   u8 mac[6] = { 0, };
16258   u8 ip6[16] = { 0, };
16259   u32 bd = ~0;
16260   int ret;
16261
16262   /* Parse args required to build the message */
16263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16264     {
16265       if (unformat (input, "del"))
16266         is_add = 0;
16267       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16268         mac_set = 1;
16269       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16270         ip_set = 1;
16271       else if (unformat (input, "bd %d", &bd))
16272         bd_set = 1;
16273       else
16274         {
16275           errmsg ("parse error '%U'", format_unformat_error, input);
16276           return -99;
16277         }
16278     }
16279
16280   if (!bd_set || !ip_set || (!mac_set && is_add))
16281     {
16282       errmsg ("Missing BD, IP or MAC!");
16283       return -99;
16284     }
16285
16286   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16287   mp->is_add = is_add;
16288   clib_memcpy (mp->mac, mac, 6);
16289   mp->bd = clib_host_to_net_u32 (bd);
16290   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16291
16292   /* send */
16293   S (mp);
16294
16295   /* wait for reply */
16296   W (ret);
16297   return ret;
16298 }
16299
16300 static int
16301 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16302 {
16303   vl_api_one_add_del_l2_arp_entry_t *mp;
16304   unformat_input_t *input = vam->input;
16305   u8 is_add = 1;
16306   u8 mac_set = 0;
16307   u8 bd_set = 0;
16308   u8 ip_set = 0;
16309   u8 mac[6] = { 0, };
16310   u32 ip4 = 0, bd = ~0;
16311   int ret;
16312
16313   /* Parse args required to build the message */
16314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (input, "del"))
16317         is_add = 0;
16318       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16319         mac_set = 1;
16320       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16321         ip_set = 1;
16322       else if (unformat (input, "bd %d", &bd))
16323         bd_set = 1;
16324       else
16325         {
16326           errmsg ("parse error '%U'", format_unformat_error, input);
16327           return -99;
16328         }
16329     }
16330
16331   if (!bd_set || !ip_set || (!mac_set && is_add))
16332     {
16333       errmsg ("Missing BD, IP or MAC!");
16334       return -99;
16335     }
16336
16337   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16338   mp->is_add = is_add;
16339   clib_memcpy (mp->mac, mac, 6);
16340   mp->bd = clib_host_to_net_u32 (bd);
16341   mp->ip4 = ip4;
16342
16343   /* send */
16344   S (mp);
16345
16346   /* wait for reply */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 static int
16352 api_one_ndp_bd_get (vat_main_t * vam)
16353 {
16354   vl_api_one_ndp_bd_get_t *mp;
16355   int ret;
16356
16357   M (ONE_NDP_BD_GET, mp);
16358
16359   /* send */
16360   S (mp);
16361
16362   /* wait for reply */
16363   W (ret);
16364   return ret;
16365 }
16366
16367 static int
16368 api_one_ndp_entries_get (vat_main_t * vam)
16369 {
16370   vl_api_one_ndp_entries_get_t *mp;
16371   unformat_input_t *input = vam->input;
16372   u8 bd_set = 0;
16373   u32 bd = ~0;
16374   int ret;
16375
16376   /* Parse args required to build the message */
16377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (input, "bd %d", &bd))
16380         bd_set = 1;
16381       else
16382         {
16383           errmsg ("parse error '%U'", format_unformat_error, input);
16384           return -99;
16385         }
16386     }
16387
16388   if (!bd_set)
16389     {
16390       errmsg ("Expected bridge domain!");
16391       return -99;
16392     }
16393
16394   M (ONE_NDP_ENTRIES_GET, mp);
16395   mp->bd = clib_host_to_net_u32 (bd);
16396
16397   /* send */
16398   S (mp);
16399
16400   /* wait for reply */
16401   W (ret);
16402   return ret;
16403 }
16404
16405 static int
16406 api_one_l2_arp_bd_get (vat_main_t * vam)
16407 {
16408   vl_api_one_l2_arp_bd_get_t *mp;
16409   int ret;
16410
16411   M (ONE_L2_ARP_BD_GET, mp);
16412
16413   /* send */
16414   S (mp);
16415
16416   /* wait for reply */
16417   W (ret);
16418   return ret;
16419 }
16420
16421 static int
16422 api_one_l2_arp_entries_get (vat_main_t * vam)
16423 {
16424   vl_api_one_l2_arp_entries_get_t *mp;
16425   unformat_input_t *input = vam->input;
16426   u8 bd_set = 0;
16427   u32 bd = ~0;
16428   int ret;
16429
16430   /* Parse args required to build the message */
16431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16432     {
16433       if (unformat (input, "bd %d", &bd))
16434         bd_set = 1;
16435       else
16436         {
16437           errmsg ("parse error '%U'", format_unformat_error, input);
16438           return -99;
16439         }
16440     }
16441
16442   if (!bd_set)
16443     {
16444       errmsg ("Expected bridge domain!");
16445       return -99;
16446     }
16447
16448   M (ONE_L2_ARP_ENTRIES_GET, mp);
16449   mp->bd = clib_host_to_net_u32 (bd);
16450
16451   /* send */
16452   S (mp);
16453
16454   /* wait for reply */
16455   W (ret);
16456   return ret;
16457 }
16458
16459 static int
16460 api_one_stats_enable_disable (vat_main_t * vam)
16461 {
16462   vl_api_one_stats_enable_disable_t *mp;
16463   unformat_input_t *input = vam->input;
16464   u8 is_set = 0;
16465   u8 is_en = 0;
16466   int ret;
16467
16468   /* Parse args required to build the message */
16469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16470     {
16471       if (unformat (input, "enable"))
16472         {
16473           is_set = 1;
16474           is_en = 1;
16475         }
16476       else if (unformat (input, "disable"))
16477         {
16478           is_set = 1;
16479         }
16480       else
16481         break;
16482     }
16483
16484   if (!is_set)
16485     {
16486       errmsg ("Value not set");
16487       return -99;
16488     }
16489
16490   M (ONE_STATS_ENABLE_DISABLE, mp);
16491   mp->is_en = is_en;
16492
16493   /* send */
16494   S (mp);
16495
16496   /* wait for reply */
16497   W (ret);
16498   return ret;
16499 }
16500
16501 static int
16502 api_show_one_stats_enable_disable (vat_main_t * vam)
16503 {
16504   vl_api_show_one_stats_enable_disable_t *mp;
16505   int ret;
16506
16507   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16508
16509   /* send */
16510   S (mp);
16511
16512   /* wait for reply */
16513   W (ret);
16514   return ret;
16515 }
16516
16517 static int
16518 api_show_one_map_request_mode (vat_main_t * vam)
16519 {
16520   vl_api_show_one_map_request_mode_t *mp;
16521   int ret;
16522
16523   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16524
16525   /* send */
16526   S (mp);
16527
16528   /* wait for reply */
16529   W (ret);
16530   return ret;
16531 }
16532
16533 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16534
16535 static int
16536 api_one_map_request_mode (vat_main_t * vam)
16537 {
16538   unformat_input_t *input = vam->input;
16539   vl_api_one_map_request_mode_t *mp;
16540   u8 mode = 0;
16541   int ret;
16542
16543   /* Parse args required to build the message */
16544   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16545     {
16546       if (unformat (input, "dst-only"))
16547         mode = 0;
16548       else if (unformat (input, "src-dst"))
16549         mode = 1;
16550       else
16551         {
16552           errmsg ("parse error '%U'", format_unformat_error, input);
16553           return -99;
16554         }
16555     }
16556
16557   M (ONE_MAP_REQUEST_MODE, mp);
16558
16559   mp->mode = mode;
16560
16561   /* send */
16562   S (mp);
16563
16564   /* wait for reply */
16565   W (ret);
16566   return ret;
16567 }
16568
16569 #define api_lisp_map_request_mode api_one_map_request_mode
16570
16571 /**
16572  * Enable/disable ONE proxy ITR.
16573  *
16574  * @param vam vpp API test context
16575  * @return return code
16576  */
16577 static int
16578 api_one_pitr_set_locator_set (vat_main_t * vam)
16579 {
16580   u8 ls_name_set = 0;
16581   unformat_input_t *input = vam->input;
16582   vl_api_one_pitr_set_locator_set_t *mp;
16583   u8 is_add = 1;
16584   u8 *ls_name = 0;
16585   int ret;
16586
16587   /* Parse args required to build the message */
16588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16589     {
16590       if (unformat (input, "del"))
16591         is_add = 0;
16592       else if (unformat (input, "locator-set %s", &ls_name))
16593         ls_name_set = 1;
16594       else
16595         {
16596           errmsg ("parse error '%U'", format_unformat_error, input);
16597           return -99;
16598         }
16599     }
16600
16601   if (!ls_name_set)
16602     {
16603       errmsg ("locator-set name not set!");
16604       return -99;
16605     }
16606
16607   M (ONE_PITR_SET_LOCATOR_SET, mp);
16608
16609   mp->is_add = is_add;
16610   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16611   vec_free (ls_name);
16612
16613   /* send */
16614   S (mp);
16615
16616   /* wait for reply */
16617   W (ret);
16618   return ret;
16619 }
16620
16621 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16622
16623 static int
16624 api_one_nsh_set_locator_set (vat_main_t * vam)
16625 {
16626   u8 ls_name_set = 0;
16627   unformat_input_t *input = vam->input;
16628   vl_api_one_nsh_set_locator_set_t *mp;
16629   u8 is_add = 1;
16630   u8 *ls_name = 0;
16631   int ret;
16632
16633   /* Parse args required to build the message */
16634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16635     {
16636       if (unformat (input, "del"))
16637         is_add = 0;
16638       else if (unformat (input, "ls %s", &ls_name))
16639         ls_name_set = 1;
16640       else
16641         {
16642           errmsg ("parse error '%U'", format_unformat_error, input);
16643           return -99;
16644         }
16645     }
16646
16647   if (!ls_name_set && is_add)
16648     {
16649       errmsg ("locator-set name not set!");
16650       return -99;
16651     }
16652
16653   M (ONE_NSH_SET_LOCATOR_SET, mp);
16654
16655   mp->is_add = is_add;
16656   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16657   vec_free (ls_name);
16658
16659   /* send */
16660   S (mp);
16661
16662   /* wait for reply */
16663   W (ret);
16664   return ret;
16665 }
16666
16667 static int
16668 api_show_one_pitr (vat_main_t * vam)
16669 {
16670   vl_api_show_one_pitr_t *mp;
16671   int ret;
16672
16673   if (!vam->json_output)
16674     {
16675       print (vam->ofp, "%=20s", "lisp status:");
16676     }
16677
16678   M (SHOW_ONE_PITR, mp);
16679   /* send it... */
16680   S (mp);
16681
16682   /* Wait for a reply... */
16683   W (ret);
16684   return ret;
16685 }
16686
16687 #define api_show_lisp_pitr api_show_one_pitr
16688
16689 static int
16690 api_one_use_petr (vat_main_t * vam)
16691 {
16692   unformat_input_t *input = vam->input;
16693   vl_api_one_use_petr_t *mp;
16694   u8 is_add = 0;
16695   ip_address_t ip;
16696   int ret;
16697
16698   clib_memset (&ip, 0, sizeof (ip));
16699
16700   /* Parse args required to build the message */
16701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16702     {
16703       if (unformat (input, "disable"))
16704         is_add = 0;
16705       else
16706         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16707         {
16708           is_add = 1;
16709           ip_addr_version (&ip) = IP4;
16710         }
16711       else
16712         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16713         {
16714           is_add = 1;
16715           ip_addr_version (&ip) = IP6;
16716         }
16717       else
16718         {
16719           errmsg ("parse error '%U'", format_unformat_error, input);
16720           return -99;
16721         }
16722     }
16723
16724   M (ONE_USE_PETR, mp);
16725
16726   mp->is_add = is_add;
16727   if (is_add)
16728     {
16729       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16730       if (mp->is_ip4)
16731         clib_memcpy (mp->address, &ip, 4);
16732       else
16733         clib_memcpy (mp->address, &ip, 16);
16734     }
16735
16736   /* send */
16737   S (mp);
16738
16739   /* wait for reply */
16740   W (ret);
16741   return ret;
16742 }
16743
16744 #define api_lisp_use_petr api_one_use_petr
16745
16746 static int
16747 api_show_one_nsh_mapping (vat_main_t * vam)
16748 {
16749   vl_api_show_one_use_petr_t *mp;
16750   int ret;
16751
16752   if (!vam->json_output)
16753     {
16754       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16755     }
16756
16757   M (SHOW_ONE_NSH_MAPPING, mp);
16758   /* send it... */
16759   S (mp);
16760
16761   /* Wait for a reply... */
16762   W (ret);
16763   return ret;
16764 }
16765
16766 static int
16767 api_show_one_use_petr (vat_main_t * vam)
16768 {
16769   vl_api_show_one_use_petr_t *mp;
16770   int ret;
16771
16772   if (!vam->json_output)
16773     {
16774       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16775     }
16776
16777   M (SHOW_ONE_USE_PETR, mp);
16778   /* send it... */
16779   S (mp);
16780
16781   /* Wait for a reply... */
16782   W (ret);
16783   return ret;
16784 }
16785
16786 #define api_show_lisp_use_petr api_show_one_use_petr
16787
16788 /**
16789  * Add/delete mapping between vni and vrf
16790  */
16791 static int
16792 api_one_eid_table_add_del_map (vat_main_t * vam)
16793 {
16794   unformat_input_t *input = vam->input;
16795   vl_api_one_eid_table_add_del_map_t *mp;
16796   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16797   u32 vni, vrf, bd_index;
16798   int ret;
16799
16800   /* Parse args required to build the message */
16801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16802     {
16803       if (unformat (input, "del"))
16804         is_add = 0;
16805       else if (unformat (input, "vrf %d", &vrf))
16806         vrf_set = 1;
16807       else if (unformat (input, "bd_index %d", &bd_index))
16808         bd_index_set = 1;
16809       else if (unformat (input, "vni %d", &vni))
16810         vni_set = 1;
16811       else
16812         break;
16813     }
16814
16815   if (!vni_set || (!vrf_set && !bd_index_set))
16816     {
16817       errmsg ("missing arguments!");
16818       return -99;
16819     }
16820
16821   if (vrf_set && bd_index_set)
16822     {
16823       errmsg ("error: both vrf and bd entered!");
16824       return -99;
16825     }
16826
16827   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16828
16829   mp->is_add = is_add;
16830   mp->vni = htonl (vni);
16831   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16832   mp->is_l2 = bd_index_set;
16833
16834   /* send */
16835   S (mp);
16836
16837   /* wait for reply */
16838   W (ret);
16839   return ret;
16840 }
16841
16842 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16843
16844 uword
16845 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16846 {
16847   u32 *action = va_arg (*args, u32 *);
16848   u8 *s = 0;
16849
16850   if (unformat (input, "%s", &s))
16851     {
16852       if (!strcmp ((char *) s, "no-action"))
16853         action[0] = 0;
16854       else if (!strcmp ((char *) s, "natively-forward"))
16855         action[0] = 1;
16856       else if (!strcmp ((char *) s, "send-map-request"))
16857         action[0] = 2;
16858       else if (!strcmp ((char *) s, "drop"))
16859         action[0] = 3;
16860       else
16861         {
16862           clib_warning ("invalid action: '%s'", s);
16863           action[0] = 3;
16864         }
16865     }
16866   else
16867     return 0;
16868
16869   vec_free (s);
16870   return 1;
16871 }
16872
16873 /**
16874  * Add/del remote mapping to/from ONE control plane
16875  *
16876  * @param vam vpp API test context
16877  * @return return code
16878  */
16879 static int
16880 api_one_add_del_remote_mapping (vat_main_t * vam)
16881 {
16882   unformat_input_t *input = vam->input;
16883   vl_api_one_add_del_remote_mapping_t *mp;
16884   u32 vni = 0;
16885   lisp_eid_vat_t _eid, *eid = &_eid;
16886   lisp_eid_vat_t _seid, *seid = &_seid;
16887   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16888   u32 action = ~0, p, w, data_len;
16889   ip4_address_t rloc4;
16890   ip6_address_t rloc6;
16891   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16892   int ret;
16893
16894   clib_memset (&rloc, 0, sizeof (rloc));
16895
16896   /* Parse args required to build the message */
16897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16898     {
16899       if (unformat (input, "del-all"))
16900         {
16901           del_all = 1;
16902         }
16903       else if (unformat (input, "del"))
16904         {
16905           is_add = 0;
16906         }
16907       else if (unformat (input, "add"))
16908         {
16909           is_add = 1;
16910         }
16911       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16912         {
16913           eid_set = 1;
16914         }
16915       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16916         {
16917           seid_set = 1;
16918         }
16919       else if (unformat (input, "vni %d", &vni))
16920         {
16921           ;
16922         }
16923       else if (unformat (input, "p %d w %d", &p, &w))
16924         {
16925           if (!curr_rloc)
16926             {
16927               errmsg ("No RLOC configured for setting priority/weight!");
16928               return -99;
16929             }
16930           curr_rloc->priority = p;
16931           curr_rloc->weight = w;
16932         }
16933       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16934         {
16935           rloc.is_ip4 = 1;
16936           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16937           vec_add1 (rlocs, rloc);
16938           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16939         }
16940       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16941         {
16942           rloc.is_ip4 = 0;
16943           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16944           vec_add1 (rlocs, rloc);
16945           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16946         }
16947       else if (unformat (input, "action %U",
16948                          unformat_negative_mapping_action, &action))
16949         {
16950           ;
16951         }
16952       else
16953         {
16954           clib_warning ("parse error '%U'", format_unformat_error, input);
16955           return -99;
16956         }
16957     }
16958
16959   if (0 == eid_set)
16960     {
16961       errmsg ("missing params!");
16962       return -99;
16963     }
16964
16965   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16966     {
16967       errmsg ("no action set for negative map-reply!");
16968       return -99;
16969     }
16970
16971   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16972
16973   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16974   mp->is_add = is_add;
16975   mp->vni = htonl (vni);
16976   mp->action = (u8) action;
16977   mp->is_src_dst = seid_set;
16978   mp->eid_len = eid->len;
16979   mp->seid_len = seid->len;
16980   mp->del_all = del_all;
16981   mp->eid_type = eid->type;
16982   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16983   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16984
16985   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16986   clib_memcpy (mp->rlocs, rlocs, data_len);
16987   vec_free (rlocs);
16988
16989   /* send it... */
16990   S (mp);
16991
16992   /* Wait for a reply... */
16993   W (ret);
16994   return ret;
16995 }
16996
16997 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16998
16999 /**
17000  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17001  * forwarding entries in data-plane accordingly.
17002  *
17003  * @param vam vpp API test context
17004  * @return return code
17005  */
17006 static int
17007 api_one_add_del_adjacency (vat_main_t * vam)
17008 {
17009   unformat_input_t *input = vam->input;
17010   vl_api_one_add_del_adjacency_t *mp;
17011   u32 vni = 0;
17012   ip4_address_t leid4, reid4;
17013   ip6_address_t leid6, reid6;
17014   u8 reid_mac[6] = { 0 };
17015   u8 leid_mac[6] = { 0 };
17016   u8 reid_type, leid_type;
17017   u32 leid_len = 0, reid_len = 0, len;
17018   u8 is_add = 1;
17019   int ret;
17020
17021   leid_type = reid_type = (u8) ~ 0;
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         {
17028           is_add = 0;
17029         }
17030       else if (unformat (input, "add"))
17031         {
17032           is_add = 1;
17033         }
17034       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17035                          &reid4, &len))
17036         {
17037           reid_type = 0;        /* ipv4 */
17038           reid_len = len;
17039         }
17040       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17041                          &reid6, &len))
17042         {
17043           reid_type = 1;        /* ipv6 */
17044           reid_len = len;
17045         }
17046       else if (unformat (input, "reid %U", unformat_ethernet_address,
17047                          reid_mac))
17048         {
17049           reid_type = 2;        /* mac */
17050         }
17051       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17052                          &leid4, &len))
17053         {
17054           leid_type = 0;        /* ipv4 */
17055           leid_len = len;
17056         }
17057       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17058                          &leid6, &len))
17059         {
17060           leid_type = 1;        /* ipv6 */
17061           leid_len = len;
17062         }
17063       else if (unformat (input, "leid %U", unformat_ethernet_address,
17064                          leid_mac))
17065         {
17066           leid_type = 2;        /* mac */
17067         }
17068       else if (unformat (input, "vni %d", &vni))
17069         {
17070           ;
17071         }
17072       else
17073         {
17074           errmsg ("parse error '%U'", format_unformat_error, input);
17075           return -99;
17076         }
17077     }
17078
17079   if ((u8) ~ 0 == reid_type)
17080     {
17081       errmsg ("missing params!");
17082       return -99;
17083     }
17084
17085   if (leid_type != reid_type)
17086     {
17087       errmsg ("remote and local EIDs are of different types!");
17088       return -99;
17089     }
17090
17091   M (ONE_ADD_DEL_ADJACENCY, mp);
17092   mp->is_add = is_add;
17093   mp->vni = htonl (vni);
17094   mp->leid_len = leid_len;
17095   mp->reid_len = reid_len;
17096   mp->eid_type = reid_type;
17097
17098   switch (mp->eid_type)
17099     {
17100     case 0:
17101       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17102       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17103       break;
17104     case 1:
17105       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17106       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17107       break;
17108     case 2:
17109       clib_memcpy (mp->leid, leid_mac, 6);
17110       clib_memcpy (mp->reid, reid_mac, 6);
17111       break;
17112     default:
17113       errmsg ("unknown EID type %d!", mp->eid_type);
17114       return 0;
17115     }
17116
17117   /* send it... */
17118   S (mp);
17119
17120   /* Wait for a reply... */
17121   W (ret);
17122   return ret;
17123 }
17124
17125 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17126
17127 uword
17128 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17129 {
17130   u32 *mode = va_arg (*args, u32 *);
17131
17132   if (unformat (input, "lisp"))
17133     *mode = 0;
17134   else if (unformat (input, "vxlan"))
17135     *mode = 1;
17136   else
17137     return 0;
17138
17139   return 1;
17140 }
17141
17142 static int
17143 api_gpe_get_encap_mode (vat_main_t * vam)
17144 {
17145   vl_api_gpe_get_encap_mode_t *mp;
17146   int ret;
17147
17148   /* Construct the API message */
17149   M (GPE_GET_ENCAP_MODE, mp);
17150
17151   /* send it... */
17152   S (mp);
17153
17154   /* Wait for a reply... */
17155   W (ret);
17156   return ret;
17157 }
17158
17159 static int
17160 api_gpe_set_encap_mode (vat_main_t * vam)
17161 {
17162   unformat_input_t *input = vam->input;
17163   vl_api_gpe_set_encap_mode_t *mp;
17164   int ret;
17165   u32 mode = 0;
17166
17167   /* Parse args required to build the message */
17168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17169     {
17170       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17171         ;
17172       else
17173         break;
17174     }
17175
17176   /* Construct the API message */
17177   M (GPE_SET_ENCAP_MODE, mp);
17178
17179   mp->mode = mode;
17180
17181   /* send it... */
17182   S (mp);
17183
17184   /* Wait for a reply... */
17185   W (ret);
17186   return ret;
17187 }
17188
17189 static int
17190 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17191 {
17192   unformat_input_t *input = vam->input;
17193   vl_api_gpe_add_del_iface_t *mp;
17194   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17195   u32 dp_table = 0, vni = 0;
17196   int ret;
17197
17198   /* Parse args required to build the message */
17199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17200     {
17201       if (unformat (input, "up"))
17202         {
17203           action_set = 1;
17204           is_add = 1;
17205         }
17206       else if (unformat (input, "down"))
17207         {
17208           action_set = 1;
17209           is_add = 0;
17210         }
17211       else if (unformat (input, "table_id %d", &dp_table))
17212         {
17213           dp_table_set = 1;
17214         }
17215       else if (unformat (input, "bd_id %d", &dp_table))
17216         {
17217           dp_table_set = 1;
17218           is_l2 = 1;
17219         }
17220       else if (unformat (input, "vni %d", &vni))
17221         {
17222           vni_set = 1;
17223         }
17224       else
17225         break;
17226     }
17227
17228   if (action_set == 0)
17229     {
17230       errmsg ("Action not set");
17231       return -99;
17232     }
17233   if (dp_table_set == 0 || vni_set == 0)
17234     {
17235       errmsg ("vni and dp_table must be set");
17236       return -99;
17237     }
17238
17239   /* Construct the API message */
17240   M (GPE_ADD_DEL_IFACE, mp);
17241
17242   mp->is_add = is_add;
17243   mp->dp_table = clib_host_to_net_u32 (dp_table);
17244   mp->is_l2 = is_l2;
17245   mp->vni = clib_host_to_net_u32 (vni);
17246
17247   /* send it... */
17248   S (mp);
17249
17250   /* Wait for a reply... */
17251   W (ret);
17252   return ret;
17253 }
17254
17255 static int
17256 api_one_map_register_fallback_threshold (vat_main_t * vam)
17257 {
17258   unformat_input_t *input = vam->input;
17259   vl_api_one_map_register_fallback_threshold_t *mp;
17260   u32 value = 0;
17261   u8 is_set = 0;
17262   int ret;
17263
17264   /* Parse args required to build the message */
17265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17266     {
17267       if (unformat (input, "%u", &value))
17268         is_set = 1;
17269       else
17270         {
17271           clib_warning ("parse error '%U'", format_unformat_error, input);
17272           return -99;
17273         }
17274     }
17275
17276   if (!is_set)
17277     {
17278       errmsg ("fallback threshold value is missing!");
17279       return -99;
17280     }
17281
17282   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17283   mp->value = clib_host_to_net_u32 (value);
17284
17285   /* send it... */
17286   S (mp);
17287
17288   /* Wait for a reply... */
17289   W (ret);
17290   return ret;
17291 }
17292
17293 static int
17294 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17295 {
17296   vl_api_show_one_map_register_fallback_threshold_t *mp;
17297   int ret;
17298
17299   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17300
17301   /* send it... */
17302   S (mp);
17303
17304   /* Wait for a reply... */
17305   W (ret);
17306   return ret;
17307 }
17308
17309 uword
17310 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17311 {
17312   u32 *proto = va_arg (*args, u32 *);
17313
17314   if (unformat (input, "udp"))
17315     *proto = 1;
17316   else if (unformat (input, "api"))
17317     *proto = 2;
17318   else
17319     return 0;
17320
17321   return 1;
17322 }
17323
17324 static int
17325 api_one_set_transport_protocol (vat_main_t * vam)
17326 {
17327   unformat_input_t *input = vam->input;
17328   vl_api_one_set_transport_protocol_t *mp;
17329   u8 is_set = 0;
17330   u32 protocol = 0;
17331   int ret;
17332
17333   /* Parse args required to build the message */
17334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17335     {
17336       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17337         is_set = 1;
17338       else
17339         {
17340           clib_warning ("parse error '%U'", format_unformat_error, input);
17341           return -99;
17342         }
17343     }
17344
17345   if (!is_set)
17346     {
17347       errmsg ("Transport protocol missing!");
17348       return -99;
17349     }
17350
17351   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17352   mp->protocol = (u8) protocol;
17353
17354   /* send it... */
17355   S (mp);
17356
17357   /* Wait for a reply... */
17358   W (ret);
17359   return ret;
17360 }
17361
17362 static int
17363 api_one_get_transport_protocol (vat_main_t * vam)
17364 {
17365   vl_api_one_get_transport_protocol_t *mp;
17366   int ret;
17367
17368   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17369
17370   /* send it... */
17371   S (mp);
17372
17373   /* Wait for a reply... */
17374   W (ret);
17375   return ret;
17376 }
17377
17378 static int
17379 api_one_map_register_set_ttl (vat_main_t * vam)
17380 {
17381   unformat_input_t *input = vam->input;
17382   vl_api_one_map_register_set_ttl_t *mp;
17383   u32 ttl = 0;
17384   u8 is_set = 0;
17385   int ret;
17386
17387   /* Parse args required to build the message */
17388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17389     {
17390       if (unformat (input, "%u", &ttl))
17391         is_set = 1;
17392       else
17393         {
17394           clib_warning ("parse error '%U'", format_unformat_error, input);
17395           return -99;
17396         }
17397     }
17398
17399   if (!is_set)
17400     {
17401       errmsg ("TTL value missing!");
17402       return -99;
17403     }
17404
17405   M (ONE_MAP_REGISTER_SET_TTL, mp);
17406   mp->ttl = clib_host_to_net_u32 (ttl);
17407
17408   /* send it... */
17409   S (mp);
17410
17411   /* Wait for a reply... */
17412   W (ret);
17413   return ret;
17414 }
17415
17416 static int
17417 api_show_one_map_register_ttl (vat_main_t * vam)
17418 {
17419   vl_api_show_one_map_register_ttl_t *mp;
17420   int ret;
17421
17422   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17423
17424   /* send it... */
17425   S (mp);
17426
17427   /* Wait for a reply... */
17428   W (ret);
17429   return ret;
17430 }
17431
17432 /**
17433  * Add/del map request itr rlocs from ONE control plane and updates
17434  *
17435  * @param vam vpp API test context
17436  * @return return code
17437  */
17438 static int
17439 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17440 {
17441   unformat_input_t *input = vam->input;
17442   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17443   u8 *locator_set_name = 0;
17444   u8 locator_set_name_set = 0;
17445   u8 is_add = 1;
17446   int ret;
17447
17448   /* Parse args required to build the message */
17449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17450     {
17451       if (unformat (input, "del"))
17452         {
17453           is_add = 0;
17454         }
17455       else if (unformat (input, "%_%v%_", &locator_set_name))
17456         {
17457           locator_set_name_set = 1;
17458         }
17459       else
17460         {
17461           clib_warning ("parse error '%U'", format_unformat_error, input);
17462           return -99;
17463         }
17464     }
17465
17466   if (is_add && !locator_set_name_set)
17467     {
17468       errmsg ("itr-rloc is not set!");
17469       return -99;
17470     }
17471
17472   if (is_add && vec_len (locator_set_name) > 64)
17473     {
17474       errmsg ("itr-rloc locator-set name too long");
17475       vec_free (locator_set_name);
17476       return -99;
17477     }
17478
17479   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17480   mp->is_add = is_add;
17481   if (is_add)
17482     {
17483       clib_memcpy (mp->locator_set_name, locator_set_name,
17484                    vec_len (locator_set_name));
17485     }
17486   else
17487     {
17488       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17489     }
17490   vec_free (locator_set_name);
17491
17492   /* send it... */
17493   S (mp);
17494
17495   /* Wait for a reply... */
17496   W (ret);
17497   return ret;
17498 }
17499
17500 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17501
17502 static int
17503 api_one_locator_dump (vat_main_t * vam)
17504 {
17505   unformat_input_t *input = vam->input;
17506   vl_api_one_locator_dump_t *mp;
17507   vl_api_control_ping_t *mp_ping;
17508   u8 is_index_set = 0, is_name_set = 0;
17509   u8 *ls_name = 0;
17510   u32 ls_index = ~0;
17511   int ret;
17512
17513   /* Parse args required to build the message */
17514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17515     {
17516       if (unformat (input, "ls_name %_%v%_", &ls_name))
17517         {
17518           is_name_set = 1;
17519         }
17520       else if (unformat (input, "ls_index %d", &ls_index))
17521         {
17522           is_index_set = 1;
17523         }
17524       else
17525         {
17526           errmsg ("parse error '%U'", format_unformat_error, input);
17527           return -99;
17528         }
17529     }
17530
17531   if (!is_index_set && !is_name_set)
17532     {
17533       errmsg ("error: expected one of index or name!");
17534       return -99;
17535     }
17536
17537   if (is_index_set && is_name_set)
17538     {
17539       errmsg ("error: only one param expected!");
17540       return -99;
17541     }
17542
17543   if (vec_len (ls_name) > 62)
17544     {
17545       errmsg ("error: locator set name too long!");
17546       return -99;
17547     }
17548
17549   if (!vam->json_output)
17550     {
17551       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17552     }
17553
17554   M (ONE_LOCATOR_DUMP, mp);
17555   mp->is_index_set = is_index_set;
17556
17557   if (is_index_set)
17558     mp->ls_index = clib_host_to_net_u32 (ls_index);
17559   else
17560     {
17561       vec_add1 (ls_name, 0);
17562       strncpy ((char *) mp->ls_name, (char *) ls_name,
17563                sizeof (mp->ls_name) - 1);
17564     }
17565
17566   /* send it... */
17567   S (mp);
17568
17569   /* Use a control ping for synchronization */
17570   MPING (CONTROL_PING, mp_ping);
17571   S (mp_ping);
17572
17573   /* Wait for a reply... */
17574   W (ret);
17575   return ret;
17576 }
17577
17578 #define api_lisp_locator_dump api_one_locator_dump
17579
17580 static int
17581 api_one_locator_set_dump (vat_main_t * vam)
17582 {
17583   vl_api_one_locator_set_dump_t *mp;
17584   vl_api_control_ping_t *mp_ping;
17585   unformat_input_t *input = vam->input;
17586   u8 filter = 0;
17587   int ret;
17588
17589   /* Parse args required to build the message */
17590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17591     {
17592       if (unformat (input, "local"))
17593         {
17594           filter = 1;
17595         }
17596       else if (unformat (input, "remote"))
17597         {
17598           filter = 2;
17599         }
17600       else
17601         {
17602           errmsg ("parse error '%U'", format_unformat_error, input);
17603           return -99;
17604         }
17605     }
17606
17607   if (!vam->json_output)
17608     {
17609       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17610     }
17611
17612   M (ONE_LOCATOR_SET_DUMP, mp);
17613
17614   mp->filter = filter;
17615
17616   /* send it... */
17617   S (mp);
17618
17619   /* Use a control ping for synchronization */
17620   MPING (CONTROL_PING, mp_ping);
17621   S (mp_ping);
17622
17623   /* Wait for a reply... */
17624   W (ret);
17625   return ret;
17626 }
17627
17628 #define api_lisp_locator_set_dump api_one_locator_set_dump
17629
17630 static int
17631 api_one_eid_table_map_dump (vat_main_t * vam)
17632 {
17633   u8 is_l2 = 0;
17634   u8 mode_set = 0;
17635   unformat_input_t *input = vam->input;
17636   vl_api_one_eid_table_map_dump_t *mp;
17637   vl_api_control_ping_t *mp_ping;
17638   int ret;
17639
17640   /* Parse args required to build the message */
17641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17642     {
17643       if (unformat (input, "l2"))
17644         {
17645           is_l2 = 1;
17646           mode_set = 1;
17647         }
17648       else if (unformat (input, "l3"))
17649         {
17650           is_l2 = 0;
17651           mode_set = 1;
17652         }
17653       else
17654         {
17655           errmsg ("parse error '%U'", format_unformat_error, input);
17656           return -99;
17657         }
17658     }
17659
17660   if (!mode_set)
17661     {
17662       errmsg ("expected one of 'l2' or 'l3' parameter!");
17663       return -99;
17664     }
17665
17666   if (!vam->json_output)
17667     {
17668       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17669     }
17670
17671   M (ONE_EID_TABLE_MAP_DUMP, mp);
17672   mp->is_l2 = is_l2;
17673
17674   /* send it... */
17675   S (mp);
17676
17677   /* Use a control ping for synchronization */
17678   MPING (CONTROL_PING, mp_ping);
17679   S (mp_ping);
17680
17681   /* Wait for a reply... */
17682   W (ret);
17683   return ret;
17684 }
17685
17686 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17687
17688 static int
17689 api_one_eid_table_vni_dump (vat_main_t * vam)
17690 {
17691   vl_api_one_eid_table_vni_dump_t *mp;
17692   vl_api_control_ping_t *mp_ping;
17693   int ret;
17694
17695   if (!vam->json_output)
17696     {
17697       print (vam->ofp, "VNI");
17698     }
17699
17700   M (ONE_EID_TABLE_VNI_DUMP, mp);
17701
17702   /* send it... */
17703   S (mp);
17704
17705   /* Use a control ping for synchronization */
17706   MPING (CONTROL_PING, mp_ping);
17707   S (mp_ping);
17708
17709   /* Wait for a reply... */
17710   W (ret);
17711   return ret;
17712 }
17713
17714 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17715
17716 static int
17717 api_one_eid_table_dump (vat_main_t * vam)
17718 {
17719   unformat_input_t *i = vam->input;
17720   vl_api_one_eid_table_dump_t *mp;
17721   vl_api_control_ping_t *mp_ping;
17722   struct in_addr ip4;
17723   struct in6_addr ip6;
17724   u8 mac[6];
17725   u8 eid_type = ~0, eid_set = 0;
17726   u32 prefix_length = ~0, t, vni = 0;
17727   u8 filter = 0;
17728   int ret;
17729   lisp_nsh_api_t nsh;
17730
17731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17732     {
17733       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17734         {
17735           eid_set = 1;
17736           eid_type = 0;
17737           prefix_length = t;
17738         }
17739       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17740         {
17741           eid_set = 1;
17742           eid_type = 1;
17743           prefix_length = t;
17744         }
17745       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17746         {
17747           eid_set = 1;
17748           eid_type = 2;
17749         }
17750       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17751         {
17752           eid_set = 1;
17753           eid_type = 3;
17754         }
17755       else if (unformat (i, "vni %d", &t))
17756         {
17757           vni = t;
17758         }
17759       else if (unformat (i, "local"))
17760         {
17761           filter = 1;
17762         }
17763       else if (unformat (i, "remote"))
17764         {
17765           filter = 2;
17766         }
17767       else
17768         {
17769           errmsg ("parse error '%U'", format_unformat_error, i);
17770           return -99;
17771         }
17772     }
17773
17774   if (!vam->json_output)
17775     {
17776       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17777              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17778     }
17779
17780   M (ONE_EID_TABLE_DUMP, mp);
17781
17782   mp->filter = filter;
17783   if (eid_set)
17784     {
17785       mp->eid_set = 1;
17786       mp->vni = htonl (vni);
17787       mp->eid_type = eid_type;
17788       switch (eid_type)
17789         {
17790         case 0:
17791           mp->prefix_length = prefix_length;
17792           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17793           break;
17794         case 1:
17795           mp->prefix_length = prefix_length;
17796           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17797           break;
17798         case 2:
17799           clib_memcpy (mp->eid, mac, sizeof (mac));
17800           break;
17801         case 3:
17802           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17803           break;
17804         default:
17805           errmsg ("unknown EID type %d!", eid_type);
17806           return -99;
17807         }
17808     }
17809
17810   /* send it... */
17811   S (mp);
17812
17813   /* Use a control ping for synchronization */
17814   MPING (CONTROL_PING, mp_ping);
17815   S (mp_ping);
17816
17817   /* Wait for a reply... */
17818   W (ret);
17819   return ret;
17820 }
17821
17822 #define api_lisp_eid_table_dump api_one_eid_table_dump
17823
17824 static int
17825 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17826 {
17827   unformat_input_t *i = vam->input;
17828   vl_api_gpe_fwd_entries_get_t *mp;
17829   u8 vni_set = 0;
17830   u32 vni = ~0;
17831   int ret;
17832
17833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17834     {
17835       if (unformat (i, "vni %d", &vni))
17836         {
17837           vni_set = 1;
17838         }
17839       else
17840         {
17841           errmsg ("parse error '%U'", format_unformat_error, i);
17842           return -99;
17843         }
17844     }
17845
17846   if (!vni_set)
17847     {
17848       errmsg ("vni not set!");
17849       return -99;
17850     }
17851
17852   if (!vam->json_output)
17853     {
17854       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17855              "leid", "reid");
17856     }
17857
17858   M (GPE_FWD_ENTRIES_GET, mp);
17859   mp->vni = clib_host_to_net_u32 (vni);
17860
17861   /* send it... */
17862   S (mp);
17863
17864   /* Wait for a reply... */
17865   W (ret);
17866   return ret;
17867 }
17868
17869 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17870 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17871 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17872 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17873 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17874 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17875 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17876 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17877
17878 static int
17879 api_one_adjacencies_get (vat_main_t * vam)
17880 {
17881   unformat_input_t *i = vam->input;
17882   vl_api_one_adjacencies_get_t *mp;
17883   u8 vni_set = 0;
17884   u32 vni = ~0;
17885   int ret;
17886
17887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17888     {
17889       if (unformat (i, "vni %d", &vni))
17890         {
17891           vni_set = 1;
17892         }
17893       else
17894         {
17895           errmsg ("parse error '%U'", format_unformat_error, i);
17896           return -99;
17897         }
17898     }
17899
17900   if (!vni_set)
17901     {
17902       errmsg ("vni not set!");
17903       return -99;
17904     }
17905
17906   if (!vam->json_output)
17907     {
17908       print (vam->ofp, "%s %40s", "leid", "reid");
17909     }
17910
17911   M (ONE_ADJACENCIES_GET, mp);
17912   mp->vni = clib_host_to_net_u32 (vni);
17913
17914   /* send it... */
17915   S (mp);
17916
17917   /* Wait for a reply... */
17918   W (ret);
17919   return ret;
17920 }
17921
17922 #define api_lisp_adjacencies_get api_one_adjacencies_get
17923
17924 static int
17925 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17926 {
17927   unformat_input_t *i = vam->input;
17928   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17929   int ret;
17930   u8 ip_family_set = 0, is_ip4 = 1;
17931
17932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17933     {
17934       if (unformat (i, "ip4"))
17935         {
17936           ip_family_set = 1;
17937           is_ip4 = 1;
17938         }
17939       else if (unformat (i, "ip6"))
17940         {
17941           ip_family_set = 1;
17942           is_ip4 = 0;
17943         }
17944       else
17945         {
17946           errmsg ("parse error '%U'", format_unformat_error, i);
17947           return -99;
17948         }
17949     }
17950
17951   if (!ip_family_set)
17952     {
17953       errmsg ("ip family not set!");
17954       return -99;
17955     }
17956
17957   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17958   mp->is_ip4 = is_ip4;
17959
17960   /* send it... */
17961   S (mp);
17962
17963   /* Wait for a reply... */
17964   W (ret);
17965   return ret;
17966 }
17967
17968 static int
17969 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17970 {
17971   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17972   int ret;
17973
17974   if (!vam->json_output)
17975     {
17976       print (vam->ofp, "VNIs");
17977     }
17978
17979   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17980
17981   /* send it... */
17982   S (mp);
17983
17984   /* Wait for a reply... */
17985   W (ret);
17986   return ret;
17987 }
17988
17989 static int
17990 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17991 {
17992   unformat_input_t *i = vam->input;
17993   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17994   int ret = 0;
17995   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17996   struct in_addr ip4;
17997   struct in6_addr ip6;
17998   u32 table_id = 0, nh_sw_if_index = ~0;
17999
18000   clib_memset (&ip4, 0, sizeof (ip4));
18001   clib_memset (&ip6, 0, sizeof (ip6));
18002
18003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18004     {
18005       if (unformat (i, "del"))
18006         is_add = 0;
18007       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18008                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18009         {
18010           ip_set = 1;
18011           is_ip4 = 1;
18012         }
18013       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18014                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18015         {
18016           ip_set = 1;
18017           is_ip4 = 0;
18018         }
18019       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18020         {
18021           ip_set = 1;
18022           is_ip4 = 1;
18023           nh_sw_if_index = ~0;
18024         }
18025       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18026         {
18027           ip_set = 1;
18028           is_ip4 = 0;
18029           nh_sw_if_index = ~0;
18030         }
18031       else if (unformat (i, "table %d", &table_id))
18032         ;
18033       else
18034         {
18035           errmsg ("parse error '%U'", format_unformat_error, i);
18036           return -99;
18037         }
18038     }
18039
18040   if (!ip_set)
18041     {
18042       errmsg ("nh addr not set!");
18043       return -99;
18044     }
18045
18046   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18047   mp->is_add = is_add;
18048   mp->table_id = clib_host_to_net_u32 (table_id);
18049   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18050   mp->is_ip4 = is_ip4;
18051   if (is_ip4)
18052     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18053   else
18054     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18055
18056   /* send it... */
18057   S (mp);
18058
18059   /* Wait for a reply... */
18060   W (ret);
18061   return ret;
18062 }
18063
18064 static int
18065 api_one_map_server_dump (vat_main_t * vam)
18066 {
18067   vl_api_one_map_server_dump_t *mp;
18068   vl_api_control_ping_t *mp_ping;
18069   int ret;
18070
18071   if (!vam->json_output)
18072     {
18073       print (vam->ofp, "%=20s", "Map server");
18074     }
18075
18076   M (ONE_MAP_SERVER_DUMP, mp);
18077   /* send it... */
18078   S (mp);
18079
18080   /* Use a control ping for synchronization */
18081   MPING (CONTROL_PING, mp_ping);
18082   S (mp_ping);
18083
18084   /* Wait for a reply... */
18085   W (ret);
18086   return ret;
18087 }
18088
18089 #define api_lisp_map_server_dump api_one_map_server_dump
18090
18091 static int
18092 api_one_map_resolver_dump (vat_main_t * vam)
18093 {
18094   vl_api_one_map_resolver_dump_t *mp;
18095   vl_api_control_ping_t *mp_ping;
18096   int ret;
18097
18098   if (!vam->json_output)
18099     {
18100       print (vam->ofp, "%=20s", "Map resolver");
18101     }
18102
18103   M (ONE_MAP_RESOLVER_DUMP, mp);
18104   /* send it... */
18105   S (mp);
18106
18107   /* Use a control ping for synchronization */
18108   MPING (CONTROL_PING, mp_ping);
18109   S (mp_ping);
18110
18111   /* Wait for a reply... */
18112   W (ret);
18113   return ret;
18114 }
18115
18116 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18117
18118 static int
18119 api_one_stats_flush (vat_main_t * vam)
18120 {
18121   vl_api_one_stats_flush_t *mp;
18122   int ret = 0;
18123
18124   M (ONE_STATS_FLUSH, mp);
18125   S (mp);
18126   W (ret);
18127   return ret;
18128 }
18129
18130 static int
18131 api_one_stats_dump (vat_main_t * vam)
18132 {
18133   vl_api_one_stats_dump_t *mp;
18134   vl_api_control_ping_t *mp_ping;
18135   int ret;
18136
18137   M (ONE_STATS_DUMP, mp);
18138   /* send it... */
18139   S (mp);
18140
18141   /* Use a control ping for synchronization */
18142   MPING (CONTROL_PING, mp_ping);
18143   S (mp_ping);
18144
18145   /* Wait for a reply... */
18146   W (ret);
18147   return ret;
18148 }
18149
18150 static int
18151 api_show_one_status (vat_main_t * vam)
18152 {
18153   vl_api_show_one_status_t *mp;
18154   int ret;
18155
18156   if (!vam->json_output)
18157     {
18158       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18159     }
18160
18161   M (SHOW_ONE_STATUS, mp);
18162   /* send it... */
18163   S (mp);
18164   /* Wait for a reply... */
18165   W (ret);
18166   return ret;
18167 }
18168
18169 #define api_show_lisp_status api_show_one_status
18170
18171 static int
18172 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18173 {
18174   vl_api_gpe_fwd_entry_path_dump_t *mp;
18175   vl_api_control_ping_t *mp_ping;
18176   unformat_input_t *i = vam->input;
18177   u32 fwd_entry_index = ~0;
18178   int ret;
18179
18180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18181     {
18182       if (unformat (i, "index %d", &fwd_entry_index))
18183         ;
18184       else
18185         break;
18186     }
18187
18188   if (~0 == fwd_entry_index)
18189     {
18190       errmsg ("no index specified!");
18191       return -99;
18192     }
18193
18194   if (!vam->json_output)
18195     {
18196       print (vam->ofp, "first line");
18197     }
18198
18199   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18200
18201   /* send it... */
18202   S (mp);
18203   /* Use a control ping for synchronization */
18204   MPING (CONTROL_PING, mp_ping);
18205   S (mp_ping);
18206
18207   /* Wait for a reply... */
18208   W (ret);
18209   return ret;
18210 }
18211
18212 static int
18213 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18214 {
18215   vl_api_one_get_map_request_itr_rlocs_t *mp;
18216   int ret;
18217
18218   if (!vam->json_output)
18219     {
18220       print (vam->ofp, "%=20s", "itr-rlocs:");
18221     }
18222
18223   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18224   /* send it... */
18225   S (mp);
18226   /* Wait for a reply... */
18227   W (ret);
18228   return ret;
18229 }
18230
18231 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18232
18233 static int
18234 api_af_packet_create (vat_main_t * vam)
18235 {
18236   unformat_input_t *i = vam->input;
18237   vl_api_af_packet_create_t *mp;
18238   u8 *host_if_name = 0;
18239   u8 hw_addr[6];
18240   u8 random_hw_addr = 1;
18241   int ret;
18242
18243   clib_memset (hw_addr, 0, sizeof (hw_addr));
18244
18245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18246     {
18247       if (unformat (i, "name %s", &host_if_name))
18248         vec_add1 (host_if_name, 0);
18249       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18250         random_hw_addr = 0;
18251       else
18252         break;
18253     }
18254
18255   if (!vec_len (host_if_name))
18256     {
18257       errmsg ("host-interface name must be specified");
18258       return -99;
18259     }
18260
18261   if (vec_len (host_if_name) > 64)
18262     {
18263       errmsg ("host-interface name too long");
18264       return -99;
18265     }
18266
18267   M (AF_PACKET_CREATE, mp);
18268
18269   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18270   clib_memcpy (mp->hw_addr, hw_addr, 6);
18271   mp->use_random_hw_addr = random_hw_addr;
18272   vec_free (host_if_name);
18273
18274   S (mp);
18275
18276   /* *INDENT-OFF* */
18277   W2 (ret,
18278       ({
18279         if (ret == 0)
18280           fprintf (vam->ofp ? vam->ofp : stderr,
18281                    " new sw_if_index = %d\n", vam->sw_if_index);
18282       }));
18283   /* *INDENT-ON* */
18284   return ret;
18285 }
18286
18287 static int
18288 api_af_packet_delete (vat_main_t * vam)
18289 {
18290   unformat_input_t *i = vam->input;
18291   vl_api_af_packet_delete_t *mp;
18292   u8 *host_if_name = 0;
18293   int ret;
18294
18295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18296     {
18297       if (unformat (i, "name %s", &host_if_name))
18298         vec_add1 (host_if_name, 0);
18299       else
18300         break;
18301     }
18302
18303   if (!vec_len (host_if_name))
18304     {
18305       errmsg ("host-interface name must be specified");
18306       return -99;
18307     }
18308
18309   if (vec_len (host_if_name) > 64)
18310     {
18311       errmsg ("host-interface name too long");
18312       return -99;
18313     }
18314
18315   M (AF_PACKET_DELETE, mp);
18316
18317   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18318   vec_free (host_if_name);
18319
18320   S (mp);
18321   W (ret);
18322   return ret;
18323 }
18324
18325 static void vl_api_af_packet_details_t_handler
18326   (vl_api_af_packet_details_t * mp)
18327 {
18328   vat_main_t *vam = &vat_main;
18329
18330   print (vam->ofp, "%-16s %d",
18331          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18332 }
18333
18334 static void vl_api_af_packet_details_t_handler_json
18335   (vl_api_af_packet_details_t * mp)
18336 {
18337   vat_main_t *vam = &vat_main;
18338   vat_json_node_t *node = NULL;
18339
18340   if (VAT_JSON_ARRAY != vam->json_tree.type)
18341     {
18342       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18343       vat_json_init_array (&vam->json_tree);
18344     }
18345   node = vat_json_array_add (&vam->json_tree);
18346
18347   vat_json_init_object (node);
18348   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18349   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18350 }
18351
18352 static int
18353 api_af_packet_dump (vat_main_t * vam)
18354 {
18355   vl_api_af_packet_dump_t *mp;
18356   vl_api_control_ping_t *mp_ping;
18357   int ret;
18358
18359   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18360   /* Get list of tap interfaces */
18361   M (AF_PACKET_DUMP, mp);
18362   S (mp);
18363
18364   /* Use a control ping for synchronization */
18365   MPING (CONTROL_PING, mp_ping);
18366   S (mp_ping);
18367
18368   W (ret);
18369   return ret;
18370 }
18371
18372 static int
18373 api_policer_add_del (vat_main_t * vam)
18374 {
18375   unformat_input_t *i = vam->input;
18376   vl_api_policer_add_del_t *mp;
18377   u8 is_add = 1;
18378   u8 *name = 0;
18379   u32 cir = 0;
18380   u32 eir = 0;
18381   u64 cb = 0;
18382   u64 eb = 0;
18383   u8 rate_type = 0;
18384   u8 round_type = 0;
18385   u8 type = 0;
18386   u8 color_aware = 0;
18387   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18388   int ret;
18389
18390   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18391   conform_action.dscp = 0;
18392   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18393   exceed_action.dscp = 0;
18394   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18395   violate_action.dscp = 0;
18396
18397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18398     {
18399       if (unformat (i, "del"))
18400         is_add = 0;
18401       else if (unformat (i, "name %s", &name))
18402         vec_add1 (name, 0);
18403       else if (unformat (i, "cir %u", &cir))
18404         ;
18405       else if (unformat (i, "eir %u", &eir))
18406         ;
18407       else if (unformat (i, "cb %u", &cb))
18408         ;
18409       else if (unformat (i, "eb %u", &eb))
18410         ;
18411       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18412                          &rate_type))
18413         ;
18414       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18415                          &round_type))
18416         ;
18417       else if (unformat (i, "type %U", unformat_policer_type, &type))
18418         ;
18419       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18420                          &conform_action))
18421         ;
18422       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18423                          &exceed_action))
18424         ;
18425       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18426                          &violate_action))
18427         ;
18428       else if (unformat (i, "color-aware"))
18429         color_aware = 1;
18430       else
18431         break;
18432     }
18433
18434   if (!vec_len (name))
18435     {
18436       errmsg ("policer name must be specified");
18437       return -99;
18438     }
18439
18440   if (vec_len (name) > 64)
18441     {
18442       errmsg ("policer name too long");
18443       return -99;
18444     }
18445
18446   M (POLICER_ADD_DEL, mp);
18447
18448   clib_memcpy (mp->name, name, vec_len (name));
18449   vec_free (name);
18450   mp->is_add = is_add;
18451   mp->cir = ntohl (cir);
18452   mp->eir = ntohl (eir);
18453   mp->cb = clib_net_to_host_u64 (cb);
18454   mp->eb = clib_net_to_host_u64 (eb);
18455   mp->rate_type = rate_type;
18456   mp->round_type = round_type;
18457   mp->type = type;
18458   mp->conform_action_type = conform_action.action_type;
18459   mp->conform_dscp = conform_action.dscp;
18460   mp->exceed_action_type = exceed_action.action_type;
18461   mp->exceed_dscp = exceed_action.dscp;
18462   mp->violate_action_type = violate_action.action_type;
18463   mp->violate_dscp = violate_action.dscp;
18464   mp->color_aware = color_aware;
18465
18466   S (mp);
18467   W (ret);
18468   return ret;
18469 }
18470
18471 static int
18472 api_policer_dump (vat_main_t * vam)
18473 {
18474   unformat_input_t *i = vam->input;
18475   vl_api_policer_dump_t *mp;
18476   vl_api_control_ping_t *mp_ping;
18477   u8 *match_name = 0;
18478   u8 match_name_valid = 0;
18479   int ret;
18480
18481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18482     {
18483       if (unformat (i, "name %s", &match_name))
18484         {
18485           vec_add1 (match_name, 0);
18486           match_name_valid = 1;
18487         }
18488       else
18489         break;
18490     }
18491
18492   M (POLICER_DUMP, mp);
18493   mp->match_name_valid = match_name_valid;
18494   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18495   vec_free (match_name);
18496   /* send it... */
18497   S (mp);
18498
18499   /* Use a control ping for synchronization */
18500   MPING (CONTROL_PING, mp_ping);
18501   S (mp_ping);
18502
18503   /* Wait for a reply... */
18504   W (ret);
18505   return ret;
18506 }
18507
18508 static int
18509 api_policer_classify_set_interface (vat_main_t * vam)
18510 {
18511   unformat_input_t *i = vam->input;
18512   vl_api_policer_classify_set_interface_t *mp;
18513   u32 sw_if_index;
18514   int sw_if_index_set;
18515   u32 ip4_table_index = ~0;
18516   u32 ip6_table_index = ~0;
18517   u32 l2_table_index = ~0;
18518   u8 is_add = 1;
18519   int ret;
18520
18521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18522     {
18523       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18524         sw_if_index_set = 1;
18525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18526         sw_if_index_set = 1;
18527       else if (unformat (i, "del"))
18528         is_add = 0;
18529       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18530         ;
18531       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18532         ;
18533       else if (unformat (i, "l2-table %d", &l2_table_index))
18534         ;
18535       else
18536         {
18537           clib_warning ("parse error '%U'", format_unformat_error, i);
18538           return -99;
18539         }
18540     }
18541
18542   if (sw_if_index_set == 0)
18543     {
18544       errmsg ("missing interface name or sw_if_index");
18545       return -99;
18546     }
18547
18548   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18549
18550   mp->sw_if_index = ntohl (sw_if_index);
18551   mp->ip4_table_index = ntohl (ip4_table_index);
18552   mp->ip6_table_index = ntohl (ip6_table_index);
18553   mp->l2_table_index = ntohl (l2_table_index);
18554   mp->is_add = is_add;
18555
18556   S (mp);
18557   W (ret);
18558   return ret;
18559 }
18560
18561 static int
18562 api_policer_classify_dump (vat_main_t * vam)
18563 {
18564   unformat_input_t *i = vam->input;
18565   vl_api_policer_classify_dump_t *mp;
18566   vl_api_control_ping_t *mp_ping;
18567   u8 type = POLICER_CLASSIFY_N_TABLES;
18568   int ret;
18569
18570   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18571     ;
18572   else
18573     {
18574       errmsg ("classify table type must be specified");
18575       return -99;
18576     }
18577
18578   if (!vam->json_output)
18579     {
18580       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18581     }
18582
18583   M (POLICER_CLASSIFY_DUMP, mp);
18584   mp->type = type;
18585   /* send it... */
18586   S (mp);
18587
18588   /* Use a control ping for synchronization */
18589   MPING (CONTROL_PING, mp_ping);
18590   S (mp_ping);
18591
18592   /* Wait for a reply... */
18593   W (ret);
18594   return ret;
18595 }
18596
18597 static int
18598 api_netmap_create (vat_main_t * vam)
18599 {
18600   unformat_input_t *i = vam->input;
18601   vl_api_netmap_create_t *mp;
18602   u8 *if_name = 0;
18603   u8 hw_addr[6];
18604   u8 random_hw_addr = 1;
18605   u8 is_pipe = 0;
18606   u8 is_master = 0;
18607   int ret;
18608
18609   clib_memset (hw_addr, 0, sizeof (hw_addr));
18610
18611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18612     {
18613       if (unformat (i, "name %s", &if_name))
18614         vec_add1 (if_name, 0);
18615       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18616         random_hw_addr = 0;
18617       else if (unformat (i, "pipe"))
18618         is_pipe = 1;
18619       else if (unformat (i, "master"))
18620         is_master = 1;
18621       else if (unformat (i, "slave"))
18622         is_master = 0;
18623       else
18624         break;
18625     }
18626
18627   if (!vec_len (if_name))
18628     {
18629       errmsg ("interface name must be specified");
18630       return -99;
18631     }
18632
18633   if (vec_len (if_name) > 64)
18634     {
18635       errmsg ("interface name too long");
18636       return -99;
18637     }
18638
18639   M (NETMAP_CREATE, mp);
18640
18641   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18642   clib_memcpy (mp->hw_addr, hw_addr, 6);
18643   mp->use_random_hw_addr = random_hw_addr;
18644   mp->is_pipe = is_pipe;
18645   mp->is_master = is_master;
18646   vec_free (if_name);
18647
18648   S (mp);
18649   W (ret);
18650   return ret;
18651 }
18652
18653 static int
18654 api_netmap_delete (vat_main_t * vam)
18655 {
18656   unformat_input_t *i = vam->input;
18657   vl_api_netmap_delete_t *mp;
18658   u8 *if_name = 0;
18659   int ret;
18660
18661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18662     {
18663       if (unformat (i, "name %s", &if_name))
18664         vec_add1 (if_name, 0);
18665       else
18666         break;
18667     }
18668
18669   if (!vec_len (if_name))
18670     {
18671       errmsg ("interface name must be specified");
18672       return -99;
18673     }
18674
18675   if (vec_len (if_name) > 64)
18676     {
18677       errmsg ("interface name too long");
18678       return -99;
18679     }
18680
18681   M (NETMAP_DELETE, mp);
18682
18683   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18684   vec_free (if_name);
18685
18686   S (mp);
18687   W (ret);
18688   return ret;
18689 }
18690
18691 static u8 *
18692 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18693 {
18694   vl_api_fib_path_nh_proto_t proto =
18695     va_arg (*args, vl_api_fib_path_nh_proto_t);
18696
18697   switch (proto)
18698     {
18699     case FIB_API_PATH_NH_PROTO_IP4:
18700       s = format (s, "ip4");
18701       break;
18702     case FIB_API_PATH_NH_PROTO_IP6:
18703       s = format (s, "ip6");
18704       break;
18705     case FIB_API_PATH_NH_PROTO_MPLS:
18706       s = format (s, "mpls");
18707       break;
18708     case FIB_API_PATH_NH_PROTO_BIER:
18709       s = format (s, "bier");
18710       break;
18711     case FIB_API_PATH_NH_PROTO_ETHERNET:
18712       s = format (s, "ethernet");
18713       break;
18714     }
18715
18716   return (s);
18717 }
18718
18719 static u8 *
18720 format_vl_api_ip_address_union (u8 * s, va_list * args)
18721 {
18722   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18723   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18724
18725   switch (af)
18726     {
18727     case ADDRESS_IP4:
18728       s = format (s, "%U", format_ip4_address, u->ip4);
18729       break;
18730     case ADDRESS_IP6:
18731       s = format (s, "%U", format_ip6_address, u->ip6);
18732       break;
18733     }
18734   return (s);
18735 }
18736
18737 static u8 *
18738 format_vl_api_fib_path_type (u8 * s, va_list * args)
18739 {
18740   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18741
18742   switch (t)
18743     {
18744     case FIB_API_PATH_TYPE_NORMAL:
18745       s = format (s, "normal");
18746       break;
18747     case FIB_API_PATH_TYPE_LOCAL:
18748       s = format (s, "local");
18749       break;
18750     case FIB_API_PATH_TYPE_DROP:
18751       s = format (s, "drop");
18752       break;
18753     case FIB_API_PATH_TYPE_UDP_ENCAP:
18754       s = format (s, "udp-encap");
18755       break;
18756     case FIB_API_PATH_TYPE_BIER_IMP:
18757       s = format (s, "bier-imp");
18758       break;
18759     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18760       s = format (s, "unreach");
18761       break;
18762     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18763       s = format (s, "prohibit");
18764       break;
18765     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18766       s = format (s, "src-lookup");
18767       break;
18768     case FIB_API_PATH_TYPE_DVR:
18769       s = format (s, "dvr");
18770       break;
18771     case FIB_API_PATH_TYPE_INTERFACE_RX:
18772       s = format (s, "interface-rx");
18773       break;
18774     case FIB_API_PATH_TYPE_CLASSIFY:
18775       s = format (s, "classify");
18776       break;
18777     }
18778
18779   return (s);
18780 }
18781
18782 static void
18783 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18784 {
18785   print (vam->ofp,
18786          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18787          ntohl (fp->weight), ntohl (fp->sw_if_index),
18788          format_vl_api_fib_path_type, fp->type,
18789          format_fib_api_path_nh_proto, fp->proto,
18790          format_vl_api_ip_address_union, &fp->nh.address);
18791 }
18792
18793 static void
18794 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18795                                  vl_api_fib_path_t * fp)
18796 {
18797   struct in_addr ip4;
18798   struct in6_addr ip6;
18799
18800   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18801   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18802   vat_json_object_add_uint (node, "type", fp->type);
18803   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18804   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18805     {
18806       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18807       vat_json_object_add_ip4 (node, "next_hop", ip4);
18808     }
18809   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18810     {
18811       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18812       vat_json_object_add_ip6 (node, "next_hop", ip6);
18813     }
18814 }
18815
18816 static void
18817 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18818 {
18819   vat_main_t *vam = &vat_main;
18820   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18821   vl_api_fib_path_t *fp;
18822   i32 i;
18823
18824   print (vam->ofp, "sw_if_index %d via:",
18825          ntohl (mp->mt_tunnel.mt_sw_if_index));
18826   fp = mp->mt_tunnel.mt_paths;
18827   for (i = 0; i < count; i++)
18828     {
18829       vl_api_fib_path_print (vam, fp);
18830       fp++;
18831     }
18832
18833   print (vam->ofp, "");
18834 }
18835
18836 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18837 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18838
18839 static void
18840 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18841 {
18842   vat_main_t *vam = &vat_main;
18843   vat_json_node_t *node = NULL;
18844   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18845   vl_api_fib_path_t *fp;
18846   i32 i;
18847
18848   if (VAT_JSON_ARRAY != vam->json_tree.type)
18849     {
18850       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18851       vat_json_init_array (&vam->json_tree);
18852     }
18853   node = vat_json_array_add (&vam->json_tree);
18854
18855   vat_json_init_object (node);
18856   vat_json_object_add_uint (node, "sw_if_index",
18857                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18858
18859   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18860
18861   fp = mp->mt_tunnel.mt_paths;
18862   for (i = 0; i < count; i++)
18863     {
18864       vl_api_mpls_fib_path_json_print (node, fp);
18865       fp++;
18866     }
18867 }
18868
18869 static int
18870 api_mpls_tunnel_dump (vat_main_t * vam)
18871 {
18872   vl_api_mpls_tunnel_dump_t *mp;
18873   vl_api_control_ping_t *mp_ping;
18874   int ret;
18875
18876   M (MPLS_TUNNEL_DUMP, mp);
18877
18878   S (mp);
18879
18880   /* Use a control ping for synchronization */
18881   MPING (CONTROL_PING, mp_ping);
18882   S (mp_ping);
18883
18884   W (ret);
18885   return ret;
18886 }
18887
18888 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18889 #define vl_api_mpls_table_details_t_print vl_noop_handler
18890
18891
18892 static void
18893 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18894 {
18895   vat_main_t *vam = &vat_main;
18896
18897   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18898 }
18899
18900 static void vl_api_mpls_table_details_t_handler_json
18901   (vl_api_mpls_table_details_t * mp)
18902 {
18903   vat_main_t *vam = &vat_main;
18904   vat_json_node_t *node = NULL;
18905
18906   if (VAT_JSON_ARRAY != vam->json_tree.type)
18907     {
18908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18909       vat_json_init_array (&vam->json_tree);
18910     }
18911   node = vat_json_array_add (&vam->json_tree);
18912
18913   vat_json_init_object (node);
18914   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18915 }
18916
18917 static int
18918 api_mpls_table_dump (vat_main_t * vam)
18919 {
18920   vl_api_mpls_table_dump_t *mp;
18921   vl_api_control_ping_t *mp_ping;
18922   int ret;
18923
18924   M (MPLS_TABLE_DUMP, mp);
18925   S (mp);
18926
18927   /* Use a control ping for synchronization */
18928   MPING (CONTROL_PING, mp_ping);
18929   S (mp_ping);
18930
18931   W (ret);
18932   return ret;
18933 }
18934
18935 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18936 #define vl_api_mpls_route_details_t_print vl_noop_handler
18937
18938 static void
18939 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18940 {
18941   vat_main_t *vam = &vat_main;
18942   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18943   vl_api_fib_path_t *fp;
18944   int i;
18945
18946   print (vam->ofp,
18947          "table-id %d, label %u, ess_bit %u",
18948          ntohl (mp->mr_route.mr_table_id),
18949          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18950   fp = mp->mr_route.mr_paths;
18951   for (i = 0; i < count; i++)
18952     {
18953       vl_api_fib_path_print (vam, fp);
18954       fp++;
18955     }
18956 }
18957
18958 static void vl_api_mpls_route_details_t_handler_json
18959   (vl_api_mpls_route_details_t * mp)
18960 {
18961   vat_main_t *vam = &vat_main;
18962   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18963   vat_json_node_t *node = NULL;
18964   vl_api_fib_path_t *fp;
18965   int i;
18966
18967   if (VAT_JSON_ARRAY != vam->json_tree.type)
18968     {
18969       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18970       vat_json_init_array (&vam->json_tree);
18971     }
18972   node = vat_json_array_add (&vam->json_tree);
18973
18974   vat_json_init_object (node);
18975   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18976   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18977   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18978   vat_json_object_add_uint (node, "path_count", count);
18979   fp = mp->mr_route.mr_paths;
18980   for (i = 0; i < count; i++)
18981     {
18982       vl_api_mpls_fib_path_json_print (node, fp);
18983       fp++;
18984     }
18985 }
18986
18987 static int
18988 api_mpls_route_dump (vat_main_t * vam)
18989 {
18990   unformat_input_t *input = vam->input;
18991   vl_api_mpls_route_dump_t *mp;
18992   vl_api_control_ping_t *mp_ping;
18993   u32 table_id;
18994   int ret;
18995
18996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18997     {
18998       if (unformat (input, "table_id %d", &table_id))
18999         ;
19000       else
19001         break;
19002     }
19003   if (table_id == ~0)
19004     {
19005       errmsg ("missing table id");
19006       return -99;
19007     }
19008
19009   M (MPLS_ROUTE_DUMP, mp);
19010
19011   mp->table.mt_table_id = ntohl (table_id);
19012   S (mp);
19013
19014   /* Use a control ping for synchronization */
19015   MPING (CONTROL_PING, mp_ping);
19016   S (mp_ping);
19017
19018   W (ret);
19019   return ret;
19020 }
19021
19022 #define vl_api_ip_table_details_t_endian vl_noop_handler
19023 #define vl_api_ip_table_details_t_print vl_noop_handler
19024
19025 static void
19026 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
19027 {
19028   vat_main_t *vam = &vat_main;
19029
19030   print (vam->ofp,
19031          "%s; table-id %d, prefix %U/%d",
19032          mp->table.name, ntohl (mp->table.table_id));
19033 }
19034
19035
19036 static void vl_api_ip_table_details_t_handler_json
19037   (vl_api_ip_table_details_t * mp)
19038 {
19039   vat_main_t *vam = &vat_main;
19040   vat_json_node_t *node = NULL;
19041
19042   if (VAT_JSON_ARRAY != vam->json_tree.type)
19043     {
19044       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19045       vat_json_init_array (&vam->json_tree);
19046     }
19047   node = vat_json_array_add (&vam->json_tree);
19048
19049   vat_json_init_object (node);
19050   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
19051 }
19052
19053 static int
19054 api_ip_table_dump (vat_main_t * vam)
19055 {
19056   vl_api_ip_table_dump_t *mp;
19057   vl_api_control_ping_t *mp_ping;
19058   int ret;
19059
19060   M (IP_TABLE_DUMP, mp);
19061   S (mp);
19062
19063   /* Use a control ping for synchronization */
19064   MPING (CONTROL_PING, mp_ping);
19065   S (mp_ping);
19066
19067   W (ret);
19068   return ret;
19069 }
19070
19071 static int
19072 api_ip_mtable_dump (vat_main_t * vam)
19073 {
19074   vl_api_ip_mtable_dump_t *mp;
19075   vl_api_control_ping_t *mp_ping;
19076   int ret;
19077
19078   M (IP_MTABLE_DUMP, mp);
19079   S (mp);
19080
19081   /* Use a control ping for synchronization */
19082   MPING (CONTROL_PING, mp_ping);
19083   S (mp_ping);
19084
19085   W (ret);
19086   return ret;
19087 }
19088
19089 static int
19090 api_ip_mroute_dump (vat_main_t * vam)
19091 {
19092   unformat_input_t *input = vam->input;
19093   vl_api_control_ping_t *mp_ping;
19094   vl_api_ip_mroute_dump_t *mp;
19095   int ret, is_ip6;
19096   u32 table_id;
19097
19098   is_ip6 = 0;
19099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19100     {
19101       if (unformat (input, "table_id %d", &table_id))
19102         ;
19103       else if (unformat (input, "ip6"))
19104         is_ip6 = 1;
19105       else if (unformat (input, "ip4"))
19106         is_ip6 = 0;
19107       else
19108         break;
19109     }
19110   if (table_id == ~0)
19111     {
19112       errmsg ("missing table id");
19113       return -99;
19114     }
19115
19116   M (IP_MROUTE_DUMP, mp);
19117   mp->table.table_id = table_id;
19118   mp->table.is_ip6 = is_ip6;
19119   S (mp);
19120
19121   /* Use a control ping for synchronization */
19122   MPING (CONTROL_PING, mp_ping);
19123   S (mp_ping);
19124
19125   W (ret);
19126   return ret;
19127 }
19128
19129 static void vl_api_ip_neighbor_details_t_handler
19130   (vl_api_ip_neighbor_details_t * mp)
19131 {
19132   vat_main_t *vam = &vat_main;
19133
19134   print (vam->ofp, "%c %U %U",
19135          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19136          format_vl_api_mac_address, &mp->neighbor.mac_address,
19137          format_vl_api_address, &mp->neighbor.ip_address);
19138 }
19139
19140 static void vl_api_ip_neighbor_details_t_handler_json
19141   (vl_api_ip_neighbor_details_t * mp)
19142 {
19143
19144   vat_main_t *vam = &vat_main;
19145   vat_json_node_t *node;
19146
19147   if (VAT_JSON_ARRAY != vam->json_tree.type)
19148     {
19149       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19150       vat_json_init_array (&vam->json_tree);
19151     }
19152   node = vat_json_array_add (&vam->json_tree);
19153
19154   vat_json_init_object (node);
19155   vat_json_object_add_string_copy
19156     (node, "flag",
19157      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19158       (u8 *) "static" : (u8 *) "dynamic"));
19159
19160   vat_json_object_add_string_copy (node, "link_layer",
19161                                    format (0, "%U", format_vl_api_mac_address,
19162                                            &mp->neighbor.mac_address));
19163   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19164 }
19165
19166 static int
19167 api_ip_neighbor_dump (vat_main_t * vam)
19168 {
19169   unformat_input_t *i = vam->input;
19170   vl_api_ip_neighbor_dump_t *mp;
19171   vl_api_control_ping_t *mp_ping;
19172   u8 is_ipv6 = 0;
19173   u32 sw_if_index = ~0;
19174   int ret;
19175
19176   /* Parse args required to build the message */
19177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19178     {
19179       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19180         ;
19181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19182         ;
19183       else if (unformat (i, "ip6"))
19184         is_ipv6 = 1;
19185       else
19186         break;
19187     }
19188
19189   if (sw_if_index == ~0)
19190     {
19191       errmsg ("missing interface name or sw_if_index");
19192       return -99;
19193     }
19194
19195   M (IP_NEIGHBOR_DUMP, mp);
19196   mp->is_ipv6 = (u8) is_ipv6;
19197   mp->sw_if_index = ntohl (sw_if_index);
19198   S (mp);
19199
19200   /* Use a control ping for synchronization */
19201   MPING (CONTROL_PING, mp_ping);
19202   S (mp_ping);
19203
19204   W (ret);
19205   return ret;
19206 }
19207
19208 #define vl_api_ip_route_details_t_endian vl_noop_handler
19209 #define vl_api_ip_route_details_t_print vl_noop_handler
19210
19211 static void
19212 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19213 {
19214   vat_main_t *vam = &vat_main;
19215   u8 count = mp->route.n_paths;
19216   vl_api_fib_path_t *fp;
19217   int i;
19218
19219   print (vam->ofp,
19220          "table-id %d, prefix %U/%d",
19221          ntohl (mp->route.table_id),
19222          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19223   for (i = 0; i < count; i++)
19224     {
19225       fp = &mp->route.paths[i];
19226
19227       vl_api_fib_path_print (vam, fp);
19228       fp++;
19229     }
19230 }
19231
19232 static void vl_api_ip_route_details_t_handler_json
19233   (vl_api_ip_route_details_t * mp)
19234 {
19235   vat_main_t *vam = &vat_main;
19236   u8 count = mp->route.n_paths;
19237   vat_json_node_t *node = NULL;
19238   struct in_addr ip4;
19239   struct in6_addr ip6;
19240   vl_api_fib_path_t *fp;
19241   int i;
19242
19243   if (VAT_JSON_ARRAY != vam->json_tree.type)
19244     {
19245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19246       vat_json_init_array (&vam->json_tree);
19247     }
19248   node = vat_json_array_add (&vam->json_tree);
19249
19250   vat_json_init_object (node);
19251   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19252   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19253     {
19254       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19255       vat_json_object_add_ip6 (node, "prefix", ip6);
19256     }
19257   else
19258     {
19259       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19260       vat_json_object_add_ip4 (node, "prefix", ip4);
19261     }
19262   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19263   vat_json_object_add_uint (node, "path_count", count);
19264   for (i = 0; i < count; i++)
19265     {
19266       fp = &mp->route.paths[i];
19267       vl_api_mpls_fib_path_json_print (node, fp);
19268     }
19269 }
19270
19271 static int
19272 api_ip_route_dump (vat_main_t * vam)
19273 {
19274   unformat_input_t *input = vam->input;
19275   vl_api_ip_route_dump_t *mp;
19276   vl_api_control_ping_t *mp_ping;
19277   u32 table_id;
19278   u8 is_ip6;
19279   int ret;
19280
19281   is_ip6 = 0;
19282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19283     {
19284       if (unformat (input, "table_id %d", &table_id))
19285         ;
19286       else if (unformat (input, "ip6"))
19287         is_ip6 = 1;
19288       else if (unformat (input, "ip4"))
19289         is_ip6 = 0;
19290       else
19291         break;
19292     }
19293   if (table_id == ~0)
19294     {
19295       errmsg ("missing table id");
19296       return -99;
19297     }
19298
19299   M (IP_ROUTE_DUMP, mp);
19300
19301   mp->table.table_id = table_id;
19302   mp->table.is_ip6 = is_ip6;
19303
19304   S (mp);
19305
19306   /* Use a control ping for synchronization */
19307   MPING (CONTROL_PING, mp_ping);
19308   S (mp_ping);
19309
19310   W (ret);
19311   return ret;
19312 }
19313
19314 int
19315 api_classify_table_ids (vat_main_t * vam)
19316 {
19317   vl_api_classify_table_ids_t *mp;
19318   int ret;
19319
19320   /* Construct the API message */
19321   M (CLASSIFY_TABLE_IDS, mp);
19322   mp->context = 0;
19323
19324   S (mp);
19325   W (ret);
19326   return ret;
19327 }
19328
19329 int
19330 api_classify_table_by_interface (vat_main_t * vam)
19331 {
19332   unformat_input_t *input = vam->input;
19333   vl_api_classify_table_by_interface_t *mp;
19334
19335   u32 sw_if_index = ~0;
19336   int ret;
19337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19338     {
19339       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19340         ;
19341       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19342         ;
19343       else
19344         break;
19345     }
19346   if (sw_if_index == ~0)
19347     {
19348       errmsg ("missing interface name or sw_if_index");
19349       return -99;
19350     }
19351
19352   /* Construct the API message */
19353   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19354   mp->context = 0;
19355   mp->sw_if_index = ntohl (sw_if_index);
19356
19357   S (mp);
19358   W (ret);
19359   return ret;
19360 }
19361
19362 int
19363 api_classify_table_info (vat_main_t * vam)
19364 {
19365   unformat_input_t *input = vam->input;
19366   vl_api_classify_table_info_t *mp;
19367
19368   u32 table_id = ~0;
19369   int ret;
19370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19371     {
19372       if (unformat (input, "table_id %d", &table_id))
19373         ;
19374       else
19375         break;
19376     }
19377   if (table_id == ~0)
19378     {
19379       errmsg ("missing table id");
19380       return -99;
19381     }
19382
19383   /* Construct the API message */
19384   M (CLASSIFY_TABLE_INFO, mp);
19385   mp->context = 0;
19386   mp->table_id = ntohl (table_id);
19387
19388   S (mp);
19389   W (ret);
19390   return ret;
19391 }
19392
19393 int
19394 api_classify_session_dump (vat_main_t * vam)
19395 {
19396   unformat_input_t *input = vam->input;
19397   vl_api_classify_session_dump_t *mp;
19398   vl_api_control_ping_t *mp_ping;
19399
19400   u32 table_id = ~0;
19401   int ret;
19402   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19403     {
19404       if (unformat (input, "table_id %d", &table_id))
19405         ;
19406       else
19407         break;
19408     }
19409   if (table_id == ~0)
19410     {
19411       errmsg ("missing table id");
19412       return -99;
19413     }
19414
19415   /* Construct the API message */
19416   M (CLASSIFY_SESSION_DUMP, mp);
19417   mp->context = 0;
19418   mp->table_id = ntohl (table_id);
19419   S (mp);
19420
19421   /* Use a control ping for synchronization */
19422   MPING (CONTROL_PING, mp_ping);
19423   S (mp_ping);
19424
19425   W (ret);
19426   return ret;
19427 }
19428
19429 static void
19430 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19431 {
19432   vat_main_t *vam = &vat_main;
19433
19434   print (vam->ofp, "collector_address %U, collector_port %d, "
19435          "src_address %U, vrf_id %d, path_mtu %u, "
19436          "template_interval %u, udp_checksum %d",
19437          format_ip4_address, mp->collector_address,
19438          ntohs (mp->collector_port),
19439          format_ip4_address, mp->src_address,
19440          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19441          ntohl (mp->template_interval), mp->udp_checksum);
19442
19443   vam->retval = 0;
19444   vam->result_ready = 1;
19445 }
19446
19447 static void
19448   vl_api_ipfix_exporter_details_t_handler_json
19449   (vl_api_ipfix_exporter_details_t * mp)
19450 {
19451   vat_main_t *vam = &vat_main;
19452   vat_json_node_t node;
19453   struct in_addr collector_address;
19454   struct in_addr src_address;
19455
19456   vat_json_init_object (&node);
19457   clib_memcpy (&collector_address, &mp->collector_address,
19458                sizeof (collector_address));
19459   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19460   vat_json_object_add_uint (&node, "collector_port",
19461                             ntohs (mp->collector_port));
19462   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19463   vat_json_object_add_ip4 (&node, "src_address", src_address);
19464   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19465   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19466   vat_json_object_add_uint (&node, "template_interval",
19467                             ntohl (mp->template_interval));
19468   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19469
19470   vat_json_print (vam->ofp, &node);
19471   vat_json_free (&node);
19472   vam->retval = 0;
19473   vam->result_ready = 1;
19474 }
19475
19476 int
19477 api_ipfix_exporter_dump (vat_main_t * vam)
19478 {
19479   vl_api_ipfix_exporter_dump_t *mp;
19480   int ret;
19481
19482   /* Construct the API message */
19483   M (IPFIX_EXPORTER_DUMP, mp);
19484   mp->context = 0;
19485
19486   S (mp);
19487   W (ret);
19488   return ret;
19489 }
19490
19491 static int
19492 api_ipfix_classify_stream_dump (vat_main_t * vam)
19493 {
19494   vl_api_ipfix_classify_stream_dump_t *mp;
19495   int ret;
19496
19497   /* Construct the API message */
19498   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19499   mp->context = 0;
19500
19501   S (mp);
19502   W (ret);
19503   return ret;
19504   /* NOTREACHED */
19505   return 0;
19506 }
19507
19508 static void
19509   vl_api_ipfix_classify_stream_details_t_handler
19510   (vl_api_ipfix_classify_stream_details_t * mp)
19511 {
19512   vat_main_t *vam = &vat_main;
19513   print (vam->ofp, "domain_id %d, src_port %d",
19514          ntohl (mp->domain_id), ntohs (mp->src_port));
19515   vam->retval = 0;
19516   vam->result_ready = 1;
19517 }
19518
19519 static void
19520   vl_api_ipfix_classify_stream_details_t_handler_json
19521   (vl_api_ipfix_classify_stream_details_t * mp)
19522 {
19523   vat_main_t *vam = &vat_main;
19524   vat_json_node_t node;
19525
19526   vat_json_init_object (&node);
19527   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19528   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19529
19530   vat_json_print (vam->ofp, &node);
19531   vat_json_free (&node);
19532   vam->retval = 0;
19533   vam->result_ready = 1;
19534 }
19535
19536 static int
19537 api_ipfix_classify_table_dump (vat_main_t * vam)
19538 {
19539   vl_api_ipfix_classify_table_dump_t *mp;
19540   vl_api_control_ping_t *mp_ping;
19541   int ret;
19542
19543   if (!vam->json_output)
19544     {
19545       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19546              "transport_protocol");
19547     }
19548
19549   /* Construct the API message */
19550   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19551
19552   /* send it... */
19553   S (mp);
19554
19555   /* Use a control ping for synchronization */
19556   MPING (CONTROL_PING, mp_ping);
19557   S (mp_ping);
19558
19559   W (ret);
19560   return ret;
19561 }
19562
19563 static void
19564   vl_api_ipfix_classify_table_details_t_handler
19565   (vl_api_ipfix_classify_table_details_t * mp)
19566 {
19567   vat_main_t *vam = &vat_main;
19568   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19569          mp->transport_protocol);
19570 }
19571
19572 static void
19573   vl_api_ipfix_classify_table_details_t_handler_json
19574   (vl_api_ipfix_classify_table_details_t * mp)
19575 {
19576   vat_json_node_t *node = NULL;
19577   vat_main_t *vam = &vat_main;
19578
19579   if (VAT_JSON_ARRAY != vam->json_tree.type)
19580     {
19581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19582       vat_json_init_array (&vam->json_tree);
19583     }
19584
19585   node = vat_json_array_add (&vam->json_tree);
19586   vat_json_init_object (node);
19587
19588   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19589   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19590   vat_json_object_add_uint (node, "transport_protocol",
19591                             mp->transport_protocol);
19592 }
19593
19594 static int
19595 api_sw_interface_span_enable_disable (vat_main_t * vam)
19596 {
19597   unformat_input_t *i = vam->input;
19598   vl_api_sw_interface_span_enable_disable_t *mp;
19599   u32 src_sw_if_index = ~0;
19600   u32 dst_sw_if_index = ~0;
19601   u8 state = 3;
19602   int ret;
19603   u8 is_l2 = 0;
19604
19605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19606     {
19607       if (unformat
19608           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19609         ;
19610       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19611         ;
19612       else
19613         if (unformat
19614             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19615         ;
19616       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19617         ;
19618       else if (unformat (i, "disable"))
19619         state = 0;
19620       else if (unformat (i, "rx"))
19621         state = 1;
19622       else if (unformat (i, "tx"))
19623         state = 2;
19624       else if (unformat (i, "both"))
19625         state = 3;
19626       else if (unformat (i, "l2"))
19627         is_l2 = 1;
19628       else
19629         break;
19630     }
19631
19632   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19633
19634   mp->sw_if_index_from = htonl (src_sw_if_index);
19635   mp->sw_if_index_to = htonl (dst_sw_if_index);
19636   mp->state = state;
19637   mp->is_l2 = is_l2;
19638
19639   S (mp);
19640   W (ret);
19641   return ret;
19642 }
19643
19644 static void
19645 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19646                                             * mp)
19647 {
19648   vat_main_t *vam = &vat_main;
19649   u8 *sw_if_from_name = 0;
19650   u8 *sw_if_to_name = 0;
19651   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19652   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19653   char *states[] = { "none", "rx", "tx", "both" };
19654   hash_pair_t *p;
19655
19656   /* *INDENT-OFF* */
19657   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19658   ({
19659     if ((u32) p->value[0] == sw_if_index_from)
19660       {
19661         sw_if_from_name = (u8 *)(p->key);
19662         if (sw_if_to_name)
19663           break;
19664       }
19665     if ((u32) p->value[0] == sw_if_index_to)
19666       {
19667         sw_if_to_name = (u8 *)(p->key);
19668         if (sw_if_from_name)
19669           break;
19670       }
19671   }));
19672   /* *INDENT-ON* */
19673   print (vam->ofp, "%20s => %20s (%s) %s",
19674          sw_if_from_name, sw_if_to_name, states[mp->state],
19675          mp->is_l2 ? "l2" : "device");
19676 }
19677
19678 static void
19679   vl_api_sw_interface_span_details_t_handler_json
19680   (vl_api_sw_interface_span_details_t * mp)
19681 {
19682   vat_main_t *vam = &vat_main;
19683   vat_json_node_t *node = NULL;
19684   u8 *sw_if_from_name = 0;
19685   u8 *sw_if_to_name = 0;
19686   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19687   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19688   hash_pair_t *p;
19689
19690   /* *INDENT-OFF* */
19691   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19692   ({
19693     if ((u32) p->value[0] == sw_if_index_from)
19694       {
19695         sw_if_from_name = (u8 *)(p->key);
19696         if (sw_if_to_name)
19697           break;
19698       }
19699     if ((u32) p->value[0] == sw_if_index_to)
19700       {
19701         sw_if_to_name = (u8 *)(p->key);
19702         if (sw_if_from_name)
19703           break;
19704       }
19705   }));
19706   /* *INDENT-ON* */
19707
19708   if (VAT_JSON_ARRAY != vam->json_tree.type)
19709     {
19710       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19711       vat_json_init_array (&vam->json_tree);
19712     }
19713   node = vat_json_array_add (&vam->json_tree);
19714
19715   vat_json_init_object (node);
19716   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19717   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19718   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19719   if (0 != sw_if_to_name)
19720     {
19721       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19722     }
19723   vat_json_object_add_uint (node, "state", mp->state);
19724   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19725 }
19726
19727 static int
19728 api_sw_interface_span_dump (vat_main_t * vam)
19729 {
19730   unformat_input_t *input = vam->input;
19731   vl_api_sw_interface_span_dump_t *mp;
19732   vl_api_control_ping_t *mp_ping;
19733   u8 is_l2 = 0;
19734   int ret;
19735
19736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19737     {
19738       if (unformat (input, "l2"))
19739         is_l2 = 1;
19740       else
19741         break;
19742     }
19743
19744   M (SW_INTERFACE_SPAN_DUMP, mp);
19745   mp->is_l2 = is_l2;
19746   S (mp);
19747
19748   /* Use a control ping for synchronization */
19749   MPING (CONTROL_PING, mp_ping);
19750   S (mp_ping);
19751
19752   W (ret);
19753   return ret;
19754 }
19755
19756 int
19757 api_pg_create_interface (vat_main_t * vam)
19758 {
19759   unformat_input_t *input = vam->input;
19760   vl_api_pg_create_interface_t *mp;
19761
19762   u32 if_id = ~0, gso_size = 0;
19763   u8 gso_enabled = 0;
19764   int ret;
19765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19766     {
19767       if (unformat (input, "if_id %d", &if_id))
19768         ;
19769       else if (unformat (input, "gso-enabled"))
19770         {
19771           gso_enabled = 1;
19772           if (unformat (input, "gso-size %u", &gso_size))
19773             ;
19774           else
19775             {
19776               errmsg ("missing gso-size");
19777               return -99;
19778             }
19779         }
19780       else
19781         break;
19782     }
19783   if (if_id == ~0)
19784     {
19785       errmsg ("missing pg interface index");
19786       return -99;
19787     }
19788
19789   /* Construct the API message */
19790   M (PG_CREATE_INTERFACE, mp);
19791   mp->context = 0;
19792   mp->interface_id = ntohl (if_id);
19793   mp->gso_enabled = gso_enabled;
19794
19795   S (mp);
19796   W (ret);
19797   return ret;
19798 }
19799
19800 int
19801 api_pg_capture (vat_main_t * vam)
19802 {
19803   unformat_input_t *input = vam->input;
19804   vl_api_pg_capture_t *mp;
19805
19806   u32 if_id = ~0;
19807   u8 enable = 1;
19808   u32 count = 1;
19809   u8 pcap_file_set = 0;
19810   u8 *pcap_file = 0;
19811   int ret;
19812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19813     {
19814       if (unformat (input, "if_id %d", &if_id))
19815         ;
19816       else if (unformat (input, "pcap %s", &pcap_file))
19817         pcap_file_set = 1;
19818       else if (unformat (input, "count %d", &count))
19819         ;
19820       else if (unformat (input, "disable"))
19821         enable = 0;
19822       else
19823         break;
19824     }
19825   if (if_id == ~0)
19826     {
19827       errmsg ("missing pg interface index");
19828       return -99;
19829     }
19830   if (pcap_file_set > 0)
19831     {
19832       if (vec_len (pcap_file) > 255)
19833         {
19834           errmsg ("pcap file name is too long");
19835           return -99;
19836         }
19837     }
19838
19839   u32 name_len = vec_len (pcap_file);
19840   /* Construct the API message */
19841   M (PG_CAPTURE, mp);
19842   mp->context = 0;
19843   mp->interface_id = ntohl (if_id);
19844   mp->is_enabled = enable;
19845   mp->count = ntohl (count);
19846   mp->pcap_name_length = ntohl (name_len);
19847   if (pcap_file_set != 0)
19848     {
19849       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19850     }
19851   vec_free (pcap_file);
19852
19853   S (mp);
19854   W (ret);
19855   return ret;
19856 }
19857
19858 int
19859 api_pg_enable_disable (vat_main_t * vam)
19860 {
19861   unformat_input_t *input = vam->input;
19862   vl_api_pg_enable_disable_t *mp;
19863
19864   u8 enable = 1;
19865   u8 stream_name_set = 0;
19866   u8 *stream_name = 0;
19867   int ret;
19868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19869     {
19870       if (unformat (input, "stream %s", &stream_name))
19871         stream_name_set = 1;
19872       else if (unformat (input, "disable"))
19873         enable = 0;
19874       else
19875         break;
19876     }
19877
19878   if (stream_name_set > 0)
19879     {
19880       if (vec_len (stream_name) > 255)
19881         {
19882           errmsg ("stream name too long");
19883           return -99;
19884         }
19885     }
19886
19887   u32 name_len = vec_len (stream_name);
19888   /* Construct the API message */
19889   M (PG_ENABLE_DISABLE, mp);
19890   mp->context = 0;
19891   mp->is_enabled = enable;
19892   if (stream_name_set != 0)
19893     {
19894       mp->stream_name_length = ntohl (name_len);
19895       clib_memcpy (mp->stream_name, stream_name, name_len);
19896     }
19897   vec_free (stream_name);
19898
19899   S (mp);
19900   W (ret);
19901   return ret;
19902 }
19903
19904 int
19905 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19906 {
19907   unformat_input_t *input = vam->input;
19908   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19909
19910   u16 *low_ports = 0;
19911   u16 *high_ports = 0;
19912   u16 this_low;
19913   u16 this_hi;
19914   vl_api_prefix_t prefix;
19915   u32 tmp, tmp2;
19916   u8 prefix_set = 0;
19917   u32 vrf_id = ~0;
19918   u8 is_add = 1;
19919   int ret;
19920
19921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19922     {
19923       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19924         prefix_set = 1;
19925       else if (unformat (input, "vrf %d", &vrf_id))
19926         ;
19927       else if (unformat (input, "del"))
19928         is_add = 0;
19929       else if (unformat (input, "port %d", &tmp))
19930         {
19931           if (tmp == 0 || tmp > 65535)
19932             {
19933               errmsg ("port %d out of range", tmp);
19934               return -99;
19935             }
19936           this_low = tmp;
19937           this_hi = this_low + 1;
19938           vec_add1 (low_ports, this_low);
19939           vec_add1 (high_ports, this_hi);
19940         }
19941       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19942         {
19943           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19944             {
19945               errmsg ("incorrect range parameters");
19946               return -99;
19947             }
19948           this_low = tmp;
19949           /* Note: in debug CLI +1 is added to high before
19950              passing to real fn that does "the work"
19951              (ip_source_and_port_range_check_add_del).
19952              This fn is a wrapper around the binary API fn a
19953              control plane will call, which expects this increment
19954              to have occurred. Hence letting the binary API control
19955              plane fn do the increment for consistency between VAT
19956              and other control planes.
19957            */
19958           this_hi = tmp2;
19959           vec_add1 (low_ports, this_low);
19960           vec_add1 (high_ports, this_hi);
19961         }
19962       else
19963         break;
19964     }
19965
19966   if (prefix_set == 0)
19967     {
19968       errmsg ("<address>/<mask> not specified");
19969       return -99;
19970     }
19971
19972   if (vrf_id == ~0)
19973     {
19974       errmsg ("VRF ID required, not specified");
19975       return -99;
19976     }
19977
19978   if (vrf_id == 0)
19979     {
19980       errmsg
19981         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19982       return -99;
19983     }
19984
19985   if (vec_len (low_ports) == 0)
19986     {
19987       errmsg ("At least one port or port range required");
19988       return -99;
19989     }
19990
19991   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19992
19993   mp->is_add = is_add;
19994
19995   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19996
19997   mp->number_of_ranges = vec_len (low_ports);
19998
19999   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20000   vec_free (low_ports);
20001
20002   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20003   vec_free (high_ports);
20004
20005   mp->vrf_id = ntohl (vrf_id);
20006
20007   S (mp);
20008   W (ret);
20009   return ret;
20010 }
20011
20012 int
20013 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20014 {
20015   unformat_input_t *input = vam->input;
20016   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20017   u32 sw_if_index = ~0;
20018   int vrf_set = 0;
20019   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20020   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20021   u8 is_add = 1;
20022   int ret;
20023
20024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20025     {
20026       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20027         ;
20028       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20029         ;
20030       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20031         vrf_set = 1;
20032       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20033         vrf_set = 1;
20034       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20035         vrf_set = 1;
20036       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20037         vrf_set = 1;
20038       else if (unformat (input, "del"))
20039         is_add = 0;
20040       else
20041         break;
20042     }
20043
20044   if (sw_if_index == ~0)
20045     {
20046       errmsg ("Interface required but not specified");
20047       return -99;
20048     }
20049
20050   if (vrf_set == 0)
20051     {
20052       errmsg ("VRF ID required but not specified");
20053       return -99;
20054     }
20055
20056   if (tcp_out_vrf_id == 0
20057       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20058     {
20059       errmsg
20060         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20061       return -99;
20062     }
20063
20064   /* Construct the API message */
20065   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20066
20067   mp->sw_if_index = ntohl (sw_if_index);
20068   mp->is_add = is_add;
20069   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20070   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20071   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20072   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20073
20074   /* send it... */
20075   S (mp);
20076
20077   /* Wait for a reply... */
20078   W (ret);
20079   return ret;
20080 }
20081
20082 static int
20083 api_set_punt (vat_main_t * vam)
20084 {
20085   unformat_input_t *i = vam->input;
20086   vl_api_address_family_t af;
20087   vl_api_set_punt_t *mp;
20088   u32 protocol = ~0;
20089   u32 port = ~0;
20090   int is_add = 1;
20091   int ret;
20092
20093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20094     {
20095       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20096         ;
20097       else if (unformat (i, "protocol %d", &protocol))
20098         ;
20099       else if (unformat (i, "port %d", &port))
20100         ;
20101       else if (unformat (i, "del"))
20102         is_add = 0;
20103       else
20104         {
20105           clib_warning ("parse error '%U'", format_unformat_error, i);
20106           return -99;
20107         }
20108     }
20109
20110   M (SET_PUNT, mp);
20111
20112   mp->is_add = (u8) is_add;
20113   mp->punt.type = PUNT_API_TYPE_L4;
20114   mp->punt.punt.l4.af = af;
20115   mp->punt.punt.l4.protocol = (u8) protocol;
20116   mp->punt.punt.l4.port = htons ((u16) port);
20117
20118   S (mp);
20119   W (ret);
20120   return ret;
20121 }
20122
20123 static int
20124 api_delete_subif (vat_main_t * vam)
20125 {
20126   unformat_input_t *i = vam->input;
20127   vl_api_delete_subif_t *mp;
20128   u32 sw_if_index = ~0;
20129   int ret;
20130
20131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20132     {
20133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20134         ;
20135       if (unformat (i, "sw_if_index %d", &sw_if_index))
20136         ;
20137       else
20138         break;
20139     }
20140
20141   if (sw_if_index == ~0)
20142     {
20143       errmsg ("missing sw_if_index");
20144       return -99;
20145     }
20146
20147   /* Construct the API message */
20148   M (DELETE_SUBIF, mp);
20149   mp->sw_if_index = ntohl (sw_if_index);
20150
20151   S (mp);
20152   W (ret);
20153   return ret;
20154 }
20155
20156 #define foreach_pbb_vtr_op      \
20157 _("disable",  L2_VTR_DISABLED)  \
20158 _("pop",  L2_VTR_POP_2)         \
20159 _("push",  L2_VTR_PUSH_2)
20160
20161 static int
20162 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20163 {
20164   unformat_input_t *i = vam->input;
20165   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20166   u32 sw_if_index = ~0, vtr_op = ~0;
20167   u16 outer_tag = ~0;
20168   u8 dmac[6], smac[6];
20169   u8 dmac_set = 0, smac_set = 0;
20170   u16 vlanid = 0;
20171   u32 sid = ~0;
20172   u32 tmp;
20173   int ret;
20174
20175   /* Shut up coverity */
20176   clib_memset (dmac, 0, sizeof (dmac));
20177   clib_memset (smac, 0, sizeof (smac));
20178
20179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20180     {
20181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20182         ;
20183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20184         ;
20185       else if (unformat (i, "vtr_op %d", &vtr_op))
20186         ;
20187 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20188       foreach_pbb_vtr_op
20189 #undef _
20190         else if (unformat (i, "translate_pbb_stag"))
20191         {
20192           if (unformat (i, "%d", &tmp))
20193             {
20194               vtr_op = L2_VTR_TRANSLATE_2_1;
20195               outer_tag = tmp;
20196             }
20197           else
20198             {
20199               errmsg
20200                 ("translate_pbb_stag operation requires outer tag definition");
20201               return -99;
20202             }
20203         }
20204       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20205         dmac_set++;
20206       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20207         smac_set++;
20208       else if (unformat (i, "sid %d", &sid))
20209         ;
20210       else if (unformat (i, "vlanid %d", &tmp))
20211         vlanid = tmp;
20212       else
20213         {
20214           clib_warning ("parse error '%U'", format_unformat_error, i);
20215           return -99;
20216         }
20217     }
20218
20219   if ((sw_if_index == ~0) || (vtr_op == ~0))
20220     {
20221       errmsg ("missing sw_if_index or vtr operation");
20222       return -99;
20223     }
20224   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20225       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20226     {
20227       errmsg
20228         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20229       return -99;
20230     }
20231
20232   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20233   mp->sw_if_index = ntohl (sw_if_index);
20234   mp->vtr_op = ntohl (vtr_op);
20235   mp->outer_tag = ntohs (outer_tag);
20236   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20237   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20238   mp->b_vlanid = ntohs (vlanid);
20239   mp->i_sid = ntohl (sid);
20240
20241   S (mp);
20242   W (ret);
20243   return ret;
20244 }
20245
20246 static int
20247 api_flow_classify_set_interface (vat_main_t * vam)
20248 {
20249   unformat_input_t *i = vam->input;
20250   vl_api_flow_classify_set_interface_t *mp;
20251   u32 sw_if_index;
20252   int sw_if_index_set;
20253   u32 ip4_table_index = ~0;
20254   u32 ip6_table_index = ~0;
20255   u8 is_add = 1;
20256   int ret;
20257
20258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20259     {
20260       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20261         sw_if_index_set = 1;
20262       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20263         sw_if_index_set = 1;
20264       else if (unformat (i, "del"))
20265         is_add = 0;
20266       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20267         ;
20268       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20269         ;
20270       else
20271         {
20272           clib_warning ("parse error '%U'", format_unformat_error, i);
20273           return -99;
20274         }
20275     }
20276
20277   if (sw_if_index_set == 0)
20278     {
20279       errmsg ("missing interface name or sw_if_index");
20280       return -99;
20281     }
20282
20283   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20284
20285   mp->sw_if_index = ntohl (sw_if_index);
20286   mp->ip4_table_index = ntohl (ip4_table_index);
20287   mp->ip6_table_index = ntohl (ip6_table_index);
20288   mp->is_add = is_add;
20289
20290   S (mp);
20291   W (ret);
20292   return ret;
20293 }
20294
20295 static int
20296 api_flow_classify_dump (vat_main_t * vam)
20297 {
20298   unformat_input_t *i = vam->input;
20299   vl_api_flow_classify_dump_t *mp;
20300   vl_api_control_ping_t *mp_ping;
20301   u8 type = FLOW_CLASSIFY_N_TABLES;
20302   int ret;
20303
20304   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20305     ;
20306   else
20307     {
20308       errmsg ("classify table type must be specified");
20309       return -99;
20310     }
20311
20312   if (!vam->json_output)
20313     {
20314       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20315     }
20316
20317   M (FLOW_CLASSIFY_DUMP, mp);
20318   mp->type = type;
20319   /* send it... */
20320   S (mp);
20321
20322   /* Use a control ping for synchronization */
20323   MPING (CONTROL_PING, mp_ping);
20324   S (mp_ping);
20325
20326   /* Wait for a reply... */
20327   W (ret);
20328   return ret;
20329 }
20330
20331 static int
20332 api_feature_enable_disable (vat_main_t * vam)
20333 {
20334   unformat_input_t *i = vam->input;
20335   vl_api_feature_enable_disable_t *mp;
20336   u8 *arc_name = 0;
20337   u8 *feature_name = 0;
20338   u32 sw_if_index = ~0;
20339   u8 enable = 1;
20340   int ret;
20341
20342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20343     {
20344       if (unformat (i, "arc_name %s", &arc_name))
20345         ;
20346       else if (unformat (i, "feature_name %s", &feature_name))
20347         ;
20348       else
20349         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20350         ;
20351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20352         ;
20353       else if (unformat (i, "disable"))
20354         enable = 0;
20355       else
20356         break;
20357     }
20358
20359   if (arc_name == 0)
20360     {
20361       errmsg ("missing arc name");
20362       return -99;
20363     }
20364   if (vec_len (arc_name) > 63)
20365     {
20366       errmsg ("arc name too long");
20367     }
20368
20369   if (feature_name == 0)
20370     {
20371       errmsg ("missing feature name");
20372       return -99;
20373     }
20374   if (vec_len (feature_name) > 63)
20375     {
20376       errmsg ("feature name too long");
20377     }
20378
20379   if (sw_if_index == ~0)
20380     {
20381       errmsg ("missing interface name or sw_if_index");
20382       return -99;
20383     }
20384
20385   /* Construct the API message */
20386   M (FEATURE_ENABLE_DISABLE, mp);
20387   mp->sw_if_index = ntohl (sw_if_index);
20388   mp->enable = enable;
20389   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20390   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20391   vec_free (arc_name);
20392   vec_free (feature_name);
20393
20394   S (mp);
20395   W (ret);
20396   return ret;
20397 }
20398
20399 static int
20400 api_sw_interface_tag_add_del (vat_main_t * vam)
20401 {
20402   unformat_input_t *i = vam->input;
20403   vl_api_sw_interface_tag_add_del_t *mp;
20404   u32 sw_if_index = ~0;
20405   u8 *tag = 0;
20406   u8 enable = 1;
20407   int ret;
20408
20409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20410     {
20411       if (unformat (i, "tag %s", &tag))
20412         ;
20413       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20414         ;
20415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20416         ;
20417       else if (unformat (i, "del"))
20418         enable = 0;
20419       else
20420         break;
20421     }
20422
20423   if (sw_if_index == ~0)
20424     {
20425       errmsg ("missing interface name or sw_if_index");
20426       return -99;
20427     }
20428
20429   if (enable && (tag == 0))
20430     {
20431       errmsg ("no tag specified");
20432       return -99;
20433     }
20434
20435   /* Construct the API message */
20436   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20437   mp->sw_if_index = ntohl (sw_if_index);
20438   mp->is_add = enable;
20439   if (enable)
20440     vl_api_to_api_string (strlen ((char *) tag), (char *) tag, &mp->tag);
20441   vec_free (tag);
20442
20443   S (mp);
20444   W (ret);
20445   return ret;
20446 }
20447
20448 static void vl_api_l2_xconnect_details_t_handler
20449   (vl_api_l2_xconnect_details_t * mp)
20450 {
20451   vat_main_t *vam = &vat_main;
20452
20453   print (vam->ofp, "%15d%15d",
20454          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20455 }
20456
20457 static void vl_api_l2_xconnect_details_t_handler_json
20458   (vl_api_l2_xconnect_details_t * mp)
20459 {
20460   vat_main_t *vam = &vat_main;
20461   vat_json_node_t *node = NULL;
20462
20463   if (VAT_JSON_ARRAY != vam->json_tree.type)
20464     {
20465       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20466       vat_json_init_array (&vam->json_tree);
20467     }
20468   node = vat_json_array_add (&vam->json_tree);
20469
20470   vat_json_init_object (node);
20471   vat_json_object_add_uint (node, "rx_sw_if_index",
20472                             ntohl (mp->rx_sw_if_index));
20473   vat_json_object_add_uint (node, "tx_sw_if_index",
20474                             ntohl (mp->tx_sw_if_index));
20475 }
20476
20477 static int
20478 api_l2_xconnect_dump (vat_main_t * vam)
20479 {
20480   vl_api_l2_xconnect_dump_t *mp;
20481   vl_api_control_ping_t *mp_ping;
20482   int ret;
20483
20484   if (!vam->json_output)
20485     {
20486       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20487     }
20488
20489   M (L2_XCONNECT_DUMP, mp);
20490
20491   S (mp);
20492
20493   /* Use a control ping for synchronization */
20494   MPING (CONTROL_PING, mp_ping);
20495   S (mp_ping);
20496
20497   W (ret);
20498   return ret;
20499 }
20500
20501 static int
20502 api_hw_interface_set_mtu (vat_main_t * vam)
20503 {
20504   unformat_input_t *i = vam->input;
20505   vl_api_hw_interface_set_mtu_t *mp;
20506   u32 sw_if_index = ~0;
20507   u32 mtu = 0;
20508   int ret;
20509
20510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20511     {
20512       if (unformat (i, "mtu %d", &mtu))
20513         ;
20514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20515         ;
20516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20517         ;
20518       else
20519         break;
20520     }
20521
20522   if (sw_if_index == ~0)
20523     {
20524       errmsg ("missing interface name or sw_if_index");
20525       return -99;
20526     }
20527
20528   if (mtu == 0)
20529     {
20530       errmsg ("no mtu specified");
20531       return -99;
20532     }
20533
20534   /* Construct the API message */
20535   M (HW_INTERFACE_SET_MTU, mp);
20536   mp->sw_if_index = ntohl (sw_if_index);
20537   mp->mtu = ntohs ((u16) mtu);
20538
20539   S (mp);
20540   W (ret);
20541   return ret;
20542 }
20543
20544 static int
20545 api_p2p_ethernet_add (vat_main_t * vam)
20546 {
20547   unformat_input_t *i = vam->input;
20548   vl_api_p2p_ethernet_add_t *mp;
20549   u32 parent_if_index = ~0;
20550   u32 sub_id = ~0;
20551   u8 remote_mac[6];
20552   u8 mac_set = 0;
20553   int ret;
20554
20555   clib_memset (remote_mac, 0, sizeof (remote_mac));
20556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20557     {
20558       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20559         ;
20560       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20561         ;
20562       else
20563         if (unformat
20564             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20565         mac_set++;
20566       else if (unformat (i, "sub_id %d", &sub_id))
20567         ;
20568       else
20569         {
20570           clib_warning ("parse error '%U'", format_unformat_error, i);
20571           return -99;
20572         }
20573     }
20574
20575   if (parent_if_index == ~0)
20576     {
20577       errmsg ("missing interface name or sw_if_index");
20578       return -99;
20579     }
20580   if (mac_set == 0)
20581     {
20582       errmsg ("missing remote mac address");
20583       return -99;
20584     }
20585   if (sub_id == ~0)
20586     {
20587       errmsg ("missing sub-interface id");
20588       return -99;
20589     }
20590
20591   M (P2P_ETHERNET_ADD, mp);
20592   mp->parent_if_index = ntohl (parent_if_index);
20593   mp->subif_id = ntohl (sub_id);
20594   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20595
20596   S (mp);
20597   W (ret);
20598   return ret;
20599 }
20600
20601 static int
20602 api_p2p_ethernet_del (vat_main_t * vam)
20603 {
20604   unformat_input_t *i = vam->input;
20605   vl_api_p2p_ethernet_del_t *mp;
20606   u32 parent_if_index = ~0;
20607   u8 remote_mac[6];
20608   u8 mac_set = 0;
20609   int ret;
20610
20611   clib_memset (remote_mac, 0, sizeof (remote_mac));
20612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20613     {
20614       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20615         ;
20616       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20617         ;
20618       else
20619         if (unformat
20620             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20621         mac_set++;
20622       else
20623         {
20624           clib_warning ("parse error '%U'", format_unformat_error, i);
20625           return -99;
20626         }
20627     }
20628
20629   if (parent_if_index == ~0)
20630     {
20631       errmsg ("missing interface name or sw_if_index");
20632       return -99;
20633     }
20634   if (mac_set == 0)
20635     {
20636       errmsg ("missing remote mac address");
20637       return -99;
20638     }
20639
20640   M (P2P_ETHERNET_DEL, mp);
20641   mp->parent_if_index = ntohl (parent_if_index);
20642   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20643
20644   S (mp);
20645   W (ret);
20646   return ret;
20647 }
20648
20649 static int
20650 api_lldp_config (vat_main_t * vam)
20651 {
20652   unformat_input_t *i = vam->input;
20653   vl_api_lldp_config_t *mp;
20654   int tx_hold = 0;
20655   int tx_interval = 0;
20656   u8 *sys_name = NULL;
20657   int ret;
20658
20659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20660     {
20661       if (unformat (i, "system-name %s", &sys_name))
20662         ;
20663       else if (unformat (i, "tx-hold %d", &tx_hold))
20664         ;
20665       else if (unformat (i, "tx-interval %d", &tx_interval))
20666         ;
20667       else
20668         {
20669           clib_warning ("parse error '%U'", format_unformat_error, i);
20670           return -99;
20671         }
20672     }
20673
20674   vec_add1 (sys_name, 0);
20675
20676   M (LLDP_CONFIG, mp);
20677   mp->tx_hold = htonl (tx_hold);
20678   mp->tx_interval = htonl (tx_interval);
20679   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20680   vec_free (sys_name);
20681
20682   S (mp);
20683   W (ret);
20684   return ret;
20685 }
20686
20687 static int
20688 api_sw_interface_set_lldp (vat_main_t * vam)
20689 {
20690   unformat_input_t *i = vam->input;
20691   vl_api_sw_interface_set_lldp_t *mp;
20692   u32 sw_if_index = ~0;
20693   u32 enable = 1;
20694   u8 *port_desc = NULL, *mgmt_oid = NULL;
20695   ip4_address_t ip4_addr;
20696   ip6_address_t ip6_addr;
20697   int ret;
20698
20699   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20700   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20701
20702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20703     {
20704       if (unformat (i, "disable"))
20705         enable = 0;
20706       else
20707         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20708         ;
20709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20710         ;
20711       else if (unformat (i, "port-desc %s", &port_desc))
20712         ;
20713       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20714         ;
20715       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20716         ;
20717       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20718         ;
20719       else
20720         break;
20721     }
20722
20723   if (sw_if_index == ~0)
20724     {
20725       errmsg ("missing interface name or sw_if_index");
20726       return -99;
20727     }
20728
20729   /* Construct the API message */
20730   vec_add1 (port_desc, 0);
20731   vec_add1 (mgmt_oid, 0);
20732   M (SW_INTERFACE_SET_LLDP, mp);
20733   mp->sw_if_index = ntohl (sw_if_index);
20734   mp->enable = enable;
20735   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20736   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20737   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20738   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20739   vec_free (port_desc);
20740   vec_free (mgmt_oid);
20741
20742   S (mp);
20743   W (ret);
20744   return ret;
20745 }
20746
20747 static int
20748 api_tcp_configure_src_addresses (vat_main_t * vam)
20749 {
20750   vl_api_tcp_configure_src_addresses_t *mp;
20751   unformat_input_t *i = vam->input;
20752   ip4_address_t v4first, v4last;
20753   ip6_address_t v6first, v6last;
20754   u8 range_set = 0;
20755   u32 vrf_id = 0;
20756   int ret;
20757
20758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20759     {
20760       if (unformat (i, "%U - %U",
20761                     unformat_ip4_address, &v4first,
20762                     unformat_ip4_address, &v4last))
20763         {
20764           if (range_set)
20765             {
20766               errmsg ("one range per message (range already set)");
20767               return -99;
20768             }
20769           range_set = 1;
20770         }
20771       else if (unformat (i, "%U - %U",
20772                          unformat_ip6_address, &v6first,
20773                          unformat_ip6_address, &v6last))
20774         {
20775           if (range_set)
20776             {
20777               errmsg ("one range per message (range already set)");
20778               return -99;
20779             }
20780           range_set = 2;
20781         }
20782       else if (unformat (i, "vrf %d", &vrf_id))
20783         ;
20784       else
20785         break;
20786     }
20787
20788   if (range_set == 0)
20789     {
20790       errmsg ("address range not set");
20791       return -99;
20792     }
20793
20794   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20795   mp->vrf_id = ntohl (vrf_id);
20796   /* ipv6? */
20797   if (range_set == 2)
20798     {
20799       mp->is_ipv6 = 1;
20800       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20801       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20802     }
20803   else
20804     {
20805       mp->is_ipv6 = 0;
20806       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20807       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20808     }
20809   S (mp);
20810   W (ret);
20811   return ret;
20812 }
20813
20814 static void vl_api_app_namespace_add_del_reply_t_handler
20815   (vl_api_app_namespace_add_del_reply_t * mp)
20816 {
20817   vat_main_t *vam = &vat_main;
20818   i32 retval = ntohl (mp->retval);
20819   if (vam->async_mode)
20820     {
20821       vam->async_errors += (retval < 0);
20822     }
20823   else
20824     {
20825       vam->retval = retval;
20826       if (retval == 0)
20827         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20828       vam->result_ready = 1;
20829     }
20830 }
20831
20832 static void vl_api_app_namespace_add_del_reply_t_handler_json
20833   (vl_api_app_namespace_add_del_reply_t * mp)
20834 {
20835   vat_main_t *vam = &vat_main;
20836   vat_json_node_t node;
20837
20838   vat_json_init_object (&node);
20839   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20840   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20841
20842   vat_json_print (vam->ofp, &node);
20843   vat_json_free (&node);
20844
20845   vam->retval = ntohl (mp->retval);
20846   vam->result_ready = 1;
20847 }
20848
20849 static int
20850 api_app_namespace_add_del (vat_main_t * vam)
20851 {
20852   vl_api_app_namespace_add_del_t *mp;
20853   unformat_input_t *i = vam->input;
20854   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20855   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20856   u64 secret;
20857   int ret;
20858
20859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20860     {
20861       if (unformat (i, "id %_%v%_", &ns_id))
20862         ;
20863       else if (unformat (i, "secret %lu", &secret))
20864         secret_set = 1;
20865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20866         sw_if_index_set = 1;
20867       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20868         ;
20869       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20870         ;
20871       else
20872         break;
20873     }
20874   if (!ns_id || !secret_set || !sw_if_index_set)
20875     {
20876       errmsg ("namespace id, secret and sw_if_index must be set");
20877       return -99;
20878     }
20879   if (vec_len (ns_id) > 64)
20880     {
20881       errmsg ("namespace id too long");
20882       return -99;
20883     }
20884   M (APP_NAMESPACE_ADD_DEL, mp);
20885
20886   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20887   mp->namespace_id_len = vec_len (ns_id);
20888   mp->secret = clib_host_to_net_u64 (secret);
20889   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20890   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20891   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20892   vec_free (ns_id);
20893   S (mp);
20894   W (ret);
20895   return ret;
20896 }
20897
20898 static int
20899 api_sock_init_shm (vat_main_t * vam)
20900 {
20901 #if VPP_API_TEST_BUILTIN == 0
20902   unformat_input_t *i = vam->input;
20903   vl_api_shm_elem_config_t *config = 0;
20904   u64 size = 64 << 20;
20905   int rv;
20906
20907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20908     {
20909       if (unformat (i, "size %U", unformat_memory_size, &size))
20910         ;
20911       else
20912         break;
20913     }
20914
20915   /*
20916    * Canned custom ring allocator config.
20917    * Should probably parse all of this
20918    */
20919   vec_validate (config, 6);
20920   config[0].type = VL_API_VLIB_RING;
20921   config[0].size = 256;
20922   config[0].count = 32;
20923
20924   config[1].type = VL_API_VLIB_RING;
20925   config[1].size = 1024;
20926   config[1].count = 16;
20927
20928   config[2].type = VL_API_VLIB_RING;
20929   config[2].size = 4096;
20930   config[2].count = 2;
20931
20932   config[3].type = VL_API_CLIENT_RING;
20933   config[3].size = 256;
20934   config[3].count = 32;
20935
20936   config[4].type = VL_API_CLIENT_RING;
20937   config[4].size = 1024;
20938   config[4].count = 16;
20939
20940   config[5].type = VL_API_CLIENT_RING;
20941   config[5].size = 4096;
20942   config[5].count = 2;
20943
20944   config[6].type = VL_API_QUEUE;
20945   config[6].count = 128;
20946   config[6].size = sizeof (uword);
20947
20948   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20949   if (!rv)
20950     vam->client_index_invalid = 1;
20951   return rv;
20952 #else
20953   return -99;
20954 #endif
20955 }
20956
20957 static int
20958 api_dns_enable_disable (vat_main_t * vam)
20959 {
20960   unformat_input_t *line_input = vam->input;
20961   vl_api_dns_enable_disable_t *mp;
20962   u8 enable_disable = 1;
20963   int ret;
20964
20965   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20966     {
20967       if (unformat (line_input, "disable"))
20968         enable_disable = 0;
20969       if (unformat (line_input, "enable"))
20970         enable_disable = 1;
20971       else
20972         break;
20973     }
20974
20975   /* Construct the API message */
20976   M (DNS_ENABLE_DISABLE, mp);
20977   mp->enable = enable_disable;
20978
20979   /* send it... */
20980   S (mp);
20981   /* Wait for the reply */
20982   W (ret);
20983   return ret;
20984 }
20985
20986 static int
20987 api_dns_resolve_name (vat_main_t * vam)
20988 {
20989   unformat_input_t *line_input = vam->input;
20990   vl_api_dns_resolve_name_t *mp;
20991   u8 *name = 0;
20992   int ret;
20993
20994   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20995     {
20996       if (unformat (line_input, "%s", &name))
20997         ;
20998       else
20999         break;
21000     }
21001
21002   if (vec_len (name) > 127)
21003     {
21004       errmsg ("name too long");
21005       return -99;
21006     }
21007
21008   /* Construct the API message */
21009   M (DNS_RESOLVE_NAME, mp);
21010   memcpy (mp->name, name, vec_len (name));
21011   vec_free (name);
21012
21013   /* send it... */
21014   S (mp);
21015   /* Wait for the reply */
21016   W (ret);
21017   return ret;
21018 }
21019
21020 static int
21021 api_dns_resolve_ip (vat_main_t * vam)
21022 {
21023   unformat_input_t *line_input = vam->input;
21024   vl_api_dns_resolve_ip_t *mp;
21025   int is_ip6 = -1;
21026   ip4_address_t addr4;
21027   ip6_address_t addr6;
21028   int ret;
21029
21030   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21031     {
21032       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21033         is_ip6 = 1;
21034       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21035         is_ip6 = 0;
21036       else
21037         break;
21038     }
21039
21040   if (is_ip6 == -1)
21041     {
21042       errmsg ("missing address");
21043       return -99;
21044     }
21045
21046   /* Construct the API message */
21047   M (DNS_RESOLVE_IP, mp);
21048   mp->is_ip6 = is_ip6;
21049   if (is_ip6)
21050     memcpy (mp->address, &addr6, sizeof (addr6));
21051   else
21052     memcpy (mp->address, &addr4, sizeof (addr4));
21053
21054   /* send it... */
21055   S (mp);
21056   /* Wait for the reply */
21057   W (ret);
21058   return ret;
21059 }
21060
21061 static int
21062 api_dns_name_server_add_del (vat_main_t * vam)
21063 {
21064   unformat_input_t *i = vam->input;
21065   vl_api_dns_name_server_add_del_t *mp;
21066   u8 is_add = 1;
21067   ip6_address_t ip6_server;
21068   ip4_address_t ip4_server;
21069   int ip6_set = 0;
21070   int ip4_set = 0;
21071   int ret = 0;
21072
21073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21074     {
21075       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21076         ip6_set = 1;
21077       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21078         ip4_set = 1;
21079       else if (unformat (i, "del"))
21080         is_add = 0;
21081       else
21082         {
21083           clib_warning ("parse error '%U'", format_unformat_error, i);
21084           return -99;
21085         }
21086     }
21087
21088   if (ip4_set && ip6_set)
21089     {
21090       errmsg ("Only one server address allowed per message");
21091       return -99;
21092     }
21093   if ((ip4_set + ip6_set) == 0)
21094     {
21095       errmsg ("Server address required");
21096       return -99;
21097     }
21098
21099   /* Construct the API message */
21100   M (DNS_NAME_SERVER_ADD_DEL, mp);
21101
21102   if (ip6_set)
21103     {
21104       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21105       mp->is_ip6 = 1;
21106     }
21107   else
21108     {
21109       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21110       mp->is_ip6 = 0;
21111     }
21112
21113   mp->is_add = is_add;
21114
21115   /* send it... */
21116   S (mp);
21117
21118   /* Wait for a reply, return good/bad news  */
21119   W (ret);
21120   return ret;
21121 }
21122
21123 static void
21124 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21125 {
21126   vat_main_t *vam = &vat_main;
21127
21128   if (mp->is_ip4)
21129     {
21130       print (vam->ofp,
21131              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21132              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21133              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21134              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21135              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21136              clib_net_to_host_u32 (mp->action_index), mp->tag);
21137     }
21138   else
21139     {
21140       print (vam->ofp,
21141              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21142              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21143              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21144              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21145              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21146              clib_net_to_host_u32 (mp->action_index), mp->tag);
21147     }
21148 }
21149
21150 static void
21151 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21152                                              mp)
21153 {
21154   vat_main_t *vam = &vat_main;
21155   vat_json_node_t *node = NULL;
21156   struct in6_addr ip6;
21157   struct in_addr ip4;
21158
21159   if (VAT_JSON_ARRAY != vam->json_tree.type)
21160     {
21161       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21162       vat_json_init_array (&vam->json_tree);
21163     }
21164   node = vat_json_array_add (&vam->json_tree);
21165   vat_json_init_object (node);
21166
21167   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21168   vat_json_object_add_uint (node, "appns_index",
21169                             clib_net_to_host_u32 (mp->appns_index));
21170   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21171   vat_json_object_add_uint (node, "scope", mp->scope);
21172   vat_json_object_add_uint (node, "action_index",
21173                             clib_net_to_host_u32 (mp->action_index));
21174   vat_json_object_add_uint (node, "lcl_port",
21175                             clib_net_to_host_u16 (mp->lcl_port));
21176   vat_json_object_add_uint (node, "rmt_port",
21177                             clib_net_to_host_u16 (mp->rmt_port));
21178   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21179   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21180   vat_json_object_add_string_copy (node, "tag", mp->tag);
21181   if (mp->is_ip4)
21182     {
21183       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21184       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21185       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21186       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21187     }
21188   else
21189     {
21190       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21191       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21192       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21193       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21194     }
21195 }
21196
21197 static int
21198 api_session_rule_add_del (vat_main_t * vam)
21199 {
21200   vl_api_session_rule_add_del_t *mp;
21201   unformat_input_t *i = vam->input;
21202   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21203   u32 appns_index = 0, scope = 0;
21204   ip4_address_t lcl_ip4, rmt_ip4;
21205   ip6_address_t lcl_ip6, rmt_ip6;
21206   u8 is_ip4 = 1, conn_set = 0;
21207   u8 is_add = 1, *tag = 0;
21208   int ret;
21209
21210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21211     {
21212       if (unformat (i, "del"))
21213         is_add = 0;
21214       else if (unformat (i, "add"))
21215         ;
21216       else if (unformat (i, "proto tcp"))
21217         proto = 0;
21218       else if (unformat (i, "proto udp"))
21219         proto = 1;
21220       else if (unformat (i, "appns %d", &appns_index))
21221         ;
21222       else if (unformat (i, "scope %d", &scope))
21223         ;
21224       else if (unformat (i, "tag %_%v%_", &tag))
21225         ;
21226       else
21227         if (unformat
21228             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21229              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21230              &rmt_port))
21231         {
21232           is_ip4 = 1;
21233           conn_set = 1;
21234         }
21235       else
21236         if (unformat
21237             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21238              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21239              &rmt_port))
21240         {
21241           is_ip4 = 0;
21242           conn_set = 1;
21243         }
21244       else if (unformat (i, "action %d", &action))
21245         ;
21246       else
21247         break;
21248     }
21249   if (proto == ~0 || !conn_set || action == ~0)
21250     {
21251       errmsg ("transport proto, connection and action must be set");
21252       return -99;
21253     }
21254
21255   if (scope > 3)
21256     {
21257       errmsg ("scope should be 0-3");
21258       return -99;
21259     }
21260
21261   M (SESSION_RULE_ADD_DEL, mp);
21262
21263   mp->is_ip4 = is_ip4;
21264   mp->transport_proto = proto;
21265   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21266   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21267   mp->lcl_plen = lcl_plen;
21268   mp->rmt_plen = rmt_plen;
21269   mp->action_index = clib_host_to_net_u32 (action);
21270   mp->appns_index = clib_host_to_net_u32 (appns_index);
21271   mp->scope = scope;
21272   mp->is_add = is_add;
21273   if (is_ip4)
21274     {
21275       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21276       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21277     }
21278   else
21279     {
21280       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21281       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21282     }
21283   if (tag)
21284     {
21285       clib_memcpy (mp->tag, tag, vec_len (tag));
21286       vec_free (tag);
21287     }
21288
21289   S (mp);
21290   W (ret);
21291   return ret;
21292 }
21293
21294 static int
21295 api_session_rules_dump (vat_main_t * vam)
21296 {
21297   vl_api_session_rules_dump_t *mp;
21298   vl_api_control_ping_t *mp_ping;
21299   int ret;
21300
21301   if (!vam->json_output)
21302     {
21303       print (vam->ofp, "%=20s", "Session Rules");
21304     }
21305
21306   M (SESSION_RULES_DUMP, mp);
21307   /* send it... */
21308   S (mp);
21309
21310   /* Use a control ping for synchronization */
21311   MPING (CONTROL_PING, mp_ping);
21312   S (mp_ping);
21313
21314   /* Wait for a reply... */
21315   W (ret);
21316   return ret;
21317 }
21318
21319 static int
21320 api_ip_container_proxy_add_del (vat_main_t * vam)
21321 {
21322   vl_api_ip_container_proxy_add_del_t *mp;
21323   unformat_input_t *i = vam->input;
21324   u32 sw_if_index = ~0;
21325   vl_api_prefix_t pfx = { };
21326   u8 is_add = 1;
21327   int ret;
21328
21329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21330     {
21331       if (unformat (i, "del"))
21332         is_add = 0;
21333       else if (unformat (i, "add"))
21334         ;
21335       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21336         ;
21337       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21338         ;
21339       else
21340         break;
21341     }
21342   if (sw_if_index == ~0 || pfx.len == 0)
21343     {
21344       errmsg ("address and sw_if_index must be set");
21345       return -99;
21346     }
21347
21348   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21349
21350   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21351   mp->is_add = is_add;
21352   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21353
21354   S (mp);
21355   W (ret);
21356   return ret;
21357 }
21358
21359 static int
21360 api_qos_record_enable_disable (vat_main_t * vam)
21361 {
21362   unformat_input_t *i = vam->input;
21363   vl_api_qos_record_enable_disable_t *mp;
21364   u32 sw_if_index, qs = 0xff;
21365   u8 sw_if_index_set = 0;
21366   u8 enable = 1;
21367   int ret;
21368
21369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21370     {
21371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21372         sw_if_index_set = 1;
21373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21374         sw_if_index_set = 1;
21375       else if (unformat (i, "%U", unformat_qos_source, &qs))
21376         ;
21377       else if (unformat (i, "disable"))
21378         enable = 0;
21379       else
21380         {
21381           clib_warning ("parse error '%U'", format_unformat_error, i);
21382           return -99;
21383         }
21384     }
21385
21386   if (sw_if_index_set == 0)
21387     {
21388       errmsg ("missing interface name or sw_if_index");
21389       return -99;
21390     }
21391   if (qs == 0xff)
21392     {
21393       errmsg ("input location must be specified");
21394       return -99;
21395     }
21396
21397   M (QOS_RECORD_ENABLE_DISABLE, mp);
21398
21399   mp->record.sw_if_index = ntohl (sw_if_index);
21400   mp->record.input_source = qs;
21401   mp->enable = enable;
21402
21403   S (mp);
21404   W (ret);
21405   return ret;
21406 }
21407
21408
21409 static int
21410 q_or_quit (vat_main_t * vam)
21411 {
21412 #if VPP_API_TEST_BUILTIN == 0
21413   longjmp (vam->jump_buf, 1);
21414 #endif
21415   return 0;                     /* not so much */
21416 }
21417
21418 static int
21419 q (vat_main_t * vam)
21420 {
21421   return q_or_quit (vam);
21422 }
21423
21424 static int
21425 quit (vat_main_t * vam)
21426 {
21427   return q_or_quit (vam);
21428 }
21429
21430 static int
21431 comment (vat_main_t * vam)
21432 {
21433   return 0;
21434 }
21435
21436 static int
21437 elog_save (vat_main_t * vam)
21438 {
21439 #if VPP_API_TEST_BUILTIN == 0
21440   elog_main_t *em = &vam->elog_main;
21441   unformat_input_t *i = vam->input;
21442   char *file, *chroot_file;
21443   clib_error_t *error;
21444
21445   if (!unformat (i, "%s", &file))
21446     {
21447       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21448       return 0;
21449     }
21450
21451   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21452   if (strstr (file, "..") || index (file, '/'))
21453     {
21454       errmsg ("illegal characters in filename '%s'", file);
21455       return 0;
21456     }
21457
21458   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21459
21460   vec_free (file);
21461
21462   errmsg ("Saving %wd of %wd events to %s",
21463           elog_n_events_in_buffer (em),
21464           elog_buffer_capacity (em), chroot_file);
21465
21466   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21467   vec_free (chroot_file);
21468
21469   if (error)
21470     clib_error_report (error);
21471 #else
21472   errmsg ("Use the vpp event loger...");
21473 #endif
21474
21475   return 0;
21476 }
21477
21478 static int
21479 elog_setup (vat_main_t * vam)
21480 {
21481 #if VPP_API_TEST_BUILTIN == 0
21482   elog_main_t *em = &vam->elog_main;
21483   unformat_input_t *i = vam->input;
21484   u32 nevents = 128 << 10;
21485
21486   (void) unformat (i, "nevents %d", &nevents);
21487
21488   elog_init (em, nevents);
21489   vl_api_set_elog_main (em);
21490   vl_api_set_elog_trace_api_messages (1);
21491   errmsg ("Event logger initialized with %u events", nevents);
21492 #else
21493   errmsg ("Use the vpp event loger...");
21494 #endif
21495   return 0;
21496 }
21497
21498 static int
21499 elog_enable (vat_main_t * vam)
21500 {
21501 #if VPP_API_TEST_BUILTIN == 0
21502   elog_main_t *em = &vam->elog_main;
21503
21504   elog_enable_disable (em, 1 /* enable */ );
21505   vl_api_set_elog_trace_api_messages (1);
21506   errmsg ("Event logger enabled...");
21507 #else
21508   errmsg ("Use the vpp event loger...");
21509 #endif
21510   return 0;
21511 }
21512
21513 static int
21514 elog_disable (vat_main_t * vam)
21515 {
21516 #if VPP_API_TEST_BUILTIN == 0
21517   elog_main_t *em = &vam->elog_main;
21518
21519   elog_enable_disable (em, 0 /* enable */ );
21520   vl_api_set_elog_trace_api_messages (1);
21521   errmsg ("Event logger disabled...");
21522 #else
21523   errmsg ("Use the vpp event loger...");
21524 #endif
21525   return 0;
21526 }
21527
21528 static int
21529 statseg (vat_main_t * vam)
21530 {
21531   ssvm_private_t *ssvmp = &vam->stat_segment;
21532   ssvm_shared_header_t *shared_header = ssvmp->sh;
21533   vlib_counter_t **counters;
21534   u64 thread0_index1_packets;
21535   u64 thread0_index1_bytes;
21536   f64 vector_rate, input_rate;
21537   uword *p;
21538
21539   uword *counter_vector_by_name;
21540   if (vam->stat_segment_lockp == 0)
21541     {
21542       errmsg ("Stat segment not mapped...");
21543       return -99;
21544     }
21545
21546   /* look up "/if/rx for sw_if_index 1 as a test */
21547
21548   clib_spinlock_lock (vam->stat_segment_lockp);
21549
21550   counter_vector_by_name = (uword *) shared_header->opaque[1];
21551
21552   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21553   if (p == 0)
21554     {
21555       clib_spinlock_unlock (vam->stat_segment_lockp);
21556       errmsg ("/if/tx not found?");
21557       return -99;
21558     }
21559
21560   /* Fish per-thread vector of combined counters from shared memory */
21561   counters = (vlib_counter_t **) p[0];
21562
21563   if (vec_len (counters[0]) < 2)
21564     {
21565       clib_spinlock_unlock (vam->stat_segment_lockp);
21566       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21567       return -99;
21568     }
21569
21570   /* Read thread 0 sw_if_index 1 counter */
21571   thread0_index1_packets = counters[0][1].packets;
21572   thread0_index1_bytes = counters[0][1].bytes;
21573
21574   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21575   if (p == 0)
21576     {
21577       clib_spinlock_unlock (vam->stat_segment_lockp);
21578       errmsg ("vector_rate not found?");
21579       return -99;
21580     }
21581
21582   vector_rate = *(f64 *) (p[0]);
21583   p = hash_get_mem (counter_vector_by_name, "input_rate");
21584   if (p == 0)
21585     {
21586       clib_spinlock_unlock (vam->stat_segment_lockp);
21587       errmsg ("input_rate not found?");
21588       return -99;
21589     }
21590   input_rate = *(f64 *) (p[0]);
21591
21592   clib_spinlock_unlock (vam->stat_segment_lockp);
21593
21594   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21595          vector_rate, input_rate);
21596   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21597          thread0_index1_packets, thread0_index1_bytes);
21598
21599   return 0;
21600 }
21601
21602 static int
21603 cmd_cmp (void *a1, void *a2)
21604 {
21605   u8 **c1 = a1;
21606   u8 **c2 = a2;
21607
21608   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21609 }
21610
21611 static int
21612 help (vat_main_t * vam)
21613 {
21614   u8 **cmds = 0;
21615   u8 *name = 0;
21616   hash_pair_t *p;
21617   unformat_input_t *i = vam->input;
21618   int j;
21619
21620   if (unformat (i, "%s", &name))
21621     {
21622       uword *hs;
21623
21624       vec_add1 (name, 0);
21625
21626       hs = hash_get_mem (vam->help_by_name, name);
21627       if (hs)
21628         print (vam->ofp, "usage: %s %s", name, hs[0]);
21629       else
21630         print (vam->ofp, "No such msg / command '%s'", name);
21631       vec_free (name);
21632       return 0;
21633     }
21634
21635   print (vam->ofp, "Help is available for the following:");
21636
21637     /* *INDENT-OFF* */
21638     hash_foreach_pair (p, vam->function_by_name,
21639     ({
21640       vec_add1 (cmds, (u8 *)(p->key));
21641     }));
21642     /* *INDENT-ON* */
21643
21644   vec_sort_with_function (cmds, cmd_cmp);
21645
21646   for (j = 0; j < vec_len (cmds); j++)
21647     print (vam->ofp, "%s", cmds[j]);
21648
21649   vec_free (cmds);
21650   return 0;
21651 }
21652
21653 static int
21654 set (vat_main_t * vam)
21655 {
21656   u8 *name = 0, *value = 0;
21657   unformat_input_t *i = vam->input;
21658
21659   if (unformat (i, "%s", &name))
21660     {
21661       /* The input buffer is a vector, not a string. */
21662       value = vec_dup (i->buffer);
21663       vec_delete (value, i->index, 0);
21664       /* Almost certainly has a trailing newline */
21665       if (value[vec_len (value) - 1] == '\n')
21666         value[vec_len (value) - 1] = 0;
21667       /* Make sure it's a proper string, one way or the other */
21668       vec_add1 (value, 0);
21669       (void) clib_macro_set_value (&vam->macro_main,
21670                                    (char *) name, (char *) value);
21671     }
21672   else
21673     errmsg ("usage: set <name> <value>");
21674
21675   vec_free (name);
21676   vec_free (value);
21677   return 0;
21678 }
21679
21680 static int
21681 unset (vat_main_t * vam)
21682 {
21683   u8 *name = 0;
21684
21685   if (unformat (vam->input, "%s", &name))
21686     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21687       errmsg ("unset: %s wasn't set", name);
21688   vec_free (name);
21689   return 0;
21690 }
21691
21692 typedef struct
21693 {
21694   u8 *name;
21695   u8 *value;
21696 } macro_sort_t;
21697
21698
21699 static int
21700 macro_sort_cmp (void *a1, void *a2)
21701 {
21702   macro_sort_t *s1 = a1;
21703   macro_sort_t *s2 = a2;
21704
21705   return strcmp ((char *) (s1->name), (char *) (s2->name));
21706 }
21707
21708 static int
21709 dump_macro_table (vat_main_t * vam)
21710 {
21711   macro_sort_t *sort_me = 0, *sm;
21712   int i;
21713   hash_pair_t *p;
21714
21715     /* *INDENT-OFF* */
21716     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21717     ({
21718       vec_add2 (sort_me, sm, 1);
21719       sm->name = (u8 *)(p->key);
21720       sm->value = (u8 *) (p->value[0]);
21721     }));
21722     /* *INDENT-ON* */
21723
21724   vec_sort_with_function (sort_me, macro_sort_cmp);
21725
21726   if (vec_len (sort_me))
21727     print (vam->ofp, "%-15s%s", "Name", "Value");
21728   else
21729     print (vam->ofp, "The macro table is empty...");
21730
21731   for (i = 0; i < vec_len (sort_me); i++)
21732     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21733   return 0;
21734 }
21735
21736 static int
21737 dump_node_table (vat_main_t * vam)
21738 {
21739   int i, j;
21740   vlib_node_t *node, *next_node;
21741
21742   if (vec_len (vam->graph_nodes) == 0)
21743     {
21744       print (vam->ofp, "Node table empty, issue get_node_graph...");
21745       return 0;
21746     }
21747
21748   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21749     {
21750       node = vam->graph_nodes[0][i];
21751       print (vam->ofp, "[%d] %s", i, node->name);
21752       for (j = 0; j < vec_len (node->next_nodes); j++)
21753         {
21754           if (node->next_nodes[j] != ~0)
21755             {
21756               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21757               print (vam->ofp, "  [%d] %s", j, next_node->name);
21758             }
21759         }
21760     }
21761   return 0;
21762 }
21763
21764 static int
21765 value_sort_cmp (void *a1, void *a2)
21766 {
21767   name_sort_t *n1 = a1;
21768   name_sort_t *n2 = a2;
21769
21770   if (n1->value < n2->value)
21771     return -1;
21772   if (n1->value > n2->value)
21773     return 1;
21774   return 0;
21775 }
21776
21777
21778 static int
21779 dump_msg_api_table (vat_main_t * vam)
21780 {
21781   api_main_t *am = &api_main;
21782   name_sort_t *nses = 0, *ns;
21783   hash_pair_t *hp;
21784   int i;
21785
21786   /* *INDENT-OFF* */
21787   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21788   ({
21789     vec_add2 (nses, ns, 1);
21790     ns->name = (u8 *)(hp->key);
21791     ns->value = (u32) hp->value[0];
21792   }));
21793   /* *INDENT-ON* */
21794
21795   vec_sort_with_function (nses, value_sort_cmp);
21796
21797   for (i = 0; i < vec_len (nses); i++)
21798     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21799   vec_free (nses);
21800   return 0;
21801 }
21802
21803 static int
21804 get_msg_id (vat_main_t * vam)
21805 {
21806   u8 *name_and_crc;
21807   u32 message_index;
21808
21809   if (unformat (vam->input, "%s", &name_and_crc))
21810     {
21811       message_index = vl_msg_api_get_msg_index (name_and_crc);
21812       if (message_index == ~0)
21813         {
21814           print (vam->ofp, " '%s' not found", name_and_crc);
21815           return 0;
21816         }
21817       print (vam->ofp, " '%s' has message index %d",
21818              name_and_crc, message_index);
21819       return 0;
21820     }
21821   errmsg ("name_and_crc required...");
21822   return 0;
21823 }
21824
21825 static int
21826 search_node_table (vat_main_t * vam)
21827 {
21828   unformat_input_t *line_input = vam->input;
21829   u8 *node_to_find;
21830   int j;
21831   vlib_node_t *node, *next_node;
21832   uword *p;
21833
21834   if (vam->graph_node_index_by_name == 0)
21835     {
21836       print (vam->ofp, "Node table empty, issue get_node_graph...");
21837       return 0;
21838     }
21839
21840   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21841     {
21842       if (unformat (line_input, "%s", &node_to_find))
21843         {
21844           vec_add1 (node_to_find, 0);
21845           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21846           if (p == 0)
21847             {
21848               print (vam->ofp, "%s not found...", node_to_find);
21849               goto out;
21850             }
21851           node = vam->graph_nodes[0][p[0]];
21852           print (vam->ofp, "[%d] %s", p[0], node->name);
21853           for (j = 0; j < vec_len (node->next_nodes); j++)
21854             {
21855               if (node->next_nodes[j] != ~0)
21856                 {
21857                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21858                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21859                 }
21860             }
21861         }
21862
21863       else
21864         {
21865           clib_warning ("parse error '%U'", format_unformat_error,
21866                         line_input);
21867           return -99;
21868         }
21869
21870     out:
21871       vec_free (node_to_find);
21872
21873     }
21874
21875   return 0;
21876 }
21877
21878
21879 static int
21880 script (vat_main_t * vam)
21881 {
21882 #if (VPP_API_TEST_BUILTIN==0)
21883   u8 *s = 0;
21884   char *save_current_file;
21885   unformat_input_t save_input;
21886   jmp_buf save_jump_buf;
21887   u32 save_line_number;
21888
21889   FILE *new_fp, *save_ifp;
21890
21891   if (unformat (vam->input, "%s", &s))
21892     {
21893       new_fp = fopen ((char *) s, "r");
21894       if (new_fp == 0)
21895         {
21896           errmsg ("Couldn't open script file %s", s);
21897           vec_free (s);
21898           return -99;
21899         }
21900     }
21901   else
21902     {
21903       errmsg ("Missing script name");
21904       return -99;
21905     }
21906
21907   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21908   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21909   save_ifp = vam->ifp;
21910   save_line_number = vam->input_line_number;
21911   save_current_file = (char *) vam->current_file;
21912
21913   vam->input_line_number = 0;
21914   vam->ifp = new_fp;
21915   vam->current_file = s;
21916   do_one_file (vam);
21917
21918   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21919   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21920   vam->ifp = save_ifp;
21921   vam->input_line_number = save_line_number;
21922   vam->current_file = (u8 *) save_current_file;
21923   vec_free (s);
21924
21925   return 0;
21926 #else
21927   clib_warning ("use the exec command...");
21928   return -99;
21929 #endif
21930 }
21931
21932 static int
21933 echo (vat_main_t * vam)
21934 {
21935   print (vam->ofp, "%v", vam->input->buffer);
21936   return 0;
21937 }
21938
21939 /* List of API message constructors, CLI names map to api_xxx */
21940 #define foreach_vpe_api_msg                                             \
21941 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21942 _(sw_interface_dump,"")                                                 \
21943 _(sw_interface_set_flags,                                               \
21944   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21945 _(sw_interface_add_del_address,                                         \
21946   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21947 _(sw_interface_set_rx_mode,                                             \
21948   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21949 _(sw_interface_set_rx_placement,                                        \
21950   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21951 _(sw_interface_rx_placement_dump,                                       \
21952   "[<intfc> | sw_if_index <id>]")                                         \
21953 _(sw_interface_set_table,                                               \
21954   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21955 _(sw_interface_set_mpls_enable,                                         \
21956   "<intfc> | sw_if_index [disable | dis]")                              \
21957 _(sw_interface_set_vpath,                                               \
21958   "<intfc> | sw_if_index <id> enable | disable")                        \
21959 _(sw_interface_set_vxlan_bypass,                                        \
21960   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21961 _(sw_interface_set_geneve_bypass,                                       \
21962   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21963 _(sw_interface_set_l2_xconnect,                                         \
21964   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21965   "enable | disable")                                                   \
21966 _(sw_interface_set_l2_bridge,                                           \
21967   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21968   "[shg <split-horizon-group>] [bvi]\n"                                 \
21969   "enable | disable")                                                   \
21970 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21971 _(bridge_domain_add_del,                                                \
21972   "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") \
21973 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21974 _(l2fib_add_del,                                                        \
21975   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21976 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21977 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21978 _(l2_flags,                                                             \
21979   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21980 _(bridge_flags,                                                         \
21981   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21982 _(tap_create_v2,                                                        \
21983   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21984 _(tap_delete_v2,                                                        \
21985   "<vpp-if-name> | sw_if_index <id>")                                   \
21986 _(sw_interface_tap_v2_dump, "")                                         \
21987 _(virtio_pci_create,                                                    \
21988   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21989 _(virtio_pci_delete,                                                    \
21990   "<vpp-if-name> | sw_if_index <id>")                                   \
21991 _(sw_interface_virtio_pci_dump, "")                                     \
21992 _(bond_create,                                                          \
21993   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21994   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21995   "[id <if-id>]")                                                       \
21996 _(bond_delete,                                                          \
21997   "<vpp-if-name> | sw_if_index <id>")                                   \
21998 _(bond_enslave,                                                         \
21999   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22000 _(bond_detach_slave,                                                    \
22001   "sw_if_index <n>")                                                    \
22002 _(sw_interface_bond_dump, "")                                           \
22003 _(sw_interface_slave_dump,                                              \
22004   "<vpp-if-name> | sw_if_index <id>")                                   \
22005 _(ip_table_add_del,                                                     \
22006   "table <n> [ipv6] [add | del]\n")                                     \
22007 _(ip_route_add_del,                                                     \
22008   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22009   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22010   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22011   "[multipath] [count <n>] [del]")                                      \
22012 _(ip_mroute_add_del,                                                    \
22013   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22014   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22015 _(mpls_table_add_del,                                                   \
22016   "table <n> [add | del]\n")                                            \
22017 _(mpls_route_add_del,                                                   \
22018   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22019   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22020   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22021   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22022   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22023   "[count <n>] [del]")                                                  \
22024 _(mpls_ip_bind_unbind,                                                  \
22025   "<label> <addr/len>")                                                 \
22026 _(mpls_tunnel_add_del,                                                  \
22027   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22028   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22029   "[l2-only]  [out-label <n>]")                                         \
22030 _(sr_mpls_policy_add,                                                   \
22031   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22032 _(sr_mpls_policy_del,                                                   \
22033   "bsid <id>")                                                          \
22034 _(bier_table_add_del,                                                   \
22035   "<label> <sub-domain> <set> <bsl> [del]")                             \
22036 _(bier_route_add_del,                                                   \
22037   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22038   "[<intfc> | sw_if_index <id>]"                                        \
22039   "[weight <n>] [del] [multipath]")                                     \
22040 _(proxy_arp_add_del,                                                    \
22041   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22042 _(proxy_arp_intfc_enable_disable,                                       \
22043   "<intfc> | sw_if_index <id> enable | disable")                        \
22044 _(sw_interface_set_unnumbered,                                          \
22045   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22046 _(ip_neighbor_add_del,                                                  \
22047   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22048   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22049 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22050 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22051   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22052   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22053   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22054 _(reset_fib, "vrf <n> [ipv6]")                                          \
22055 _(dhcp_proxy_config,                                                    \
22056   "svr <v46-address> src <v46-address>\n"                               \
22057    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22058 _(dhcp_proxy_set_vss,                                                   \
22059   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22060 _(dhcp_proxy_dump, "ip6")                                               \
22061 _(dhcp_client_config,                                                   \
22062   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22063 _(set_ip_flow_hash,                                                     \
22064   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22065 _(sw_interface_ip6_enable_disable,                                      \
22066   "<intfc> | sw_if_index <id> enable | disable")                        \
22067 _(ip6nd_proxy_add_del,                                                  \
22068   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22069 _(ip6nd_proxy_dump, "")                                                 \
22070 _(sw_interface_ip6nd_ra_prefix,                                         \
22071   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22072   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22073   "[nolink] [isno]")                                                    \
22074 _(sw_interface_ip6nd_ra_config,                                         \
22075   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22076   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22077   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22078 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22079 _(l2_patch_add_del,                                                     \
22080   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22081   "enable | disable")                                                   \
22082 _(sr_localsid_add_del,                                                  \
22083   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22084   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22085 _(classify_add_del_table,                                               \
22086   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22087   " [del] [del-chain] mask <mask-value>\n"                              \
22088   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22089   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22090 _(classify_add_del_session,                                             \
22091   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22092   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22093   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22094   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22095 _(classify_set_interface_ip_table,                                      \
22096   "<intfc> | sw_if_index <nn> table <nn>")                              \
22097 _(classify_set_interface_l2_tables,                                     \
22098   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22099   "  [other-table <nn>]")                                               \
22100 _(get_node_index, "node <node-name")                                    \
22101 _(add_node_next, "node <node-name> next <next-node-name>")              \
22102 _(l2tpv3_create_tunnel,                                                 \
22103   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22104   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22105   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22106 _(l2tpv3_set_tunnel_cookies,                                            \
22107   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22108   "[new_remote_cookie <nn>]\n")                                         \
22109 _(l2tpv3_interface_enable_disable,                                      \
22110   "<intfc> | sw_if_index <nn> enable | disable")                        \
22111 _(l2tpv3_set_lookup_key,                                                \
22112   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22113 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22114 _(vxlan_offload_rx,                                                     \
22115   "hw { <interface name> | hw_if_index <nn>} "                          \
22116   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22117 _(vxlan_add_del_tunnel,                                                 \
22118   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22119   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22120   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22121 _(geneve_add_del_tunnel,                                                \
22122   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22123   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22124   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22125 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22126 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22127 _(gre_tunnel_add_del,                                                   \
22128   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22129   "[teb | erspan <session-id>] [del]")                                  \
22130 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22131 _(l2_fib_clear_table, "")                                               \
22132 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22133 _(l2_interface_vlan_tag_rewrite,                                        \
22134   "<intfc> | sw_if_index <nn> \n"                                       \
22135   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22136   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22137 _(create_vhost_user_if,                                                 \
22138         "socket <filename> [server] [renumber <dev_instance>] "         \
22139         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
22140         "[mac <mac_address>]")                                          \
22141 _(modify_vhost_user_if,                                                 \
22142         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22143         "[server] [renumber <dev_instance>] [gso]")                     \
22144 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22145 _(sw_interface_vhost_user_dump, "")                                     \
22146 _(show_version, "")                                                     \
22147 _(show_threads, "")                                                     \
22148 _(vxlan_gpe_add_del_tunnel,                                             \
22149   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22150   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22151   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22152   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22153 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22154 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22155 _(interface_name_renumber,                                              \
22156   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22157 _(input_acl_set_interface,                                              \
22158   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22159   "  [l2-table <nn>] [del]")                                            \
22160 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22161 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22162   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22163 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22164 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22165 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22166 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22167 _(ip_dump, "ipv4 | ipv6")                                               \
22168 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22169 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22170   "  spid_id <n> ")                                                     \
22171 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22172   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22173   "  integ_alg <alg> integ_key <hex>")                                  \
22174 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22175   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22176   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22177   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22178 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22179   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22180   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22181   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22182   "  [instance <n>]")     \
22183 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22184 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22185 _(delete_loopback,"sw_if_index <nn>")                                   \
22186 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22187 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22188 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22189 _(want_interface_events,  "enable|disable")                             \
22190 _(get_first_msg_id, "client <name>")                                    \
22191 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22192 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22193   "fib-id <nn> [ip4][ip6][default]")                                    \
22194 _(get_node_graph, " ")                                                  \
22195 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22196 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22197 _(ioam_disable, "")                                                     \
22198 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22199                             " sw_if_index <sw_if_index> p <priority> "  \
22200                             "w <weight>] [del]")                        \
22201 _(one_add_del_locator, "locator-set <locator_name> "                    \
22202                         "iface <intf> | sw_if_index <sw_if_index> "     \
22203                         "p <priority> w <weight> [del]")                \
22204 _(one_add_del_local_eid,"vni <vni> eid "                                \
22205                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22206                          "locator-set <locator_name> [del]"             \
22207                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22208 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22209 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22210 _(one_enable_disable, "enable|disable")                                 \
22211 _(one_map_register_enable_disable, "enable|disable")                    \
22212 _(one_map_register_fallback_threshold, "<value>")                       \
22213 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22214 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22215                                "[seid <seid>] "                         \
22216                                "rloc <locator> p <prio> "               \
22217                                "w <weight> [rloc <loc> ... ] "          \
22218                                "action <action> [del-all]")             \
22219 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22220                           "<local-eid>")                                \
22221 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22222 _(one_use_petr, "ip-address> | disable")                                \
22223 _(one_map_request_mode, "src-dst|dst-only")                             \
22224 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22225 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22226 _(one_locator_set_dump, "[local | remote]")                             \
22227 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22228 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22229                        "[local] | [remote]")                            \
22230 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22231 _(one_ndp_bd_get, "")                                                   \
22232 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22233 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22234 _(one_l2_arp_bd_get, "")                                                \
22235 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22236 _(one_stats_enable_disable, "enable|disable")                           \
22237 _(show_one_stats_enable_disable, "")                                    \
22238 _(one_eid_table_vni_dump, "")                                           \
22239 _(one_eid_table_map_dump, "l2|l3")                                      \
22240 _(one_map_resolver_dump, "")                                            \
22241 _(one_map_server_dump, "")                                              \
22242 _(one_adjacencies_get, "vni <vni>")                                     \
22243 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22244 _(show_one_rloc_probe_state, "")                                        \
22245 _(show_one_map_register_state, "")                                      \
22246 _(show_one_status, "")                                                  \
22247 _(one_stats_dump, "")                                                   \
22248 _(one_stats_flush, "")                                                  \
22249 _(one_get_map_request_itr_rlocs, "")                                    \
22250 _(one_map_register_set_ttl, "<ttl>")                                    \
22251 _(one_set_transport_protocol, "udp|api")                                \
22252 _(one_get_transport_protocol, "")                                       \
22253 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22254 _(one_show_xtr_mode, "")                                                \
22255 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22256 _(one_show_pitr_mode, "")                                               \
22257 _(one_enable_disable_petr_mode, "enable|disable")                       \
22258 _(one_show_petr_mode, "")                                               \
22259 _(show_one_nsh_mapping, "")                                             \
22260 _(show_one_pitr, "")                                                    \
22261 _(show_one_use_petr, "")                                                \
22262 _(show_one_map_request_mode, "")                                        \
22263 _(show_one_map_register_ttl, "")                                        \
22264 _(show_one_map_register_fallback_threshold, "")                         \
22265 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22266                             " sw_if_index <sw_if_index> p <priority> "  \
22267                             "w <weight>] [del]")                        \
22268 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22269                         "iface <intf> | sw_if_index <sw_if_index> "     \
22270                         "p <priority> w <weight> [del]")                \
22271 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22272                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22273                          "locator-set <locator_name> [del]"             \
22274                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22275 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22276 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22277 _(lisp_enable_disable, "enable|disable")                                \
22278 _(lisp_map_register_enable_disable, "enable|disable")                   \
22279 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22280 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22281                                "[seid <seid>] "                         \
22282                                "rloc <locator> p <prio> "               \
22283                                "w <weight> [rloc <loc> ... ] "          \
22284                                "action <action> [del-all]")             \
22285 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22286                           "<local-eid>")                                \
22287 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22288 _(lisp_use_petr, "<ip-address> | disable")                              \
22289 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22290 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22291 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22292 _(lisp_locator_set_dump, "[local | remote]")                            \
22293 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22294 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22295                        "[local] | [remote]")                            \
22296 _(lisp_eid_table_vni_dump, "")                                          \
22297 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22298 _(lisp_map_resolver_dump, "")                                           \
22299 _(lisp_map_server_dump, "")                                             \
22300 _(lisp_adjacencies_get, "vni <vni>")                                    \
22301 _(gpe_fwd_entry_vnis_get, "")                                           \
22302 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22303 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22304                                 "[table <table-id>]")                   \
22305 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22306 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22307 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22308 _(gpe_get_encap_mode, "")                                               \
22309 _(lisp_gpe_add_del_iface, "up|down")                                    \
22310 _(lisp_gpe_enable_disable, "enable|disable")                            \
22311 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22312   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22313 _(show_lisp_rloc_probe_state, "")                                       \
22314 _(show_lisp_map_register_state, "")                                     \
22315 _(show_lisp_status, "")                                                 \
22316 _(lisp_get_map_request_itr_rlocs, "")                                   \
22317 _(show_lisp_pitr, "")                                                   \
22318 _(show_lisp_use_petr, "")                                               \
22319 _(show_lisp_map_request_mode, "")                                       \
22320 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22321 _(af_packet_delete, "name <host interface name>")                       \
22322 _(af_packet_dump, "")                                                   \
22323 _(policer_add_del, "name <policer name> <params> [del]")                \
22324 _(policer_dump, "[name <policer name>]")                                \
22325 _(policer_classify_set_interface,                                       \
22326   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22327   "  [l2-table <nn>] [del]")                                            \
22328 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22329 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22330     "[master|slave]")                                                   \
22331 _(netmap_delete, "name <interface name>")                               \
22332 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22333 _(mpls_table_dump, "")                                                  \
22334 _(mpls_route_dump, "table-id <ID>")                                     \
22335 _(classify_table_ids, "")                                               \
22336 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22337 _(classify_table_info, "table_id <nn>")                                 \
22338 _(classify_session_dump, "table_id <nn>")                               \
22339 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22340     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22341     "[template_interval <nn>] [udp_checksum]")                          \
22342 _(ipfix_exporter_dump, "")                                              \
22343 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22344 _(ipfix_classify_stream_dump, "")                                       \
22345 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22346 _(ipfix_classify_table_dump, "")                                        \
22347 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22348 _(sw_interface_span_dump, "[l2]")                                           \
22349 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22350 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22351 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22352 _(pg_enable_disable, "[stream <id>] disable")                           \
22353 _(ip_source_and_port_range_check_add_del,                               \
22354   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22355 _(ip_source_and_port_range_check_interface_add_del,                     \
22356   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22357   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22358 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22359 _(l2_interface_pbb_tag_rewrite,                                         \
22360   "<intfc> | sw_if_index <nn> \n"                                       \
22361   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22362   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22363 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22364 _(flow_classify_set_interface,                                          \
22365   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22366 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22367 _(ip_table_dump, "")                                                    \
22368 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22369 _(ip_mtable_dump, "")                                                   \
22370 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22371 _(feature_enable_disable, "arc_name <arc_name> "                        \
22372   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22373 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22374 "[disable]")                                                            \
22375 _(l2_xconnect_dump, "")                                                 \
22376 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22377 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22378 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22379 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22380 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22381 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22382 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22383   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22384 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22385 _(sock_init_shm, "size <nnn>")                                          \
22386 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22387 _(dns_enable_disable, "[enable][disable]")                              \
22388 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22389 _(dns_resolve_name, "<hostname>")                                       \
22390 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22391 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22392 _(dns_resolve_name, "<hostname>")                                       \
22393 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22394   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22395 _(session_rules_dump, "")                                               \
22396 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22397 _(output_acl_set_interface,                                             \
22398   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22399   "  [l2-table <nn>] [del]")                                            \
22400 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22401
22402 /* List of command functions, CLI names map directly to functions */
22403 #define foreach_cli_function                                    \
22404 _(comment, "usage: comment <ignore-rest-of-line>")              \
22405 _(dump_interface_table, "usage: dump_interface_table")          \
22406 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22407 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22408 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22409 _(dump_macro_table, "usage: dump_macro_table ")                 \
22410 _(dump_node_table, "usage: dump_node_table")                    \
22411 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22412 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22413 _(elog_disable, "usage: elog_disable")                          \
22414 _(elog_enable, "usage: elog_enable")                            \
22415 _(elog_save, "usage: elog_save <filename>")                     \
22416 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22417 _(echo, "usage: echo <message>")                                \
22418 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22419 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22420 _(help, "usage: help")                                          \
22421 _(q, "usage: quit")                                             \
22422 _(quit, "usage: quit")                                          \
22423 _(search_node_table, "usage: search_node_table <name>...")      \
22424 _(set, "usage: set <variable-name> <value>")                    \
22425 _(script, "usage: script <file-name>")                          \
22426 _(statseg, "usage: statseg")                                    \
22427 _(unset, "usage: unset <variable-name>")
22428
22429 #define _(N,n)                                  \
22430     static void vl_api_##n##_t_handler_uni      \
22431     (vl_api_##n##_t * mp)                       \
22432     {                                           \
22433         vat_main_t * vam = &vat_main;           \
22434         if (vam->json_output) {                 \
22435             vl_api_##n##_t_handler_json(mp);    \
22436         } else {                                \
22437             vl_api_##n##_t_handler(mp);         \
22438         }                                       \
22439     }
22440 foreach_vpe_api_reply_msg;
22441 #if VPP_API_TEST_BUILTIN == 0
22442 foreach_standalone_reply_msg;
22443 #endif
22444 #undef _
22445
22446 void
22447 vat_api_hookup (vat_main_t * vam)
22448 {
22449 #define _(N,n)                                                  \
22450     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22451                            vl_api_##n##_t_handler_uni,          \
22452                            vl_noop_handler,                     \
22453                            vl_api_##n##_t_endian,               \
22454                            vl_api_##n##_t_print,                \
22455                            sizeof(vl_api_##n##_t), 1);
22456   foreach_vpe_api_reply_msg;
22457 #if VPP_API_TEST_BUILTIN == 0
22458   foreach_standalone_reply_msg;
22459 #endif
22460 #undef _
22461
22462 #if (VPP_API_TEST_BUILTIN==0)
22463   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22464
22465   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22466
22467   vam->function_by_name = hash_create_string (0, sizeof (uword));
22468
22469   vam->help_by_name = hash_create_string (0, sizeof (uword));
22470 #endif
22471
22472   /* API messages we can send */
22473 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22474   foreach_vpe_api_msg;
22475 #undef _
22476
22477   /* Help strings */
22478 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22479   foreach_vpe_api_msg;
22480 #undef _
22481
22482   /* CLI functions */
22483 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22484   foreach_cli_function;
22485 #undef _
22486
22487   /* Help strings */
22488 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22489   foreach_cli_function;
22490 #undef _
22491 }
22492
22493 #if VPP_API_TEST_BUILTIN
22494 static clib_error_t *
22495 vat_api_hookup_shim (vlib_main_t * vm)
22496 {
22497   vat_api_hookup (&vat_main);
22498   return 0;
22499 }
22500
22501 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22502 #endif
22503
22504 /*
22505  * fd.io coding-style-patch-verification: ON
22506  *
22507  * Local Variables:
22508  * eval: (c-set-style "gnu")
22509  * End:
22510  */