virtio: support virtio 1.1 packed ring in vhost
[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 <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.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 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   api_main_t *am = vlibapi_get_main ();
107   vam->socket_client_main = &socket_client_main;
108   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
109                                       "vpp_api_test",
110                                       0 /* default socket rx, tx buffer */ )))
111     return rv;
112
113   /* vpp expects the client index in network order */
114   vam->my_client_index = htonl (socket_client_main.client_index);
115   am->my_client_index = vam->my_client_index;
116   return 0;
117 }
118 #else /* vpp built-in case, we don't do sockets... */
119 int
120 vat_socket_connect (vat_main_t * vam)
121 {
122   return 0;
123 }
124
125 int
126 vl_socket_client_read (int wait)
127 {
128   return -1;
129 };
130
131 int
132 vl_socket_client_write ()
133 {
134   return -1;
135 };
136
137 void *
138 vl_socket_client_msg_alloc (int nbytes)
139 {
140   return 0;
141 }
142 #endif
143
144
145 f64
146 vat_time_now (vat_main_t * vam)
147 {
148 #if VPP_API_TEST_BUILTIN
149   return vlib_time_now (vam->vlib_main);
150 #else
151   return clib_time_now (&vam->clib_time);
152 #endif
153 }
154
155 void
156 errmsg (char *fmt, ...)
157 {
158   vat_main_t *vam = &vat_main;
159   va_list va;
160   u8 *s;
161
162   va_start (va, fmt);
163   s = va_format (0, fmt, &va);
164   va_end (va);
165
166   vec_add1 (s, 0);
167
168 #if VPP_API_TEST_BUILTIN
169   vlib_cli_output (vam->vlib_main, (char *) s);
170 #else
171   {
172     if (vam->ifp != stdin)
173       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
174                vam->input_line_number);
175     else
176       fformat (vam->ofp, "%s\n", (char *) s);
177     fflush (vam->ofp);
178   }
179 #endif
180
181   vec_free (s);
182 }
183
184 #if VPP_API_TEST_BUILTIN == 0
185 static uword
186 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
187 {
188   vat_main_t *vam = va_arg (*args, vat_main_t *);
189   u32 *result = va_arg (*args, u32 *);
190   u8 *if_name;
191   uword *p;
192
193   if (!unformat (input, "%s", &if_name))
194     return 0;
195
196   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
197   if (p == 0)
198     return 0;
199   *result = p[0];
200   return 1;
201 }
202
203 static uword
204 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
205 {
206   return 0;
207 }
208
209 /* Parse an IP4 address %d.%d.%d.%d. */
210 uword
211 unformat_ip4_address (unformat_input_t * input, va_list * args)
212 {
213   u8 *result = va_arg (*args, u8 *);
214   unsigned a[4];
215
216   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
217     return 0;
218
219   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
220     return 0;
221
222   result[0] = a[0];
223   result[1] = a[1];
224   result[2] = a[2];
225   result[3] = a[3];
226
227   return 1;
228 }
229
230 uword
231 unformat_ethernet_address (unformat_input_t * input, va_list * args)
232 {
233   u8 *result = va_arg (*args, u8 *);
234   u32 i, a[6];
235
236   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
237                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
238     return 0;
239
240   /* Check range. */
241   for (i = 0; i < 6; i++)
242     if (a[i] >= (1 << 8))
243       return 0;
244
245   for (i = 0; i < 6; i++)
246     result[i] = a[i];
247
248   return 1;
249 }
250
251 /* Returns ethernet type as an int in host byte order. */
252 uword
253 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
254                                         va_list * args)
255 {
256   u16 *result = va_arg (*args, u16 *);
257   int type;
258
259   /* Numeric type. */
260   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
261     {
262       if (type >= (1 << 16))
263         return 0;
264       *result = type;
265       return 1;
266     }
267   return 0;
268 }
269
270 /* Parse an IP46 address. */
271 uword
272 unformat_ip46_address (unformat_input_t * input, va_list * args)
273 {
274   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
275   ip46_type_t type = va_arg (*args, ip46_type_t);
276   if ((type != IP46_TYPE_IP6) &&
277       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
278     {
279       ip46_address_mask_ip4 (ip46);
280       return 1;
281     }
282   else if ((type != IP46_TYPE_IP4) &&
283            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
284     {
285       return 1;
286     }
287   return 0;
288 }
289
290 /* Parse an IP6 address. */
291 uword
292 unformat_ip6_address (unformat_input_t * input, va_list * args)
293 {
294   ip6_address_t *result = va_arg (*args, ip6_address_t *);
295   u16 hex_quads[8];
296   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
297   uword c, n_colon, double_colon_index;
298
299   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
300   double_colon_index = ARRAY_LEN (hex_quads);
301   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
302     {
303       hex_digit = 16;
304       if (c >= '0' && c <= '9')
305         hex_digit = c - '0';
306       else if (c >= 'a' && c <= 'f')
307         hex_digit = c + 10 - 'a';
308       else if (c >= 'A' && c <= 'F')
309         hex_digit = c + 10 - 'A';
310       else if (c == ':' && n_colon < 2)
311         n_colon++;
312       else
313         {
314           unformat_put_input (input);
315           break;
316         }
317
318       /* Too many hex quads. */
319       if (n_hex_quads >= ARRAY_LEN (hex_quads))
320         return 0;
321
322       if (hex_digit < 16)
323         {
324           hex_quad = (hex_quad << 4) | hex_digit;
325
326           /* Hex quad must fit in 16 bits. */
327           if (n_hex_digits >= 4)
328             return 0;
329
330           n_colon = 0;
331           n_hex_digits++;
332         }
333
334       /* Save position of :: */
335       if (n_colon == 2)
336         {
337           /* More than one :: ? */
338           if (double_colon_index < ARRAY_LEN (hex_quads))
339             return 0;
340           double_colon_index = n_hex_quads;
341         }
342
343       if (n_colon > 0 && n_hex_digits > 0)
344         {
345           hex_quads[n_hex_quads++] = hex_quad;
346           hex_quad = 0;
347           n_hex_digits = 0;
348         }
349     }
350
351   if (n_hex_digits > 0)
352     hex_quads[n_hex_quads++] = hex_quad;
353
354   {
355     word i;
356
357     /* Expand :: to appropriate number of zero hex quads. */
358     if (double_colon_index < ARRAY_LEN (hex_quads))
359       {
360         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
361
362         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
363           hex_quads[n_zero + i] = hex_quads[i];
364
365         for (i = 0; i < n_zero; i++)
366           hex_quads[double_colon_index + i] = 0;
367
368         n_hex_quads = ARRAY_LEN (hex_quads);
369       }
370
371     /* Too few hex quads given. */
372     if (n_hex_quads < ARRAY_LEN (hex_quads))
373       return 0;
374
375     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
376       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
377
378     return 1;
379   }
380 }
381
382 uword
383 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
384 {
385   u32 *r = va_arg (*args, u32 *);
386
387   if (0);
388 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
389   foreach_ipsec_policy_action
390 #undef _
391     else
392     return 0;
393   return 1;
394 }
395
396 u8 *
397 format_ipsec_crypto_alg (u8 * s, va_list * args)
398 {
399   u32 i = va_arg (*args, u32);
400   u8 *t = 0;
401
402   switch (i)
403     {
404 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
405       foreach_ipsec_crypto_alg
406 #undef _
407     default:
408       return format (s, "unknown");
409     }
410   return format (s, "%s", t);
411 }
412
413 u8 *
414 format_ipsec_integ_alg (u8 * s, va_list * args)
415 {
416   u32 i = va_arg (*args, u32);
417   u8 *t = 0;
418
419   switch (i)
420     {
421 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
422       foreach_ipsec_integ_alg
423 #undef _
424     default:
425       return format (s, "unknown");
426     }
427   return format (s, "%s", t);
428 }
429
430 #else /* VPP_API_TEST_BUILTIN == 1 */
431 static uword
432 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
433 {
434   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
435   vnet_main_t *vnm = vnet_get_main ();
436   u32 *result = va_arg (*args, u32 *);
437
438   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
439 }
440
441 static uword
442 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
443 {
444   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
445   vnet_main_t *vnm = vnet_get_main ();
446   u32 *result = va_arg (*args, u32 *);
447
448   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
449 }
450
451 #endif /* VPP_API_TEST_BUILTIN */
452
453 uword
454 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
455 {
456   u32 *r = va_arg (*args, u32 *);
457
458   if (0);
459 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
460   foreach_ipsec_crypto_alg
461 #undef _
462     else
463     return 0;
464   return 1;
465 }
466
467 uword
468 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
469 {
470   u32 *r = va_arg (*args, u32 *);
471
472   if (0);
473 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
474   foreach_ipsec_integ_alg
475 #undef _
476     else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "kbps"))
487     *r = SSE2_QOS_RATE_KBPS;
488   else if (unformat (input, "pps"))
489     *r = SSE2_QOS_RATE_PPS;
490   else
491     return 0;
492   return 1;
493 }
494
495 static uword
496 unformat_policer_round_type (unformat_input_t * input, va_list * args)
497 {
498   u8 *r = va_arg (*args, u8 *);
499
500   if (unformat (input, "closest"))
501     *r = SSE2_QOS_ROUND_TO_CLOSEST;
502   else if (unformat (input, "up"))
503     *r = SSE2_QOS_ROUND_TO_UP;
504   else if (unformat (input, "down"))
505     *r = SSE2_QOS_ROUND_TO_DOWN;
506   else
507     return 0;
508   return 1;
509 }
510
511 static uword
512 unformat_policer_type (unformat_input_t * input, va_list * args)
513 {
514   u8 *r = va_arg (*args, u8 *);
515
516   if (unformat (input, "1r2c"))
517     *r = SSE2_QOS_POLICER_TYPE_1R2C;
518   else if (unformat (input, "1r3c"))
519     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
520   else if (unformat (input, "2r3c-2698"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
522   else if (unformat (input, "2r3c-4115"))
523     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
524   else if (unformat (input, "2r3c-mef5cf1"))
525     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
526   else
527     return 0;
528   return 1;
529 }
530
531 static uword
532 unformat_dscp (unformat_input_t * input, va_list * va)
533 {
534   u8 *r = va_arg (*va, u8 *);
535
536   if (0);
537 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
538   foreach_vnet_dscp
539 #undef _
540     else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_action_type (unformat_input_t * input, va_list * va)
547 {
548   sse2_qos_pol_action_params_st *a
549     = va_arg (*va, sse2_qos_pol_action_params_st *);
550
551   if (unformat (input, "drop"))
552     a->action_type = SSE2_QOS_ACTION_DROP;
553   else if (unformat (input, "transmit"))
554     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
555   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
556     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
557   else
558     return 0;
559   return 1;
560 }
561
562 static uword
563 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
564 {
565   u32 *r = va_arg (*va, u32 *);
566   u32 tid;
567
568   if (unformat (input, "ip4"))
569     tid = POLICER_CLASSIFY_TABLE_IP4;
570   else if (unformat (input, "ip6"))
571     tid = POLICER_CLASSIFY_TABLE_IP6;
572   else if (unformat (input, "l2"))
573     tid = POLICER_CLASSIFY_TABLE_L2;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static uword
582 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
583 {
584   u32 *r = va_arg (*va, u32 *);
585   u32 tid;
586
587   if (unformat (input, "ip4"))
588     tid = FLOW_CLASSIFY_TABLE_IP4;
589   else if (unformat (input, "ip6"))
590     tid = FLOW_CLASSIFY_TABLE_IP6;
591   else
592     return 0;
593
594   *r = tid;
595   return 1;
596 }
597
598 #if (VPP_API_TEST_BUILTIN==0)
599
600 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
601 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
602 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
603 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
604
605 uword
606 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
607 {
608   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
609   mfib_itf_attribute_t attr;
610
611   old = *iflags;
612   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
613   {
614     if (unformat (input, mfib_itf_flag_long_names[attr]))
615       *iflags |= (1 << attr);
616   }
617   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
618   {
619     if (unformat (input, mfib_itf_flag_names[attr]))
620       *iflags |= (1 << attr);
621   }
622
623   return (old == *iflags ? 0 : 1);
624 }
625
626 uword
627 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
628 {
629   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
630   mfib_entry_attribute_t attr;
631
632   old = *eflags;
633   FOR_EACH_MFIB_ATTRIBUTE (attr)
634   {
635     if (unformat (input, mfib_flag_long_names[attr]))
636       *eflags |= (1 << attr);
637   }
638   FOR_EACH_MFIB_ATTRIBUTE (attr)
639   {
640     if (unformat (input, mfib_flag_names[attr]))
641       *eflags |= (1 << attr);
642   }
643
644   return (old == *eflags ? 0 : 1);
645 }
646
647 u8 *
648 format_ip4_address (u8 * s, va_list * args)
649 {
650   u8 *a = va_arg (*args, u8 *);
651   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
652 }
653
654 u8 *
655 format_ip6_address (u8 * s, va_list * args)
656 {
657   ip6_address_t *a = va_arg (*args, ip6_address_t *);
658   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
659
660   i_max_n_zero = ARRAY_LEN (a->as_u16);
661   max_n_zeros = 0;
662   i_first_zero = i_max_n_zero;
663   n_zeros = 0;
664   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
665     {
666       u32 is_zero = a->as_u16[i] == 0;
667       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
668         {
669           i_first_zero = i;
670           n_zeros = 0;
671         }
672       n_zeros += is_zero;
673       if ((!is_zero && n_zeros > max_n_zeros)
674           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
675         {
676           i_max_n_zero = i_first_zero;
677           max_n_zeros = n_zeros;
678           i_first_zero = ARRAY_LEN (a->as_u16);
679           n_zeros = 0;
680         }
681     }
682
683   last_double_colon = 0;
684   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
685     {
686       if (i == i_max_n_zero && max_n_zeros > 1)
687         {
688           s = format (s, "::");
689           i += max_n_zeros - 1;
690           last_double_colon = 1;
691         }
692       else
693         {
694           s = format (s, "%s%x",
695                       (last_double_colon || i == 0) ? "" : ":",
696                       clib_net_to_host_u16 (a->as_u16[i]));
697           last_double_colon = 0;
698         }
699     }
700
701   return s;
702 }
703
704 /* Format an IP46 address. */
705 u8 *
706 format_ip46_address (u8 * s, va_list * args)
707 {
708   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
709   ip46_type_t type = va_arg (*args, ip46_type_t);
710   int is_ip4 = 1;
711
712   switch (type)
713     {
714     case IP46_TYPE_ANY:
715       is_ip4 = ip46_address_is_ip4 (ip46);
716       break;
717     case IP46_TYPE_IP4:
718       is_ip4 = 1;
719       break;
720     case IP46_TYPE_IP6:
721       is_ip4 = 0;
722       break;
723     }
724
725   return is_ip4 ?
726     format (s, "%U", format_ip4_address, &ip46->ip4) :
727     format (s, "%U", format_ip6_address, &ip46->ip6);
728 }
729
730 u8 *
731 format_ethernet_address (u8 * s, va_list * args)
732 {
733   u8 *a = va_arg (*args, u8 *);
734
735   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
736                  a[0], a[1], a[2], a[3], a[4], a[5]);
737 }
738 #endif
739
740 static void
741 increment_v4_address (vl_api_ip4_address_t * i)
742 {
743   ip4_address_t *a = (ip4_address_t *) i;
744   u32 v;
745
746   v = ntohl (a->as_u32) + 1;
747   a->as_u32 = ntohl (v);
748 }
749
750 static void
751 increment_v6_address (vl_api_ip6_address_t * i)
752 {
753   ip6_address_t *a = (ip6_address_t *) i;
754   u64 v0, v1;
755
756   v0 = clib_net_to_host_u64 (a->as_u64[0]);
757   v1 = clib_net_to_host_u64 (a->as_u64[1]);
758
759   v1 += 1;
760   if (v1 == 0)
761     v0 += 1;
762   a->as_u64[0] = clib_net_to_host_u64 (v0);
763   a->as_u64[1] = clib_net_to_host_u64 (v1);
764 }
765
766 static void
767 increment_address (vl_api_address_t * a)
768 {
769   if (a->af == ADDRESS_IP4)
770     increment_v4_address (&a->un.ip4);
771   else if (a->af == ADDRESS_IP6)
772     increment_v6_address (&a->un.ip6);
773 }
774
775 static void
776 set_ip4_address (vl_api_address_t * a, u32 v)
777 {
778   if (a->af == ADDRESS_IP4)
779     {
780       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
781       i->as_u32 = v;
782     }
783 }
784
785 void
786 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
787 {
788   if (is_ip4)
789     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
790   else
791     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
792                       sizeof (ip6_address_t));
793 }
794
795 static void
796 increment_mac_address (u8 * mac)
797 {
798   u64 tmp = *((u64 *) mac);
799   tmp = clib_net_to_host_u64 (tmp);
800   tmp += 1 << 16;               /* skip unused (least significant) octets */
801   tmp = clib_host_to_net_u64 (tmp);
802
803   clib_memcpy (mac, &tmp, 6);
804 }
805
806 static void
807 vat_json_object_add_address (vat_json_node_t * node,
808                              const char *str, const vl_api_address_t * addr)
809 {
810   if (ADDRESS_IP6 == addr->af)
811     {
812       struct in6_addr ip6;
813
814       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
815       vat_json_object_add_ip6 (node, str, ip6);
816     }
817   else
818     {
819       struct in_addr ip4;
820
821       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
822       vat_json_object_add_ip4 (node, str, ip4);
823     }
824 }
825
826 static void
827 vat_json_object_add_prefix (vat_json_node_t * node,
828                             const vl_api_prefix_t * prefix)
829 {
830   vat_json_object_add_uint (node, "len", prefix->len);
831   vat_json_object_add_address (node, "address", &prefix->address);
832 }
833
834 static void vl_api_create_loopback_reply_t_handler
835   (vl_api_create_loopback_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   i32 retval = ntohl (mp->retval);
839
840   vam->retval = retval;
841   vam->regenerate_interface_table = 1;
842   vam->sw_if_index = ntohl (mp->sw_if_index);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_loopback_reply_t_handler_json
847   (vl_api_create_loopback_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   vat_json_node_t node;
851
852   vat_json_init_object (&node);
853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
854   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
855
856   vat_json_print (vam->ofp, &node);
857   vat_json_free (&node);
858   vam->retval = ntohl (mp->retval);
859   vam->result_ready = 1;
860 }
861
862 static void vl_api_create_loopback_instance_reply_t_handler
863   (vl_api_create_loopback_instance_reply_t * mp)
864 {
865   vat_main_t *vam = &vat_main;
866   i32 retval = ntohl (mp->retval);
867
868   vam->retval = retval;
869   vam->regenerate_interface_table = 1;
870   vam->sw_if_index = ntohl (mp->sw_if_index);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_loopback_instance_reply_t_handler_json
875   (vl_api_create_loopback_instance_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   vat_json_node_t node;
879
880   vat_json_init_object (&node);
881   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
882   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
883
884   vat_json_print (vam->ofp, &node);
885   vat_json_free (&node);
886   vam->retval = ntohl (mp->retval);
887   vam->result_ready = 1;
888 }
889
890 static void vl_api_af_packet_create_reply_t_handler
891   (vl_api_af_packet_create_reply_t * mp)
892 {
893   vat_main_t *vam = &vat_main;
894   i32 retval = ntohl (mp->retval);
895
896   vam->retval = retval;
897   vam->regenerate_interface_table = 1;
898   vam->sw_if_index = ntohl (mp->sw_if_index);
899   vam->result_ready = 1;
900 }
901
902 static void vl_api_af_packet_create_reply_t_handler_json
903   (vl_api_af_packet_create_reply_t * mp)
904 {
905   vat_main_t *vam = &vat_main;
906   vat_json_node_t node;
907
908   vat_json_init_object (&node);
909   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
910   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
911
912   vat_json_print (vam->ofp, &node);
913   vat_json_free (&node);
914
915   vam->retval = ntohl (mp->retval);
916   vam->result_ready = 1;
917 }
918
919 static void vl_api_create_vlan_subif_reply_t_handler
920   (vl_api_create_vlan_subif_reply_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   i32 retval = ntohl (mp->retval);
924
925   vam->retval = retval;
926   vam->regenerate_interface_table = 1;
927   vam->sw_if_index = ntohl (mp->sw_if_index);
928   vam->result_ready = 1;
929 }
930
931 static void vl_api_create_vlan_subif_reply_t_handler_json
932   (vl_api_create_vlan_subif_reply_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   vat_json_node_t node;
936
937   vat_json_init_object (&node);
938   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
939   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
940
941   vat_json_print (vam->ofp, &node);
942   vat_json_free (&node);
943
944   vam->retval = ntohl (mp->retval);
945   vam->result_ready = 1;
946 }
947
948 static void vl_api_create_subif_reply_t_handler
949   (vl_api_create_subif_reply_t * mp)
950 {
951   vat_main_t *vam = &vat_main;
952   i32 retval = ntohl (mp->retval);
953
954   vam->retval = retval;
955   vam->regenerate_interface_table = 1;
956   vam->sw_if_index = ntohl (mp->sw_if_index);
957   vam->result_ready = 1;
958 }
959
960 static void vl_api_create_subif_reply_t_handler_json
961   (vl_api_create_subif_reply_t * mp)
962 {
963   vat_main_t *vam = &vat_main;
964   vat_json_node_t node;
965
966   vat_json_init_object (&node);
967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
968   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
969
970   vat_json_print (vam->ofp, &node);
971   vat_json_free (&node);
972
973   vam->retval = ntohl (mp->retval);
974   vam->result_ready = 1;
975 }
976
977 static void vl_api_interface_name_renumber_reply_t_handler
978   (vl_api_interface_name_renumber_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   i32 retval = ntohl (mp->retval);
982
983   vam->retval = retval;
984   vam->regenerate_interface_table = 1;
985   vam->result_ready = 1;
986 }
987
988 static void vl_api_interface_name_renumber_reply_t_handler_json
989   (vl_api_interface_name_renumber_reply_t * mp)
990 {
991   vat_main_t *vam = &vat_main;
992   vat_json_node_t node;
993
994   vat_json_init_object (&node);
995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996
997   vat_json_print (vam->ofp, &node);
998   vat_json_free (&node);
999
1000   vam->retval = ntohl (mp->retval);
1001   vam->result_ready = 1;
1002 }
1003
1004 /*
1005  * Special-case: build the interface table, maintain
1006  * the next loopback sw_if_index vbl.
1007  */
1008 static void vl_api_sw_interface_details_t_handler
1009   (vl_api_sw_interface_details_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1013
1014   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1015                 ntohl (mp->sw_if_index));
1016
1017   /* In sub interface case, fill the sub interface table entry */
1018   if (mp->sw_if_index != mp->sup_sw_if_index)
1019     {
1020       sw_interface_subif_t *sub = NULL;
1021
1022       vec_add2 (vam->sw_if_subif_table, sub, 1);
1023
1024       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1025       strncpy ((char *) sub->interface_name, (char *) s,
1026                vec_len (sub->interface_name));
1027       sub->sw_if_index = ntohl (mp->sw_if_index);
1028       sub->sub_id = ntohl (mp->sub_id);
1029
1030       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1031
1032       sub->sub_number_of_tags = mp->sub_number_of_tags;
1033       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1034       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1035
1036       /* vlan tag rewrite */
1037       sub->vtr_op = ntohl (mp->vtr_op);
1038       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1039       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1040       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1041     }
1042 }
1043
1044 static void vl_api_sw_interface_details_t_handler_json
1045   (vl_api_sw_interface_details_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t *node = NULL;
1049
1050   if (VAT_JSON_ARRAY != vam->json_tree.type)
1051     {
1052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1053       vat_json_init_array (&vam->json_tree);
1054     }
1055   node = vat_json_array_add (&vam->json_tree);
1056
1057   vat_json_init_object (node);
1058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1059   vat_json_object_add_uint (node, "sup_sw_if_index",
1060                             ntohl (mp->sup_sw_if_index));
1061   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1062                              sizeof (mp->l2_address));
1063   vat_json_object_add_string_copy (node, "interface_name",
1064                                    mp->interface_name);
1065   vat_json_object_add_string_copy (node, "interface_dev_type",
1066                                    mp->interface_dev_type);
1067   vat_json_object_add_uint (node, "flags", mp->flags);
1068   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1069   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1070   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1071   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1072   vat_json_object_add_uint (node, "sub_number_of_tags",
1073                             mp->sub_number_of_tags);
1074   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1075                             ntohs (mp->sub_outer_vlan_id));
1076   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1077                             ntohs (mp->sub_inner_vlan_id));
1078   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1079   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1080   vat_json_object_add_uint (node, "vtr_push_dot1q",
1081                             ntohl (mp->vtr_push_dot1q));
1082   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1083   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1084   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1085     {
1086       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1087                                        format (0, "%U",
1088                                                format_ethernet_address,
1089                                                &mp->b_dmac));
1090       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1091                                        format (0, "%U",
1092                                                format_ethernet_address,
1093                                                &mp->b_smac));
1094       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1095       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1096     }
1097 }
1098
1099 #if VPP_API_TEST_BUILTIN == 0
1100 static void vl_api_sw_interface_event_t_handler
1101   (vl_api_sw_interface_event_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   if (vam->interface_event_display)
1105     errmsg ("interface flags: sw_if_index %d %s %s",
1106             ntohl (mp->sw_if_index),
1107             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1108             "admin-up" : "admin-down",
1109             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1110             "link-up" : "link-down");
1111 }
1112 #endif
1113
1114 __clib_unused static void
1115 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1116 {
1117   /* JSON output not supported */
1118 }
1119
1120 static void
1121 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1122 {
1123   vat_main_t *vam = &vat_main;
1124   i32 retval = ntohl (mp->retval);
1125
1126   vam->retval = retval;
1127   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1128   vam->result_ready = 1;
1129 }
1130
1131 static void
1132 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136   void *oldheap;
1137   u8 *reply;
1138
1139   vat_json_init_object (&node);
1140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1141   vat_json_object_add_uint (&node, "reply_in_shmem",
1142                             ntohl (mp->reply_in_shmem));
1143   /* Toss the shared-memory original... */
1144   oldheap = vl_msg_push_heap ();
1145
1146   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1147   vec_free (reply);
1148
1149   vl_msg_pop_heap (oldheap);
1150
1151   vat_json_print (vam->ofp, &node);
1152   vat_json_free (&node);
1153
1154   vam->retval = ntohl (mp->retval);
1155   vam->result_ready = 1;
1156 }
1157
1158 static void
1159 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1160 {
1161   vat_main_t *vam = &vat_main;
1162   i32 retval = ntohl (mp->retval);
1163
1164   vec_reset_length (vam->cmd_reply);
1165
1166   vam->retval = retval;
1167   if (retval == 0)
1168     vam->cmd_reply = vl_api_from_api_to_new_vec (&mp->reply);
1169   vam->result_ready = 1;
1170 }
1171
1172 static void
1173 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177   u8 *reply = 0;                /* reply vector */
1178
1179   reply = vl_api_from_api_to_new_vec (&mp->reply);
1180   vec_reset_length (vam->cmd_reply);
1181
1182   vat_json_init_object (&node);
1183   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184   vat_json_object_add_string_copy (&node, "reply", reply);
1185
1186   vat_json_print (vam->ofp, &node);
1187   vat_json_free (&node);
1188   vec_free (reply);
1189
1190   vam->retval = ntohl (mp->retval);
1191   vam->result_ready = 1;
1192 }
1193
1194 static void vl_api_classify_add_del_table_reply_t_handler
1195   (vl_api_classify_add_del_table_reply_t * mp)
1196 {
1197   vat_main_t *vam = &vat_main;
1198   i32 retval = ntohl (mp->retval);
1199   if (vam->async_mode)
1200     {
1201       vam->async_errors += (retval < 0);
1202     }
1203   else
1204     {
1205       vam->retval = retval;
1206       if (retval == 0 &&
1207           ((mp->new_table_index != 0xFFFFFFFF) ||
1208            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1209            (mp->match_n_vectors != 0xFFFFFFFF)))
1210         /*
1211          * Note: this is just barely thread-safe, depends on
1212          * the main thread spinning waiting for an answer...
1213          */
1214         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1215                 ntohl (mp->new_table_index),
1216                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1217       vam->result_ready = 1;
1218     }
1219 }
1220
1221 static void vl_api_classify_add_del_table_reply_t_handler_json
1222   (vl_api_classify_add_del_table_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   vat_json_node_t node;
1226
1227   vat_json_init_object (&node);
1228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1229   vat_json_object_add_uint (&node, "new_table_index",
1230                             ntohl (mp->new_table_index));
1231   vat_json_object_add_uint (&node, "skip_n_vectors",
1232                             ntohl (mp->skip_n_vectors));
1233   vat_json_object_add_uint (&node, "match_n_vectors",
1234                             ntohl (mp->match_n_vectors));
1235
1236   vat_json_print (vam->ofp, &node);
1237   vat_json_free (&node);
1238
1239   vam->retval = ntohl (mp->retval);
1240   vam->result_ready = 1;
1241 }
1242
1243 static void vl_api_get_node_index_reply_t_handler
1244   (vl_api_get_node_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   i32 retval = ntohl (mp->retval);
1248   if (vam->async_mode)
1249     {
1250       vam->async_errors += (retval < 0);
1251     }
1252   else
1253     {
1254       vam->retval = retval;
1255       if (retval == 0)
1256         errmsg ("node index %d", ntohl (mp->node_index));
1257       vam->result_ready = 1;
1258     }
1259 }
1260
1261 static void vl_api_get_node_index_reply_t_handler_json
1262   (vl_api_get_node_index_reply_t * mp)
1263 {
1264   vat_main_t *vam = &vat_main;
1265   vat_json_node_t node;
1266
1267   vat_json_init_object (&node);
1268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1269   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1270
1271   vat_json_print (vam->ofp, &node);
1272   vat_json_free (&node);
1273
1274   vam->retval = ntohl (mp->retval);
1275   vam->result_ready = 1;
1276 }
1277
1278 static void vl_api_get_next_index_reply_t_handler
1279   (vl_api_get_next_index_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       if (retval == 0)
1291         errmsg ("next node index %d", ntohl (mp->next_index));
1292       vam->result_ready = 1;
1293     }
1294 }
1295
1296 static void vl_api_get_next_index_reply_t_handler_json
1297   (vl_api_get_next_index_reply_t * mp)
1298 {
1299   vat_main_t *vam = &vat_main;
1300   vat_json_node_t node;
1301
1302   vat_json_init_object (&node);
1303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1304   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1305
1306   vat_json_print (vam->ofp, &node);
1307   vat_json_free (&node);
1308
1309   vam->retval = ntohl (mp->retval);
1310   vam->result_ready = 1;
1311 }
1312
1313 static void vl_api_add_node_next_reply_t_handler
1314   (vl_api_add_node_next_reply_t * mp)
1315 {
1316   vat_main_t *vam = &vat_main;
1317   i32 retval = ntohl (mp->retval);
1318   if (vam->async_mode)
1319     {
1320       vam->async_errors += (retval < 0);
1321     }
1322   else
1323     {
1324       vam->retval = retval;
1325       if (retval == 0)
1326         errmsg ("next index %d", ntohl (mp->next_index));
1327       vam->result_ready = 1;
1328     }
1329 }
1330
1331 static void vl_api_add_node_next_reply_t_handler_json
1332   (vl_api_add_node_next_reply_t * mp)
1333 {
1334   vat_main_t *vam = &vat_main;
1335   vat_json_node_t node;
1336
1337   vat_json_init_object (&node);
1338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1339   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1340
1341   vat_json_print (vam->ofp, &node);
1342   vat_json_free (&node);
1343
1344   vam->retval = ntohl (mp->retval);
1345   vam->result_ready = 1;
1346 }
1347
1348 static void vl_api_show_version_reply_t_handler
1349   (vl_api_show_version_reply_t * mp)
1350 {
1351   vat_main_t *vam = &vat_main;
1352   i32 retval = ntohl (mp->retval);
1353
1354   if (retval >= 0)
1355     {
1356       errmsg ("        program: %s", mp->program);
1357       errmsg ("        version: %s", mp->version);
1358       errmsg ("     build date: %s", mp->build_date);
1359       errmsg ("build directory: %s", mp->build_directory);
1360     }
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void vl_api_show_version_reply_t_handler_json
1366   (vl_api_show_version_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t node;
1370
1371   vat_json_init_object (&node);
1372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1373   vat_json_object_add_string_copy (&node, "program", mp->program);
1374   vat_json_object_add_string_copy (&node, "version", mp->version);
1375   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1376   vat_json_object_add_string_copy (&node, "build_directory",
1377                                    mp->build_directory);
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_show_threads_reply_t_handler
1387   (vl_api_show_threads_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   int i, count = 0;
1392
1393   if (retval >= 0)
1394     count = ntohl (mp->count);
1395
1396   for (i = 0; i < count; i++)
1397     print (vam->ofp,
1398            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1399            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1400            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1401            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1402            ntohl (mp->thread_data[i].cpu_socket));
1403
1404   vam->retval = retval;
1405   vam->result_ready = 1;
1406 }
1407
1408 static void vl_api_show_threads_reply_t_handler_json
1409   (vl_api_show_threads_reply_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t node;
1413   vl_api_thread_data_t *td;
1414   i32 retval = ntohl (mp->retval);
1415   int i, count = 0;
1416
1417   if (retval >= 0)
1418     count = ntohl (mp->count);
1419
1420   vat_json_init_object (&node);
1421   vat_json_object_add_int (&node, "retval", retval);
1422   vat_json_object_add_uint (&node, "count", count);
1423
1424   for (i = 0; i < count; i++)
1425     {
1426       td = &mp->thread_data[i];
1427       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1428       vat_json_object_add_string_copy (&node, "name", td->name);
1429       vat_json_object_add_string_copy (&node, "type", td->type);
1430       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1431       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1432       vat_json_object_add_int (&node, "core", ntohl (td->id));
1433       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1434     }
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = retval;
1440   vam->result_ready = 1;
1441 }
1442
1443 static int
1444 api_show_threads (vat_main_t * vam)
1445 {
1446   vl_api_show_threads_t *mp;
1447   int ret;
1448
1449   print (vam->ofp,
1450          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1451          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1452
1453   M (SHOW_THREADS, mp);
1454
1455   S (mp);
1456   W (ret);
1457   return ret;
1458 }
1459
1460 static void
1461 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1462 {
1463   u32 n_macs = ntohl (mp->n_macs);
1464   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1465           ntohl (mp->pid), mp->client_index, n_macs);
1466   int i;
1467   for (i = 0; i < n_macs; i++)
1468     {
1469       vl_api_mac_entry_t *mac = &mp->mac[i];
1470       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1471               i + 1, ntohl (mac->sw_if_index),
1472               format_ethernet_address, mac->mac_addr, mac->action);
1473       if (i == 1000)
1474         break;
1475     }
1476 }
1477
1478 static void
1479 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1480 {
1481   /* JSON output not supported */
1482 }
1483
1484 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1485 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1486
1487 /*
1488  * Special-case: build the bridge domain table, maintain
1489  * the next bd id vbl.
1490  */
1491 static void vl_api_bridge_domain_details_t_handler
1492   (vl_api_bridge_domain_details_t * mp)
1493 {
1494   vat_main_t *vam = &vat_main;
1495   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1496   int i;
1497
1498   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1499          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1500
1501   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1502          ntohl (mp->bd_id), mp->learn, mp->forward,
1503          mp->flood, ntohl (mp->bvi_sw_if_index),
1504          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1505
1506   if (n_sw_ifs)
1507     {
1508       vl_api_bridge_domain_sw_if_t *sw_ifs;
1509       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1510              "Interface Name");
1511
1512       sw_ifs = mp->sw_if_details;
1513       for (i = 0; i < n_sw_ifs; i++)
1514         {
1515           u8 *sw_if_name = 0;
1516           u32 sw_if_index;
1517           hash_pair_t *p;
1518
1519           sw_if_index = ntohl (sw_ifs->sw_if_index);
1520
1521           /* *INDENT-OFF* */
1522           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1523                              ({
1524                                if ((u32) p->value[0] == sw_if_index)
1525                                  {
1526                                    sw_if_name = (u8 *)(p->key);
1527                                    break;
1528                                  }
1529                              }));
1530           /* *INDENT-ON* */
1531           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1532                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1533                  "sw_if_index not found!");
1534
1535           sw_ifs++;
1536         }
1537     }
1538 }
1539
1540 static void vl_api_bridge_domain_details_t_handler_json
1541   (vl_api_bridge_domain_details_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   vat_json_node_t *node, *array = NULL;
1545   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1546
1547   if (VAT_JSON_ARRAY != vam->json_tree.type)
1548     {
1549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1550       vat_json_init_array (&vam->json_tree);
1551     }
1552   node = vat_json_array_add (&vam->json_tree);
1553
1554   vat_json_init_object (node);
1555   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1556   vat_json_object_add_uint (node, "flood", mp->flood);
1557   vat_json_object_add_uint (node, "forward", mp->forward);
1558   vat_json_object_add_uint (node, "learn", mp->learn);
1559   vat_json_object_add_uint (node, "bvi_sw_if_index",
1560                             ntohl (mp->bvi_sw_if_index));
1561   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1562   array = vat_json_object_add (node, "sw_if");
1563   vat_json_init_array (array);
1564
1565
1566
1567   if (n_sw_ifs)
1568     {
1569       vl_api_bridge_domain_sw_if_t *sw_ifs;
1570       int i;
1571
1572       sw_ifs = mp->sw_if_details;
1573       for (i = 0; i < n_sw_ifs; i++)
1574         {
1575           node = vat_json_array_add (array);
1576           vat_json_init_object (node);
1577           vat_json_object_add_uint (node, "sw_if_index",
1578                                     ntohl (sw_ifs->sw_if_index));
1579           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1580           sw_ifs++;
1581         }
1582     }
1583 }
1584
1585 static void vl_api_control_ping_reply_t_handler
1586   (vl_api_control_ping_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   i32 retval = ntohl (mp->retval);
1590   if (vam->async_mode)
1591     {
1592       vam->async_errors += (retval < 0);
1593     }
1594   else
1595     {
1596       vam->retval = retval;
1597       vam->result_ready = 1;
1598     }
1599   if (vam->socket_client_main)
1600     vam->socket_client_main->control_pings_outstanding--;
1601 }
1602
1603 static void vl_api_control_ping_reply_t_handler_json
1604   (vl_api_control_ping_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608
1609   if (VAT_JSON_NONE != vam->json_tree.type)
1610     {
1611       vat_json_print (vam->ofp, &vam->json_tree);
1612       vat_json_free (&vam->json_tree);
1613       vam->json_tree.type = VAT_JSON_NONE;
1614     }
1615   else
1616     {
1617       /* just print [] */
1618       vat_json_init_array (&vam->json_tree);
1619       vat_json_print (vam->ofp, &vam->json_tree);
1620       vam->json_tree.type = VAT_JSON_NONE;
1621     }
1622
1623   vam->retval = retval;
1624   vam->result_ready = 1;
1625 }
1626
1627 static void
1628   vl_api_bridge_domain_set_mac_age_reply_t_handler
1629   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642 }
1643
1644 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1645   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   vat_json_node_t node;
1649
1650   vat_json_init_object (&node);
1651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void
1661 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_l2_flags_reply_t_handler_json
1677   (vl_api_l2_flags_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1685                             ntohl (mp->resulting_feature_bitmap));
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 vl_api_bridge_flags_reply_t_handler
1695   (vl_api_bridge_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_bridge_flags_reply_t_handler_json
1711   (vl_api_bridge_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
1729 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_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->sw_if_index = ntohl (mp->sw_if_index);
1741       vam->result_ready = 1;
1742     }
1743
1744 }
1745
1746 static void vl_api_tap_create_v2_reply_t_handler_json
1747   (vl_api_tap_create_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   vat_json_node_t node;
1751
1752   vat_json_init_object (&node);
1753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1754   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1755
1756   vat_json_print (vam->ofp, &node);
1757   vat_json_free (&node);
1758
1759   vam->retval = ntohl (mp->retval);
1760   vam->result_ready = 1;
1761
1762 }
1763
1764 static void
1765 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_tap_delete_v2_reply_t_handler_json
1781   (vl_api_tap_delete_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
1789   vat_json_print (vam->ofp, &node);
1790   vat_json_free (&node);
1791
1792   vam->retval = ntohl (mp->retval);
1793   vam->result_ready = 1;
1794 }
1795
1796 static void
1797 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1798                                           mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   i32 retval = ntohl (mp->retval);
1802   if (vam->async_mode)
1803     {
1804       vam->async_errors += (retval < 0);
1805     }
1806   else
1807     {
1808       vam->retval = retval;
1809       vam->sw_if_index = ntohl (mp->sw_if_index);
1810       vam->result_ready = 1;
1811     }
1812 }
1813
1814 static void vl_api_virtio_pci_create_reply_t_handler_json
1815   (vl_api_virtio_pci_create_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1823
1824   vat_json_print (vam->ofp, &node);
1825   vat_json_free (&node);
1826
1827   vam->retval = ntohl (mp->retval);
1828   vam->result_ready = 1;
1829
1830 }
1831
1832 static void
1833 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1834                                           mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_virtio_pci_delete_reply_t_handler_json
1850   (vl_api_virtio_pci_delete_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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 static void
1866 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   i32 retval = ntohl (mp->retval);
1870
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->sw_if_index = ntohl (mp->sw_if_index);
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_bond_create_reply_t_handler_json
1884   (vl_api_bond_create_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void
1901 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   i32 retval = ntohl (mp->retval);
1905
1906   if (vam->async_mode)
1907     {
1908       vam->async_errors += (retval < 0);
1909     }
1910   else
1911     {
1912       vam->retval = retval;
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_delete_reply_t_handler_json
1918   (vl_api_bond_delete_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
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   i32 retval = ntohl (mp->retval);
1938
1939   if (vam->async_mode)
1940     {
1941       vam->async_errors += (retval < 0);
1942     }
1943   else
1944     {
1945       vam->retval = retval;
1946       vam->result_ready = 1;
1947     }
1948 }
1949
1950 static void vl_api_bond_enslave_reply_t_handler_json
1951   (vl_api_bond_enslave_reply_t * mp)
1952 {
1953   vat_main_t *vam = &vat_main;
1954   vat_json_node_t node;
1955
1956   vat_json_init_object (&node);
1957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958
1959   vat_json_print (vam->ofp, &node);
1960   vat_json_free (&node);
1961
1962   vam->retval = ntohl (mp->retval);
1963   vam->result_ready = 1;
1964 }
1965
1966 static void
1967 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1968                                           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_detach_slave_reply_t_handler_json
1985   (vl_api_bond_detach_slave_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 int
2001 api_sw_interface_set_bond_weight (vat_main_t * vam)
2002 {
2003   unformat_input_t *i = vam->input;
2004   vl_api_sw_interface_set_bond_weight_t *mp;
2005   u32 sw_if_index = ~0;
2006   u32 weight = 0;
2007   u8 weight_enter = 0;
2008   int ret;
2009
2010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2011     {
2012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2013         ;
2014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2015         ;
2016       else if (unformat (i, "weight %u", &weight))
2017         weight_enter = 1;
2018       else
2019         break;
2020     }
2021
2022   if (sw_if_index == ~0)
2023     {
2024       errmsg ("missing interface name or sw_if_index");
2025       return -99;
2026     }
2027   if (weight_enter == 0)
2028     {
2029       errmsg ("missing valid weight");
2030       return -99;
2031     }
2032
2033   /* Construct the API message */
2034   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2035   mp->sw_if_index = ntohl (sw_if_index);
2036   mp->weight = ntohl (weight);
2037
2038   S (mp);
2039   W (ret);
2040   return ret;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2052          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2073   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2110          ntohl (mp->weight), mp->is_local_numa);
2111 }
2112
2113 static void vl_api_sw_interface_slave_details_t_handler_json
2114   (vl_api_sw_interface_slave_details_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   vat_json_node_t *node = NULL;
2118
2119   if (VAT_JSON_ARRAY != vam->json_tree.type)
2120     {
2121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2122       vat_json_init_array (&vam->json_tree);
2123     }
2124   node = vat_json_array_add (&vam->json_tree);
2125
2126   vat_json_init_object (node);
2127   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2128   vat_json_object_add_string_copy (node, "interface_name",
2129                                    mp->interface_name);
2130   vat_json_object_add_uint (node, "passive", mp->is_passive);
2131   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2132   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2133   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2134 }
2135
2136 static int
2137 api_sw_interface_slave_dump (vat_main_t * vam)
2138 {
2139   unformat_input_t *i = vam->input;
2140   vl_api_sw_interface_slave_dump_t *mp;
2141   vl_api_control_ping_t *mp_ping;
2142   u32 sw_if_index = ~0;
2143   u8 sw_if_index_set = 0;
2144   int ret;
2145
2146   /* Parse args required to build the message */
2147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2148     {
2149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2150         sw_if_index_set = 1;
2151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2152         sw_if_index_set = 1;
2153       else
2154         break;
2155     }
2156
2157   if (sw_if_index_set == 0)
2158     {
2159       errmsg ("missing vpp interface name. ");
2160       return -99;
2161     }
2162
2163   print (vam->ofp,
2164          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2165          "slave interface name", "sw_if_index", "passive", "long_timeout",
2166          "weight", "local numa");
2167
2168   /* Get list of bond interfaces */
2169   M (SW_INTERFACE_SLAVE_DUMP, mp);
2170   mp->sw_if_index = ntohl (sw_if_index);
2171   S (mp);
2172
2173   /* Use a control ping for synchronization */
2174   MPING (CONTROL_PING, mp_ping);
2175   S (mp_ping);
2176
2177   W (ret);
2178   return ret;
2179 }
2180
2181 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2182   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->sw_if_index = ntohl (mp->sw_if_index);
2194       vam->result_ready = 1;
2195     }
2196   vam->regenerate_interface_table = 1;
2197 }
2198
2199 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2200   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204
2205   vat_json_init_object (&node);
2206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2207   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2208                             ntohl (mp->sw_if_index));
2209
2210   vat_json_print (vam->ofp, &node);
2211   vat_json_free (&node);
2212
2213   vam->retval = ntohl (mp->retval);
2214   vam->result_ready = 1;
2215 }
2216
2217 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2218   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2219 {
2220   vat_main_t *vam = &vat_main;
2221   i32 retval = ntohl (mp->retval);
2222   if (vam->async_mode)
2223     {
2224       vam->async_errors += (retval < 0);
2225     }
2226   else
2227     {
2228       vam->retval = retval;
2229       vam->sw_if_index = ntohl (mp->sw_if_index);
2230       vam->result_ready = 1;
2231     }
2232 }
2233
2234 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2235   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2236 {
2237   vat_main_t *vam = &vat_main;
2238   vat_json_node_t node;
2239
2240   vat_json_init_object (&node);
2241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2242   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2252   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2253 {
2254   vat_main_t *vam = &vat_main;
2255   i32 retval = ntohl (mp->retval);
2256   if (vam->async_mode)
2257     {
2258       vam->async_errors += (retval < 0);
2259     }
2260   else
2261     {
2262       vam->retval = retval;
2263       vam->result_ready = 1;
2264     }
2265 }
2266
2267 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2268   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2269 {
2270   vat_main_t *vam = &vat_main;
2271   vat_json_node_t node;
2272
2273   vat_json_init_object (&node);
2274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2275   vat_json_object_add_uint (&node, "fwd_entry_index",
2276                             clib_net_to_host_u32 (mp->fwd_entry_index));
2277
2278   vat_json_print (vam->ofp, &node);
2279   vat_json_free (&node);
2280
2281   vam->retval = ntohl (mp->retval);
2282   vam->result_ready = 1;
2283 }
2284
2285 u8 *
2286 format_lisp_transport_protocol (u8 * s, va_list * args)
2287 {
2288   u32 proto = va_arg (*args, u32);
2289
2290   switch (proto)
2291     {
2292     case 1:
2293       return format (s, "udp");
2294     case 2:
2295       return format (s, "api");
2296     default:
2297       return 0;
2298     }
2299   return 0;
2300 }
2301
2302 static void vl_api_one_get_transport_protocol_reply_t_handler
2303   (vl_api_one_get_transport_protocol_reply_t * mp)
2304 {
2305   vat_main_t *vam = &vat_main;
2306   i32 retval = ntohl (mp->retval);
2307   if (vam->async_mode)
2308     {
2309       vam->async_errors += (retval < 0);
2310     }
2311   else
2312     {
2313       u32 proto = mp->protocol;
2314       print (vam->ofp, "Transport protocol: %U",
2315              format_lisp_transport_protocol, proto);
2316       vam->retval = retval;
2317       vam->result_ready = 1;
2318     }
2319 }
2320
2321 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2322   (vl_api_one_get_transport_protocol_reply_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   vat_json_node_t node;
2326   u8 *s;
2327
2328   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2329   vec_add1 (s, 0);
2330
2331   vat_json_init_object (&node);
2332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2333   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2334
2335   vec_free (s);
2336   vat_json_print (vam->ofp, &node);
2337   vat_json_free (&node);
2338
2339   vam->retval = ntohl (mp->retval);
2340   vam->result_ready = 1;
2341 }
2342
2343 static void vl_api_one_add_del_locator_set_reply_t_handler
2344   (vl_api_one_add_del_locator_set_reply_t * mp)
2345 {
2346   vat_main_t *vam = &vat_main;
2347   i32 retval = ntohl (mp->retval);
2348   if (vam->async_mode)
2349     {
2350       vam->async_errors += (retval < 0);
2351     }
2352   else
2353     {
2354       vam->retval = retval;
2355       vam->result_ready = 1;
2356     }
2357 }
2358
2359 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2360   (vl_api_one_add_del_locator_set_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   vat_json_node_t node;
2364
2365   vat_json_init_object (&node);
2366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2367   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2368
2369   vat_json_print (vam->ofp, &node);
2370   vat_json_free (&node);
2371
2372   vam->retval = ntohl (mp->retval);
2373   vam->result_ready = 1;
2374 }
2375
2376 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2377   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   i32 retval = ntohl (mp->retval);
2381   if (vam->async_mode)
2382     {
2383       vam->async_errors += (retval < 0);
2384     }
2385   else
2386     {
2387       vam->retval = retval;
2388       vam->sw_if_index = ntohl (mp->sw_if_index);
2389       vam->result_ready = 1;
2390     }
2391   vam->regenerate_interface_table = 1;
2392 }
2393
2394 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2395   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2396 {
2397   vat_main_t *vam = &vat_main;
2398   vat_json_node_t node;
2399
2400   vat_json_init_object (&node);
2401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2403
2404   vat_json_print (vam->ofp, &node);
2405   vat_json_free (&node);
2406
2407   vam->retval = ntohl (mp->retval);
2408   vam->result_ready = 1;
2409 }
2410
2411 static void vl_api_vxlan_offload_rx_reply_t_handler
2412   (vl_api_vxlan_offload_rx_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416   if (vam->async_mode)
2417     {
2418       vam->async_errors += (retval < 0);
2419     }
2420   else
2421     {
2422       vam->retval = retval;
2423       vam->result_ready = 1;
2424     }
2425 }
2426
2427 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2428   (vl_api_vxlan_offload_rx_reply_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t node;
2432
2433   vat_json_init_object (&node);
2434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2435
2436   vat_json_print (vam->ofp, &node);
2437   vat_json_free (&node);
2438
2439   vam->retval = ntohl (mp->retval);
2440   vam->result_ready = 1;
2441 }
2442
2443 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2444   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447   i32 retval = ntohl (mp->retval);
2448   if (vam->async_mode)
2449     {
2450       vam->async_errors += (retval < 0);
2451     }
2452   else
2453     {
2454       vam->retval = retval;
2455       vam->sw_if_index = ntohl (mp->sw_if_index);
2456       vam->result_ready = 1;
2457     }
2458 }
2459
2460 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2461   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   vat_json_node_t node;
2465
2466   vat_json_init_object (&node);
2467   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2478   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   i32 retval = ntohl (mp->retval);
2482   if (vam->async_mode)
2483     {
2484       vam->async_errors += (retval < 0);
2485     }
2486   else
2487     {
2488       vam->retval = retval;
2489       vam->sw_if_index = ntohl (mp->sw_if_index);
2490       vam->result_ready = 1;
2491     }
2492   vam->regenerate_interface_table = 1;
2493 }
2494
2495 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2496   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t node;
2500
2501   vat_json_init_object (&node);
2502   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2503   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2504
2505   vat_json_print (vam->ofp, &node);
2506   vat_json_free (&node);
2507
2508   vam->retval = ntohl (mp->retval);
2509   vam->result_ready = 1;
2510 }
2511
2512 static void vl_api_gre_tunnel_add_del_reply_t_handler
2513   (vl_api_gre_tunnel_add_del_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   i32 retval = ntohl (mp->retval);
2517   if (vam->async_mode)
2518     {
2519       vam->async_errors += (retval < 0);
2520     }
2521   else
2522     {
2523       vam->retval = retval;
2524       vam->sw_if_index = ntohl (mp->sw_if_index);
2525       vam->result_ready = 1;
2526     }
2527 }
2528
2529 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2530   (vl_api_gre_tunnel_add_del_reply_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t node;
2534
2535   vat_json_init_object (&node);
2536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2537   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2538
2539   vat_json_print (vam->ofp, &node);
2540   vat_json_free (&node);
2541
2542   vam->retval = ntohl (mp->retval);
2543   vam->result_ready = 1;
2544 }
2545
2546 static void vl_api_create_vhost_user_if_reply_t_handler
2547   (vl_api_create_vhost_user_if_reply_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   i32 retval = ntohl (mp->retval);
2551   if (vam->async_mode)
2552     {
2553       vam->async_errors += (retval < 0);
2554     }
2555   else
2556     {
2557       vam->retval = retval;
2558       vam->sw_if_index = ntohl (mp->sw_if_index);
2559       vam->result_ready = 1;
2560     }
2561   vam->regenerate_interface_table = 1;
2562 }
2563
2564 static void vl_api_create_vhost_user_if_reply_t_handler_json
2565   (vl_api_create_vhost_user_if_reply_t * mp)
2566 {
2567   vat_main_t *vam = &vat_main;
2568   vat_json_node_t node;
2569
2570   vat_json_init_object (&node);
2571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2572   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2573
2574   vat_json_print (vam->ofp, &node);
2575   vat_json_free (&node);
2576
2577   vam->retval = ntohl (mp->retval);
2578   vam->result_ready = 1;
2579 }
2580
2581 static void vl_api_ip_address_details_t_handler
2582   (vl_api_ip_address_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   static ip_address_details_t empty_ip_address_details = { {0} };
2586   ip_address_details_t *address = NULL;
2587   ip_details_t *current_ip_details = NULL;
2588   ip_details_t *details = NULL;
2589
2590   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2591
2592   if (!details || vam->current_sw_if_index >= vec_len (details)
2593       || !details[vam->current_sw_if_index].present)
2594     {
2595       errmsg ("ip address details arrived but not stored");
2596       errmsg ("ip_dump should be called first");
2597       return;
2598     }
2599
2600   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2601
2602 #define addresses (current_ip_details->addr)
2603
2604   vec_validate_init_empty (addresses, vec_len (addresses),
2605                            empty_ip_address_details);
2606
2607   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2608
2609   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2610   address->prefix_length = mp->prefix.len;
2611 #undef addresses
2612 }
2613
2614 static void vl_api_ip_address_details_t_handler_json
2615   (vl_api_ip_address_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618   vat_json_node_t *node = NULL;
2619
2620   if (VAT_JSON_ARRAY != vam->json_tree.type)
2621     {
2622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2623       vat_json_init_array (&vam->json_tree);
2624     }
2625   node = vat_json_array_add (&vam->json_tree);
2626
2627   vat_json_init_object (node);
2628   vat_json_object_add_prefix (node, &mp->prefix);
2629 }
2630
2631 static void
2632 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2633 {
2634   vat_main_t *vam = &vat_main;
2635   static ip_details_t empty_ip_details = { 0 };
2636   ip_details_t *ip = NULL;
2637   u32 sw_if_index = ~0;
2638
2639   sw_if_index = ntohl (mp->sw_if_index);
2640
2641   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2642                            sw_if_index, empty_ip_details);
2643
2644   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2645                          sw_if_index);
2646
2647   ip->present = 1;
2648 }
2649
2650 static void
2651 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2652 {
2653   vat_main_t *vam = &vat_main;
2654
2655   if (VAT_JSON_ARRAY != vam->json_tree.type)
2656     {
2657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2658       vat_json_init_array (&vam->json_tree);
2659     }
2660   vat_json_array_add_uint (&vam->json_tree,
2661                            clib_net_to_host_u32 (mp->sw_if_index));
2662 }
2663
2664 static void vl_api_get_first_msg_id_reply_t_handler
2665   (vl_api_get_first_msg_id_reply_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   i32 retval = ntohl (mp->retval);
2669
2670   if (vam->async_mode)
2671     {
2672       vam->async_errors += (retval < 0);
2673     }
2674   else
2675     {
2676       vam->retval = retval;
2677       vam->result_ready = 1;
2678     }
2679   if (retval >= 0)
2680     {
2681       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2682     }
2683 }
2684
2685 static void vl_api_get_first_msg_id_reply_t_handler_json
2686   (vl_api_get_first_msg_id_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   vat_json_node_t node;
2690
2691   vat_json_init_object (&node);
2692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2693   vat_json_object_add_uint (&node, "first_msg_id",
2694                             (uint) ntohs (mp->first_msg_id));
2695
2696   vat_json_print (vam->ofp, &node);
2697   vat_json_free (&node);
2698
2699   vam->retval = ntohl (mp->retval);
2700   vam->result_ready = 1;
2701 }
2702
2703 static void vl_api_get_node_graph_reply_t_handler
2704   (vl_api_get_node_graph_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   i32 retval = ntohl (mp->retval);
2708   u8 *pvt_copy, *reply;
2709   void *oldheap;
2710   vlib_node_t *node;
2711   int i;
2712
2713   if (vam->async_mode)
2714     {
2715       vam->async_errors += (retval < 0);
2716     }
2717   else
2718     {
2719       vam->retval = retval;
2720       vam->result_ready = 1;
2721     }
2722
2723   /* "Should never happen..." */
2724   if (retval != 0)
2725     return;
2726
2727   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2728   pvt_copy = vec_dup (reply);
2729
2730   /* Toss the shared-memory original... */
2731   oldheap = vl_msg_push_heap ();
2732
2733   vec_free (reply);
2734
2735   vl_msg_pop_heap (oldheap);
2736
2737   if (vam->graph_nodes)
2738     {
2739       hash_free (vam->graph_node_index_by_name);
2740
2741       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2742         {
2743           node = vam->graph_nodes[0][i];
2744           vec_free (node->name);
2745           vec_free (node->next_nodes);
2746           vec_free (node);
2747         }
2748       vec_free (vam->graph_nodes[0]);
2749       vec_free (vam->graph_nodes);
2750     }
2751
2752   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2753   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2754   vec_free (pvt_copy);
2755
2756   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2757     {
2758       node = vam->graph_nodes[0][i];
2759       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2760     }
2761 }
2762
2763 static void vl_api_get_node_graph_reply_t_handler_json
2764   (vl_api_get_node_graph_reply_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   void *oldheap;
2768   vat_json_node_t node;
2769   u8 *reply;
2770
2771   /* $$$$ make this real? */
2772   vat_json_init_object (&node);
2773   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2774   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2775
2776   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2777
2778   /* Toss the shared-memory original... */
2779   oldheap = vl_msg_push_heap ();
2780
2781   vec_free (reply);
2782
2783   vl_msg_pop_heap (oldheap);
2784
2785   vat_json_print (vam->ofp, &node);
2786   vat_json_free (&node);
2787
2788   vam->retval = ntohl (mp->retval);
2789   vam->result_ready = 1;
2790 }
2791
2792 static void
2793 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   u8 *s = 0;
2797
2798   if (mp->local)
2799     {
2800       s = format (s, "%=16d%=16d%=16d",
2801                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2802     }
2803   else
2804     {
2805       s = format (s, "%=16U%=16d%=16d",
2806                   mp->is_ipv6 ? format_ip6_address :
2807                   format_ip4_address,
2808                   mp->ip_address, mp->priority, mp->weight);
2809     }
2810
2811   print (vam->ofp, "%v", s);
2812   vec_free (s);
2813 }
2814
2815 static void
2816 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t *node = NULL;
2820   struct in6_addr ip6;
2821   struct in_addr ip4;
2822
2823   if (VAT_JSON_ARRAY != vam->json_tree.type)
2824     {
2825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2826       vat_json_init_array (&vam->json_tree);
2827     }
2828   node = vat_json_array_add (&vam->json_tree);
2829   vat_json_init_object (node);
2830
2831   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2832   vat_json_object_add_uint (node, "priority", mp->priority);
2833   vat_json_object_add_uint (node, "weight", mp->weight);
2834
2835   if (mp->local)
2836     vat_json_object_add_uint (node, "sw_if_index",
2837                               clib_net_to_host_u32 (mp->sw_if_index));
2838   else
2839     {
2840       if (mp->is_ipv6)
2841         {
2842           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2843           vat_json_object_add_ip6 (node, "address", ip6);
2844         }
2845       else
2846         {
2847           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2848           vat_json_object_add_ip4 (node, "address", ip4);
2849         }
2850     }
2851 }
2852
2853 static void
2854 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2855                                           mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   u8 *ls_name = 0;
2859
2860   ls_name = format (0, "%s", mp->ls_name);
2861
2862   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2863          ls_name);
2864   vec_free (ls_name);
2865 }
2866
2867 static void
2868   vl_api_one_locator_set_details_t_handler_json
2869   (vl_api_one_locator_set_details_t * mp)
2870 {
2871   vat_main_t *vam = &vat_main;
2872   vat_json_node_t *node = 0;
2873   u8 *ls_name = 0;
2874
2875   ls_name = format (0, "%s", mp->ls_name);
2876   vec_add1 (ls_name, 0);
2877
2878   if (VAT_JSON_ARRAY != vam->json_tree.type)
2879     {
2880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2881       vat_json_init_array (&vam->json_tree);
2882     }
2883   node = vat_json_array_add (&vam->json_tree);
2884
2885   vat_json_init_object (node);
2886   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2887   vat_json_object_add_uint (node, "ls_index",
2888                             clib_net_to_host_u32 (mp->ls_index));
2889   vec_free (ls_name);
2890 }
2891
2892 typedef struct
2893 {
2894   u32 spi;
2895   u8 si;
2896 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2897
2898 uword
2899 unformat_nsh_address (unformat_input_t * input, va_list * args)
2900 {
2901   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2902   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2903 }
2904
2905 u8 *
2906 format_nsh_address_vat (u8 * s, va_list * args)
2907 {
2908   nsh_t *a = va_arg (*args, nsh_t *);
2909   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2910 }
2911
2912 static u8 *
2913 format_lisp_flat_eid (u8 * s, va_list * args)
2914 {
2915   u32 type = va_arg (*args, u32);
2916   u8 *eid = va_arg (*args, u8 *);
2917   u32 eid_len = va_arg (*args, u32);
2918
2919   switch (type)
2920     {
2921     case 0:
2922       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2923     case 1:
2924       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2925     case 2:
2926       return format (s, "%U", format_ethernet_address, eid);
2927     case 3:
2928       return format (s, "%U", format_nsh_address_vat, eid);
2929     }
2930   return 0;
2931 }
2932
2933 static u8 *
2934 format_lisp_eid_vat (u8 * s, va_list * args)
2935 {
2936   u32 type = va_arg (*args, u32);
2937   u8 *eid = va_arg (*args, u8 *);
2938   u32 eid_len = va_arg (*args, u32);
2939   u8 *seid = va_arg (*args, u8 *);
2940   u32 seid_len = va_arg (*args, u32);
2941   u32 is_src_dst = va_arg (*args, u32);
2942
2943   if (is_src_dst)
2944     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2945
2946   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2947
2948   return s;
2949 }
2950
2951 static void
2952 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2953 {
2954   vat_main_t *vam = &vat_main;
2955   u8 *s = 0, *eid = 0;
2956
2957   if (~0 == mp->locator_set_index)
2958     s = format (0, "action: %d", mp->action);
2959   else
2960     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2961
2962   eid = format (0, "%U", format_lisp_eid_vat,
2963                 mp->eid_type,
2964                 mp->eid,
2965                 mp->eid_prefix_len,
2966                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2967   vec_add1 (eid, 0);
2968
2969   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2970          clib_net_to_host_u32 (mp->vni),
2971          eid,
2972          mp->is_local ? "local" : "remote",
2973          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2974          clib_net_to_host_u16 (mp->key_id), mp->key);
2975
2976   vec_free (s);
2977   vec_free (eid);
2978 }
2979
2980 static void
2981 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2982                                              * mp)
2983 {
2984   vat_main_t *vam = &vat_main;
2985   vat_json_node_t *node = 0;
2986   u8 *eid = 0;
2987
2988   if (VAT_JSON_ARRAY != vam->json_tree.type)
2989     {
2990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2991       vat_json_init_array (&vam->json_tree);
2992     }
2993   node = vat_json_array_add (&vam->json_tree);
2994
2995   vat_json_init_object (node);
2996   if (~0 == mp->locator_set_index)
2997     vat_json_object_add_uint (node, "action", mp->action);
2998   else
2999     vat_json_object_add_uint (node, "locator_set_index",
3000                               clib_net_to_host_u32 (mp->locator_set_index));
3001
3002   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3003   if (mp->eid_type == 3)
3004     {
3005       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3006       vat_json_init_object (nsh_json);
3007       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3008       vat_json_object_add_uint (nsh_json, "spi",
3009                                 clib_net_to_host_u32 (nsh->spi));
3010       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3011     }
3012   else
3013     {
3014       eid = format (0, "%U", format_lisp_eid_vat,
3015                     mp->eid_type,
3016                     mp->eid,
3017                     mp->eid_prefix_len,
3018                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3019       vec_add1 (eid, 0);
3020       vat_json_object_add_string_copy (node, "eid", eid);
3021       vec_free (eid);
3022     }
3023   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3024   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3025   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3026
3027   if (mp->key_id)
3028     {
3029       vat_json_object_add_uint (node, "key_id",
3030                                 clib_net_to_host_u16 (mp->key_id));
3031       vat_json_object_add_string_copy (node, "key", mp->key);
3032     }
3033 }
3034
3035 static void
3036 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3037 {
3038   vat_main_t *vam = &vat_main;
3039   u8 *seid = 0, *deid = 0;
3040   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3041
3042   deid = format (0, "%U", format_lisp_eid_vat,
3043                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3044
3045   seid = format (0, "%U", format_lisp_eid_vat,
3046                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3047
3048   vec_add1 (deid, 0);
3049   vec_add1 (seid, 0);
3050
3051   if (mp->is_ip4)
3052     format_ip_address_fcn = format_ip4_address;
3053   else
3054     format_ip_address_fcn = format_ip6_address;
3055
3056
3057   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3058          clib_net_to_host_u32 (mp->vni),
3059          seid, deid,
3060          format_ip_address_fcn, mp->lloc,
3061          format_ip_address_fcn, mp->rloc,
3062          clib_net_to_host_u32 (mp->pkt_count),
3063          clib_net_to_host_u32 (mp->bytes));
3064
3065   vec_free (deid);
3066   vec_free (seid);
3067 }
3068
3069 static void
3070 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3071 {
3072   struct in6_addr ip6;
3073   struct in_addr ip4;
3074   vat_main_t *vam = &vat_main;
3075   vat_json_node_t *node = 0;
3076   u8 *deid = 0, *seid = 0;
3077
3078   if (VAT_JSON_ARRAY != vam->json_tree.type)
3079     {
3080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3081       vat_json_init_array (&vam->json_tree);
3082     }
3083   node = vat_json_array_add (&vam->json_tree);
3084
3085   vat_json_init_object (node);
3086   deid = format (0, "%U", format_lisp_eid_vat,
3087                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3088
3089   seid = format (0, "%U", format_lisp_eid_vat,
3090                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3091
3092   vec_add1 (deid, 0);
3093   vec_add1 (seid, 0);
3094
3095   vat_json_object_add_string_copy (node, "seid", seid);
3096   vat_json_object_add_string_copy (node, "deid", deid);
3097   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3098
3099   if (mp->is_ip4)
3100     {
3101       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3102       vat_json_object_add_ip4 (node, "lloc", ip4);
3103       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3104       vat_json_object_add_ip4 (node, "rloc", ip4);
3105     }
3106   else
3107     {
3108       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3109       vat_json_object_add_ip6 (node, "lloc", ip6);
3110       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3111       vat_json_object_add_ip6 (node, "rloc", ip6);
3112     }
3113   vat_json_object_add_uint (node, "pkt_count",
3114                             clib_net_to_host_u32 (mp->pkt_count));
3115   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3116
3117   vec_free (deid);
3118   vec_free (seid);
3119 }
3120
3121 static void
3122   vl_api_one_eid_table_map_details_t_handler
3123   (vl_api_one_eid_table_map_details_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126
3127   u8 *line = format (0, "%=10d%=10d",
3128                      clib_net_to_host_u32 (mp->vni),
3129                      clib_net_to_host_u32 (mp->dp_table));
3130   print (vam->ofp, "%v", line);
3131   vec_free (line);
3132 }
3133
3134 static void
3135   vl_api_one_eid_table_map_details_t_handler_json
3136   (vl_api_one_eid_table_map_details_t * mp)
3137 {
3138   vat_main_t *vam = &vat_main;
3139   vat_json_node_t *node = NULL;
3140
3141   if (VAT_JSON_ARRAY != vam->json_tree.type)
3142     {
3143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3144       vat_json_init_array (&vam->json_tree);
3145     }
3146   node = vat_json_array_add (&vam->json_tree);
3147   vat_json_init_object (node);
3148   vat_json_object_add_uint (node, "dp_table",
3149                             clib_net_to_host_u32 (mp->dp_table));
3150   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3151 }
3152
3153 static void
3154   vl_api_one_eid_table_vni_details_t_handler
3155   (vl_api_one_eid_table_vni_details_t * mp)
3156 {
3157   vat_main_t *vam = &vat_main;
3158
3159   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3160   print (vam->ofp, "%v", line);
3161   vec_free (line);
3162 }
3163
3164 static void
3165   vl_api_one_eid_table_vni_details_t_handler_json
3166   (vl_api_one_eid_table_vni_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t *node = NULL;
3170
3171   if (VAT_JSON_ARRAY != vam->json_tree.type)
3172     {
3173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3174       vat_json_init_array (&vam->json_tree);
3175     }
3176   node = vat_json_array_add (&vam->json_tree);
3177   vat_json_init_object (node);
3178   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3179 }
3180
3181 static void
3182   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3183   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186   int retval = clib_net_to_host_u32 (mp->retval);
3187
3188   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3189   print (vam->ofp, "fallback threshold value: %d", mp->value);
3190
3191   vam->retval = retval;
3192   vam->result_ready = 1;
3193 }
3194
3195 static void
3196   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3197   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200   vat_json_node_t _node, *node = &_node;
3201   int retval = clib_net_to_host_u32 (mp->retval);
3202
3203   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3204   vat_json_init_object (node);
3205   vat_json_object_add_uint (node, "value", mp->value);
3206
3207   vat_json_print (vam->ofp, node);
3208   vat_json_free (node);
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_show_one_map_register_state_reply_t_handler
3216   (vl_api_show_one_map_register_state_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   int retval = clib_net_to_host_u32 (mp->retval);
3220
3221   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3222
3223   vam->retval = retval;
3224   vam->result_ready = 1;
3225 }
3226
3227 static void
3228   vl_api_show_one_map_register_state_reply_t_handler_json
3229   (vl_api_show_one_map_register_state_reply_t * mp)
3230 {
3231   vat_main_t *vam = &vat_main;
3232   vat_json_node_t _node, *node = &_node;
3233   int retval = clib_net_to_host_u32 (mp->retval);
3234
3235   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3236
3237   vat_json_init_object (node);
3238   vat_json_object_add_string_copy (node, "state", s);
3239
3240   vat_json_print (vam->ofp, node);
3241   vat_json_free (node);
3242
3243   vam->retval = retval;
3244   vam->result_ready = 1;
3245   vec_free (s);
3246 }
3247
3248 static void
3249   vl_api_show_one_rloc_probe_state_reply_t_handler
3250   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   int retval = clib_net_to_host_u32 (mp->retval);
3254
3255   if (retval)
3256     goto end;
3257
3258   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3259 end:
3260   vam->retval = retval;
3261   vam->result_ready = 1;
3262 }
3263
3264 static void
3265   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3266   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   vat_json_node_t _node, *node = &_node;
3270   int retval = clib_net_to_host_u32 (mp->retval);
3271
3272   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3273   vat_json_init_object (node);
3274   vat_json_object_add_string_copy (node, "state", s);
3275
3276   vat_json_print (vam->ofp, node);
3277   vat_json_free (node);
3278
3279   vam->retval = retval;
3280   vam->result_ready = 1;
3281   vec_free (s);
3282 }
3283
3284 static void
3285   vl_api_show_one_stats_enable_disable_reply_t_handler
3286   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3287 {
3288   vat_main_t *vam = &vat_main;
3289   int retval = clib_net_to_host_u32 (mp->retval);
3290
3291   if (retval)
3292     goto end;
3293
3294   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3295 end:
3296   vam->retval = retval;
3297   vam->result_ready = 1;
3298 }
3299
3300 static void
3301   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3302   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   vat_json_node_t _node, *node = &_node;
3306   int retval = clib_net_to_host_u32 (mp->retval);
3307
3308   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3309   vat_json_init_object (node);
3310   vat_json_object_add_string_copy (node, "state", s);
3311
3312   vat_json_print (vam->ofp, node);
3313   vat_json_free (node);
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317   vec_free (s);
3318 }
3319
3320 static void
3321 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3322 {
3323   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3324   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3325   e->vni = clib_net_to_host_u32 (e->vni);
3326 }
3327
3328 static void
3329   gpe_fwd_entries_get_reply_t_net_to_host
3330   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3331 {
3332   u32 i;
3333
3334   mp->count = clib_net_to_host_u32 (mp->count);
3335   for (i = 0; i < mp->count; i++)
3336     {
3337       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3338     }
3339 }
3340
3341 static u8 *
3342 format_gpe_encap_mode (u8 * s, va_list * args)
3343 {
3344   u32 mode = va_arg (*args, u32);
3345
3346   switch (mode)
3347     {
3348     case 0:
3349       return format (s, "lisp");
3350     case 1:
3351       return format (s, "vxlan");
3352     }
3353   return 0;
3354 }
3355
3356 static void
3357   vl_api_gpe_get_encap_mode_reply_t_handler
3358   (vl_api_gpe_get_encap_mode_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361
3362   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3363   vam->retval = ntohl (mp->retval);
3364   vam->result_ready = 1;
3365 }
3366
3367 static void
3368   vl_api_gpe_get_encap_mode_reply_t_handler_json
3369   (vl_api_gpe_get_encap_mode_reply_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372   vat_json_node_t node;
3373
3374   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3375   vec_add1 (encap_mode, 0);
3376
3377   vat_json_init_object (&node);
3378   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3379
3380   vec_free (encap_mode);
3381   vat_json_print (vam->ofp, &node);
3382   vat_json_free (&node);
3383
3384   vam->retval = ntohl (mp->retval);
3385   vam->result_ready = 1;
3386 }
3387
3388 static void
3389   vl_api_gpe_fwd_entry_path_details_t_handler
3390   (vl_api_gpe_fwd_entry_path_details_t * mp)
3391 {
3392   vat_main_t *vam = &vat_main;
3393   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3394
3395   if (mp->lcl_loc.is_ip4)
3396     format_ip_address_fcn = format_ip4_address;
3397   else
3398     format_ip_address_fcn = format_ip6_address;
3399
3400   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3401          format_ip_address_fcn, &mp->lcl_loc,
3402          format_ip_address_fcn, &mp->rmt_loc);
3403 }
3404
3405 static void
3406 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3407 {
3408   struct in6_addr ip6;
3409   struct in_addr ip4;
3410
3411   if (loc->is_ip4)
3412     {
3413       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3414       vat_json_object_add_ip4 (n, "address", ip4);
3415     }
3416   else
3417     {
3418       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3419       vat_json_object_add_ip6 (n, "address", ip6);
3420     }
3421   vat_json_object_add_uint (n, "weight", loc->weight);
3422 }
3423
3424 static void
3425   vl_api_gpe_fwd_entry_path_details_t_handler_json
3426   (vl_api_gpe_fwd_entry_path_details_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   vat_json_node_t *node = NULL;
3430   vat_json_node_t *loc_node;
3431
3432   if (VAT_JSON_ARRAY != vam->json_tree.type)
3433     {
3434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3435       vat_json_init_array (&vam->json_tree);
3436     }
3437   node = vat_json_array_add (&vam->json_tree);
3438   vat_json_init_object (node);
3439
3440   loc_node = vat_json_object_add (node, "local_locator");
3441   vat_json_init_object (loc_node);
3442   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3443
3444   loc_node = vat_json_object_add (node, "remote_locator");
3445   vat_json_init_object (loc_node);
3446   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3447 }
3448
3449 static void
3450   vl_api_gpe_fwd_entries_get_reply_t_handler
3451   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3452 {
3453   vat_main_t *vam = &vat_main;
3454   u32 i;
3455   int retval = clib_net_to_host_u32 (mp->retval);
3456   vl_api_gpe_fwd_entry_t *e;
3457
3458   if (retval)
3459     goto end;
3460
3461   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3462
3463   for (i = 0; i < mp->count; i++)
3464     {
3465       e = &mp->entries[i];
3466       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3467              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3468              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3469     }
3470
3471 end:
3472   vam->retval = retval;
3473   vam->result_ready = 1;
3474 }
3475
3476 static void
3477   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3478   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3479 {
3480   u8 *s = 0;
3481   vat_main_t *vam = &vat_main;
3482   vat_json_node_t *e = 0, root;
3483   u32 i;
3484   int retval = clib_net_to_host_u32 (mp->retval);
3485   vl_api_gpe_fwd_entry_t *fwd;
3486
3487   if (retval)
3488     goto end;
3489
3490   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3491   vat_json_init_array (&root);
3492
3493   for (i = 0; i < mp->count; i++)
3494     {
3495       e = vat_json_array_add (&root);
3496       fwd = &mp->entries[i];
3497
3498       vat_json_init_object (e);
3499       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3500       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3501       vat_json_object_add_int (e, "vni", fwd->vni);
3502       vat_json_object_add_int (e, "action", fwd->action);
3503
3504       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3505                   fwd->leid_prefix_len);
3506       vec_add1 (s, 0);
3507       vat_json_object_add_string_copy (e, "leid", s);
3508       vec_free (s);
3509
3510       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3511                   fwd->reid_prefix_len);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "reid", s);
3514       vec_free (s);
3515     }
3516
3517   vat_json_print (vam->ofp, &root);
3518   vat_json_free (&root);
3519
3520 end:
3521   vam->retval = retval;
3522   vam->result_ready = 1;
3523 }
3524
3525 static void
3526   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3527   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530   u32 i, n;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532   vl_api_gpe_native_fwd_rpath_t *r;
3533
3534   if (retval)
3535     goto end;
3536
3537   n = clib_net_to_host_u32 (mp->count);
3538
3539   for (i = 0; i < n; i++)
3540     {
3541       r = &mp->entries[i];
3542       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3543              clib_net_to_host_u32 (r->fib_index),
3544              clib_net_to_host_u32 (r->nh_sw_if_index),
3545              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3546     }
3547
3548 end:
3549   vam->retval = retval;
3550   vam->result_ready = 1;
3551 }
3552
3553 static void
3554   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3555   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3556 {
3557   vat_main_t *vam = &vat_main;
3558   vat_json_node_t root, *e;
3559   u32 i, n;
3560   int retval = clib_net_to_host_u32 (mp->retval);
3561   vl_api_gpe_native_fwd_rpath_t *r;
3562   u8 *s;
3563
3564   if (retval)
3565     goto end;
3566
3567   n = clib_net_to_host_u32 (mp->count);
3568   vat_json_init_array (&root);
3569
3570   for (i = 0; i < n; i++)
3571     {
3572       e = vat_json_array_add (&root);
3573       vat_json_init_object (e);
3574       r = &mp->entries[i];
3575       s =
3576         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3577                 r->nh_addr);
3578       vec_add1 (s, 0);
3579       vat_json_object_add_string_copy (e, "ip4", s);
3580       vec_free (s);
3581
3582       vat_json_object_add_uint (e, "fib_index",
3583                                 clib_net_to_host_u32 (r->fib_index));
3584       vat_json_object_add_uint (e, "nh_sw_if_index",
3585                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3586     }
3587
3588   vat_json_print (vam->ofp, &root);
3589   vat_json_free (&root);
3590
3591 end:
3592   vam->retval = retval;
3593   vam->result_ready = 1;
3594 }
3595
3596 static void
3597   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3598   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3599 {
3600   vat_main_t *vam = &vat_main;
3601   u32 i, n;
3602   int retval = clib_net_to_host_u32 (mp->retval);
3603
3604   if (retval)
3605     goto end;
3606
3607   n = clib_net_to_host_u32 (mp->count);
3608
3609   for (i = 0; i < n; i++)
3610     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3611
3612 end:
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3619   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   vat_json_node_t root;
3623   u32 i, n;
3624   int retval = clib_net_to_host_u32 (mp->retval);
3625
3626   if (retval)
3627     goto end;
3628
3629   n = clib_net_to_host_u32 (mp->count);
3630   vat_json_init_array (&root);
3631
3632   for (i = 0; i < n; i++)
3633     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3634
3635   vat_json_print (vam->ofp, &root);
3636   vat_json_free (&root);
3637
3638 end:
3639   vam->retval = retval;
3640   vam->result_ready = 1;
3641 }
3642
3643 static void
3644   vl_api_one_ndp_entries_get_reply_t_handler
3645   (vl_api_one_ndp_entries_get_reply_t * mp)
3646 {
3647   vat_main_t *vam = &vat_main;
3648   u32 i, n;
3649   int retval = clib_net_to_host_u32 (mp->retval);
3650
3651   if (retval)
3652     goto end;
3653
3654   n = clib_net_to_host_u32 (mp->count);
3655
3656   for (i = 0; i < n; i++)
3657     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3658            format_ethernet_address, mp->entries[i].mac);
3659
3660 end:
3661   vam->retval = retval;
3662   vam->result_ready = 1;
3663 }
3664
3665 static void
3666   vl_api_one_ndp_entries_get_reply_t_handler_json
3667   (vl_api_one_ndp_entries_get_reply_t * mp)
3668 {
3669   u8 *s = 0;
3670   vat_main_t *vam = &vat_main;
3671   vat_json_node_t *e = 0, root;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_one_ndp_entry_t *arp_entry;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680   vat_json_init_array (&root);
3681
3682   for (i = 0; i < n; i++)
3683     {
3684       e = vat_json_array_add (&root);
3685       arp_entry = &mp->entries[i];
3686
3687       vat_json_init_object (e);
3688       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3689       vec_add1 (s, 0);
3690
3691       vat_json_object_add_string_copy (e, "mac", s);
3692       vec_free (s);
3693
3694       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3695       vec_add1 (s, 0);
3696       vat_json_object_add_string_copy (e, "ip6", s);
3697       vec_free (s);
3698     }
3699
3700   vat_json_print (vam->ofp, &root);
3701   vat_json_free (&root);
3702
3703 end:
3704   vam->retval = retval;
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_one_l2_arp_entries_get_reply_t_handler
3710   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i, n;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715
3716   if (retval)
3717     goto end;
3718
3719   n = clib_net_to_host_u32 (mp->count);
3720
3721   for (i = 0; i < n; i++)
3722     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3723            format_ethernet_address, mp->entries[i].mac);
3724
3725 end:
3726   vam->retval = retval;
3727   vam->result_ready = 1;
3728 }
3729
3730 static void
3731   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3732   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3733 {
3734   u8 *s = 0;
3735   vat_main_t *vam = &vat_main;
3736   vat_json_node_t *e = 0, root;
3737   u32 i, n;
3738   int retval = clib_net_to_host_u32 (mp->retval);
3739   vl_api_one_l2_arp_entry_t *arp_entry;
3740
3741   if (retval)
3742     goto end;
3743
3744   n = clib_net_to_host_u32 (mp->count);
3745   vat_json_init_array (&root);
3746
3747   for (i = 0; i < n; i++)
3748     {
3749       e = vat_json_array_add (&root);
3750       arp_entry = &mp->entries[i];
3751
3752       vat_json_init_object (e);
3753       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3754       vec_add1 (s, 0);
3755
3756       vat_json_object_add_string_copy (e, "mac", s);
3757       vec_free (s);
3758
3759       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3760       vec_add1 (s, 0);
3761       vat_json_object_add_string_copy (e, "ip4", s);
3762       vec_free (s);
3763     }
3764
3765   vat_json_print (vam->ofp, &root);
3766   vat_json_free (&root);
3767
3768 end:
3769   vam->retval = retval;
3770   vam->result_ready = 1;
3771 }
3772
3773 static void
3774 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3775 {
3776   vat_main_t *vam = &vat_main;
3777   u32 i, n;
3778   int retval = clib_net_to_host_u32 (mp->retval);
3779
3780   if (retval)
3781     goto end;
3782
3783   n = clib_net_to_host_u32 (mp->count);
3784
3785   for (i = 0; i < n; i++)
3786     {
3787       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3788     }
3789
3790 end:
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_one_ndp_bd_get_reply_t_handler_json
3797   (vl_api_one_ndp_bd_get_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   vat_json_node_t root;
3801   u32 i, n;
3802   int retval = clib_net_to_host_u32 (mp->retval);
3803
3804   if (retval)
3805     goto end;
3806
3807   n = clib_net_to_host_u32 (mp->count);
3808   vat_json_init_array (&root);
3809
3810   for (i = 0; i < n; i++)
3811     {
3812       vat_json_array_add_uint (&root,
3813                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3814     }
3815
3816   vat_json_print (vam->ofp, &root);
3817   vat_json_free (&root);
3818
3819 end:
3820   vam->retval = retval;
3821   vam->result_ready = 1;
3822 }
3823
3824 static void
3825   vl_api_one_l2_arp_bd_get_reply_t_handler
3826   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3827 {
3828   vat_main_t *vam = &vat_main;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831
3832   if (retval)
3833     goto end;
3834
3835   n = clib_net_to_host_u32 (mp->count);
3836
3837   for (i = 0; i < n; i++)
3838     {
3839       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3840     }
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3849   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   vat_json_node_t root;
3853   u32 i, n;
3854   int retval = clib_net_to_host_u32 (mp->retval);
3855
3856   if (retval)
3857     goto end;
3858
3859   n = clib_net_to_host_u32 (mp->count);
3860   vat_json_init_array (&root);
3861
3862   for (i = 0; i < n; i++)
3863     {
3864       vat_json_array_add_uint (&root,
3865                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3866     }
3867
3868   vat_json_print (vam->ofp, &root);
3869   vat_json_free (&root);
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_one_adjacencies_get_reply_t_handler
3878   (vl_api_one_adjacencies_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_one_adjacency_t *a;
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889
3890   for (i = 0; i < n; i++)
3891     {
3892       a = &mp->adjacencies[i];
3893       print (vam->ofp, "%U %40U",
3894              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3895              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3896     }
3897
3898 end:
3899   vam->retval = retval;
3900   vam->result_ready = 1;
3901 }
3902
3903 static void
3904   vl_api_one_adjacencies_get_reply_t_handler_json
3905   (vl_api_one_adjacencies_get_reply_t * mp)
3906 {
3907   u8 *s = 0;
3908   vat_main_t *vam = &vat_main;
3909   vat_json_node_t *e = 0, root;
3910   u32 i, n;
3911   int retval = clib_net_to_host_u32 (mp->retval);
3912   vl_api_one_adjacency_t *a;
3913
3914   if (retval)
3915     goto end;
3916
3917   n = clib_net_to_host_u32 (mp->count);
3918   vat_json_init_array (&root);
3919
3920   for (i = 0; i < n; i++)
3921     {
3922       e = vat_json_array_add (&root);
3923       a = &mp->adjacencies[i];
3924
3925       vat_json_init_object (e);
3926       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3927                   a->leid_prefix_len);
3928       vec_add1 (s, 0);
3929       vat_json_object_add_string_copy (e, "leid", s);
3930       vec_free (s);
3931
3932       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3933                   a->reid_prefix_len);
3934       vec_add1 (s, 0);
3935       vat_json_object_add_string_copy (e, "reid", s);
3936       vec_free (s);
3937     }
3938
3939   vat_json_print (vam->ofp, &root);
3940   vat_json_free (&root);
3941
3942 end:
3943   vam->retval = retval;
3944   vam->result_ready = 1;
3945 }
3946
3947 static void
3948 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3949 {
3950   vat_main_t *vam = &vat_main;
3951
3952   print (vam->ofp, "%=20U",
3953          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3954          mp->ip_address);
3955 }
3956
3957 static void
3958   vl_api_one_map_server_details_t_handler_json
3959   (vl_api_one_map_server_details_t * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962   vat_json_node_t *node = NULL;
3963   struct in6_addr ip6;
3964   struct in_addr ip4;
3965
3966   if (VAT_JSON_ARRAY != vam->json_tree.type)
3967     {
3968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3969       vat_json_init_array (&vam->json_tree);
3970     }
3971   node = vat_json_array_add (&vam->json_tree);
3972
3973   vat_json_init_object (node);
3974   if (mp->is_ipv6)
3975     {
3976       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3977       vat_json_object_add_ip6 (node, "map-server", ip6);
3978     }
3979   else
3980     {
3981       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3982       vat_json_object_add_ip4 (node, "map-server", ip4);
3983     }
3984 }
3985
3986 static void
3987 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3988                                            * mp)
3989 {
3990   vat_main_t *vam = &vat_main;
3991
3992   print (vam->ofp, "%=20U",
3993          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3994          mp->ip_address);
3995 }
3996
3997 static void
3998   vl_api_one_map_resolver_details_t_handler_json
3999   (vl_api_one_map_resolver_details_t * mp)
4000 {
4001   vat_main_t *vam = &vat_main;
4002   vat_json_node_t *node = NULL;
4003   struct in6_addr ip6;
4004   struct in_addr ip4;
4005
4006   if (VAT_JSON_ARRAY != vam->json_tree.type)
4007     {
4008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4009       vat_json_init_array (&vam->json_tree);
4010     }
4011   node = vat_json_array_add (&vam->json_tree);
4012
4013   vat_json_init_object (node);
4014   if (mp->is_ipv6)
4015     {
4016       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4017       vat_json_object_add_ip6 (node, "map resolver", ip6);
4018     }
4019   else
4020     {
4021       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4022       vat_json_object_add_ip4 (node, "map resolver", ip4);
4023     }
4024 }
4025
4026 static void
4027 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4028 {
4029   vat_main_t *vam = &vat_main;
4030   i32 retval = ntohl (mp->retval);
4031
4032   if (0 <= retval)
4033     {
4034       print (vam->ofp, "feature: %s\ngpe: %s",
4035              mp->feature_status ? "enabled" : "disabled",
4036              mp->gpe_status ? "enabled" : "disabled");
4037     }
4038
4039   vam->retval = retval;
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_show_one_status_reply_t_handler_json
4045   (vl_api_show_one_status_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   vat_json_node_t node;
4049   u8 *gpe_status = NULL;
4050   u8 *feature_status = NULL;
4051
4052   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4053   feature_status = format (0, "%s",
4054                            mp->feature_status ? "enabled" : "disabled");
4055   vec_add1 (gpe_status, 0);
4056   vec_add1 (feature_status, 0);
4057
4058   vat_json_init_object (&node);
4059   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4060   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4061
4062   vec_free (gpe_status);
4063   vec_free (feature_status);
4064
4065   vat_json_print (vam->ofp, &node);
4066   vat_json_free (&node);
4067
4068   vam->retval = ntohl (mp->retval);
4069   vam->result_ready = 1;
4070 }
4071
4072 static void
4073   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4074   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4075 {
4076   vat_main_t *vam = &vat_main;
4077   i32 retval = ntohl (mp->retval);
4078
4079   if (retval >= 0)
4080     {
4081       print (vam->ofp, "%=20s", mp->locator_set_name);
4082     }
4083
4084   vam->retval = retval;
4085   vam->result_ready = 1;
4086 }
4087
4088 static void
4089   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4090   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093   vat_json_node_t *node = NULL;
4094
4095   if (VAT_JSON_ARRAY != vam->json_tree.type)
4096     {
4097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4098       vat_json_init_array (&vam->json_tree);
4099     }
4100   node = vat_json_array_add (&vam->json_tree);
4101
4102   vat_json_init_object (node);
4103   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4104
4105   vat_json_print (vam->ofp, node);
4106   vat_json_free (node);
4107
4108   vam->retval = ntohl (mp->retval);
4109   vam->result_ready = 1;
4110 }
4111
4112 static u8 *
4113 format_lisp_map_request_mode (u8 * s, va_list * args)
4114 {
4115   u32 mode = va_arg (*args, u32);
4116
4117   switch (mode)
4118     {
4119     case 0:
4120       return format (0, "dst-only");
4121     case 1:
4122       return format (0, "src-dst");
4123     }
4124   return 0;
4125 }
4126
4127 static void
4128   vl_api_show_one_map_request_mode_reply_t_handler
4129   (vl_api_show_one_map_request_mode_reply_t * mp)
4130 {
4131   vat_main_t *vam = &vat_main;
4132   i32 retval = ntohl (mp->retval);
4133
4134   if (0 <= retval)
4135     {
4136       u32 mode = mp->mode;
4137       print (vam->ofp, "map_request_mode: %U",
4138              format_lisp_map_request_mode, mode);
4139     }
4140
4141   vam->retval = retval;
4142   vam->result_ready = 1;
4143 }
4144
4145 static void
4146   vl_api_show_one_map_request_mode_reply_t_handler_json
4147   (vl_api_show_one_map_request_mode_reply_t * mp)
4148 {
4149   vat_main_t *vam = &vat_main;
4150   vat_json_node_t node;
4151   u8 *s = 0;
4152   u32 mode;
4153
4154   mode = mp->mode;
4155   s = format (0, "%U", format_lisp_map_request_mode, mode);
4156   vec_add1 (s, 0);
4157
4158   vat_json_init_object (&node);
4159   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4160   vat_json_print (vam->ofp, &node);
4161   vat_json_free (&node);
4162
4163   vec_free (s);
4164   vam->retval = ntohl (mp->retval);
4165   vam->result_ready = 1;
4166 }
4167
4168 static void
4169   vl_api_one_show_xtr_mode_reply_t_handler
4170   (vl_api_one_show_xtr_mode_reply_t * mp)
4171 {
4172   vat_main_t *vam = &vat_main;
4173   i32 retval = ntohl (mp->retval);
4174
4175   if (0 <= retval)
4176     {
4177       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_one_show_xtr_mode_reply_t_handler_json
4186   (vl_api_one_show_xtr_mode_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t node;
4190   u8 *status = 0;
4191
4192   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4193   vec_add1 (status, 0);
4194
4195   vat_json_init_object (&node);
4196   vat_json_object_add_string_copy (&node, "status", status);
4197
4198   vec_free (status);
4199
4200   vat_json_print (vam->ofp, &node);
4201   vat_json_free (&node);
4202
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void
4208   vl_api_one_show_pitr_mode_reply_t_handler
4209   (vl_api_one_show_pitr_mode_reply_t * mp)
4210 {
4211   vat_main_t *vam = &vat_main;
4212   i32 retval = ntohl (mp->retval);
4213
4214   if (0 <= retval)
4215     {
4216       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4217     }
4218
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_show_pitr_mode_reply_t_handler_json
4225   (vl_api_one_show_pitr_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   vat_json_node_t node;
4229   u8 *status = 0;
4230
4231   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4232   vec_add1 (status, 0);
4233
4234   vat_json_init_object (&node);
4235   vat_json_object_add_string_copy (&node, "status", status);
4236
4237   vec_free (status);
4238
4239   vat_json_print (vam->ofp, &node);
4240   vat_json_free (&node);
4241
4242   vam->retval = ntohl (mp->retval);
4243   vam->result_ready = 1;
4244 }
4245
4246 static void
4247   vl_api_one_show_petr_mode_reply_t_handler
4248   (vl_api_one_show_petr_mode_reply_t * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251   i32 retval = ntohl (mp->retval);
4252
4253   if (0 <= retval)
4254     {
4255       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4256     }
4257
4258   vam->retval = retval;
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_petr_mode_reply_t_handler_json
4264   (vl_api_one_show_petr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   vat_json_node_t node;
4268   u8 *status = 0;
4269
4270   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4271   vec_add1 (status, 0);
4272
4273   vat_json_init_object (&node);
4274   vat_json_object_add_string_copy (&node, "status", status);
4275
4276   vec_free (status);
4277
4278   vat_json_print (vam->ofp, &node);
4279   vat_json_free (&node);
4280
4281   vam->retval = ntohl (mp->retval);
4282   vam->result_ready = 1;
4283 }
4284
4285 static void
4286   vl_api_show_one_use_petr_reply_t_handler
4287   (vl_api_show_one_use_petr_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4295       if (mp->status)
4296         {
4297           print (vam->ofp, "Proxy-ETR address; %U",
4298                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4299                  mp->address);
4300         }
4301     }
4302
4303   vam->retval = retval;
4304   vam->result_ready = 1;
4305 }
4306
4307 static void
4308   vl_api_show_one_use_petr_reply_t_handler_json
4309   (vl_api_show_one_use_petr_reply_t * mp)
4310 {
4311   vat_main_t *vam = &vat_main;
4312   vat_json_node_t node;
4313   u8 *status = 0;
4314   struct in_addr ip4;
4315   struct in6_addr ip6;
4316
4317   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4318   vec_add1 (status, 0);
4319
4320   vat_json_init_object (&node);
4321   vat_json_object_add_string_copy (&node, "status", status);
4322   if (mp->status)
4323     {
4324       if (mp->is_ip4)
4325         {
4326           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4327           vat_json_object_add_ip6 (&node, "address", ip6);
4328         }
4329       else
4330         {
4331           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4332           vat_json_object_add_ip4 (&node, "address", ip4);
4333         }
4334     }
4335
4336   vec_free (status);
4337
4338   vat_json_print (vam->ofp, &node);
4339   vat_json_free (&node);
4340
4341   vam->retval = ntohl (mp->retval);
4342   vam->result_ready = 1;
4343 }
4344
4345 static void
4346   vl_api_show_one_nsh_mapping_reply_t_handler
4347   (vl_api_show_one_nsh_mapping_reply_t * mp)
4348 {
4349   vat_main_t *vam = &vat_main;
4350   i32 retval = ntohl (mp->retval);
4351
4352   if (0 <= retval)
4353     {
4354       print (vam->ofp, "%-20s%-16s",
4355              mp->is_set ? "set" : "not-set",
4356              mp->is_set ? (char *) mp->locator_set_name : "");
4357     }
4358
4359   vam->retval = retval;
4360   vam->result_ready = 1;
4361 }
4362
4363 static void
4364   vl_api_show_one_nsh_mapping_reply_t_handler_json
4365   (vl_api_show_one_nsh_mapping_reply_t * mp)
4366 {
4367   vat_main_t *vam = &vat_main;
4368   vat_json_node_t node;
4369   u8 *status = 0;
4370
4371   status = format (0, "%s", mp->is_set ? "yes" : "no");
4372   vec_add1 (status, 0);
4373
4374   vat_json_init_object (&node);
4375   vat_json_object_add_string_copy (&node, "is_set", status);
4376   if (mp->is_set)
4377     {
4378       vat_json_object_add_string_copy (&node, "locator_set",
4379                                        mp->locator_set_name);
4380     }
4381
4382   vec_free (status);
4383
4384   vat_json_print (vam->ofp, &node);
4385   vat_json_free (&node);
4386
4387   vam->retval = ntohl (mp->retval);
4388   vam->result_ready = 1;
4389 }
4390
4391 static void
4392   vl_api_show_one_map_register_ttl_reply_t_handler
4393   (vl_api_show_one_map_register_ttl_reply_t * mp)
4394 {
4395   vat_main_t *vam = &vat_main;
4396   i32 retval = ntohl (mp->retval);
4397
4398   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4399
4400   if (0 <= retval)
4401     {
4402       print (vam->ofp, "ttl: %u", mp->ttl);
4403     }
4404
4405   vam->retval = retval;
4406   vam->result_ready = 1;
4407 }
4408
4409 static void
4410   vl_api_show_one_map_register_ttl_reply_t_handler_json
4411   (vl_api_show_one_map_register_ttl_reply_t * mp)
4412 {
4413   vat_main_t *vam = &vat_main;
4414   vat_json_node_t node;
4415
4416   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4417   vat_json_init_object (&node);
4418   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4429 {
4430   vat_main_t *vam = &vat_main;
4431   i32 retval = ntohl (mp->retval);
4432
4433   if (0 <= retval)
4434     {
4435       print (vam->ofp, "%-20s%-16s",
4436              mp->status ? "enabled" : "disabled",
4437              mp->status ? (char *) mp->locator_set_name : "");
4438     }
4439
4440   vam->retval = retval;
4441   vam->result_ready = 1;
4442 }
4443
4444 static void
4445 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456   if (mp->status)
4457     {
4458       vat_json_object_add_string_copy (&node, "locator_set",
4459                                        mp->locator_set_name);
4460     }
4461
4462   vec_free (status);
4463
4464   vat_json_print (vam->ofp, &node);
4465   vat_json_free (&node);
4466
4467   vam->retval = ntohl (mp->retval);
4468   vam->result_ready = 1;
4469 }
4470
4471 static u8 *
4472 format_policer_type (u8 * s, va_list * va)
4473 {
4474   u32 i = va_arg (*va, u32);
4475
4476   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4477     s = format (s, "1r2c");
4478   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4479     s = format (s, "1r3c");
4480   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4481     s = format (s, "2r3c-2698");
4482   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4483     s = format (s, "2r3c-4115");
4484   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4485     s = format (s, "2r3c-mef5cf1");
4486   else
4487     s = format (s, "ILLEGAL");
4488   return s;
4489 }
4490
4491 static u8 *
4492 format_policer_rate_type (u8 * s, va_list * va)
4493 {
4494   u32 i = va_arg (*va, u32);
4495
4496   if (i == SSE2_QOS_RATE_KBPS)
4497     s = format (s, "kbps");
4498   else if (i == SSE2_QOS_RATE_PPS)
4499     s = format (s, "pps");
4500   else
4501     s = format (s, "ILLEGAL");
4502   return s;
4503 }
4504
4505 static u8 *
4506 format_policer_round_type (u8 * s, va_list * va)
4507 {
4508   u32 i = va_arg (*va, u32);
4509
4510   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4511     s = format (s, "closest");
4512   else if (i == SSE2_QOS_ROUND_TO_UP)
4513     s = format (s, "up");
4514   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4515     s = format (s, "down");
4516   else
4517     s = format (s, "ILLEGAL");
4518   return s;
4519 }
4520
4521 static u8 *
4522 format_policer_action_type (u8 * s, va_list * va)
4523 {
4524   u32 i = va_arg (*va, u32);
4525
4526   if (i == SSE2_QOS_ACTION_DROP)
4527     s = format (s, "drop");
4528   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4529     s = format (s, "transmit");
4530   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4531     s = format (s, "mark-and-transmit");
4532   else
4533     s = format (s, "ILLEGAL");
4534   return s;
4535 }
4536
4537 static u8 *
4538 format_dscp (u8 * s, va_list * va)
4539 {
4540   u32 i = va_arg (*va, u32);
4541   char *t = 0;
4542
4543   switch (i)
4544     {
4545 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4546       foreach_vnet_dscp
4547 #undef _
4548     default:
4549       return format (s, "ILLEGAL");
4550     }
4551   s = format (s, "%s", t);
4552   return s;
4553 }
4554
4555 static void
4556 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4560
4561   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4562     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4563   else
4564     conform_dscp_str = format (0, "");
4565
4566   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4567     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4568   else
4569     exceed_dscp_str = format (0, "");
4570
4571   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4572     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4573   else
4574     violate_dscp_str = format (0, "");
4575
4576   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4577          "rate type %U, round type %U, %s rate, %s color-aware, "
4578          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4579          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4580          "conform action %U%s, exceed action %U%s, violate action %U%s",
4581          mp->name,
4582          format_policer_type, mp->type,
4583          ntohl (mp->cir),
4584          ntohl (mp->eir),
4585          clib_net_to_host_u64 (mp->cb),
4586          clib_net_to_host_u64 (mp->eb),
4587          format_policer_rate_type, mp->rate_type,
4588          format_policer_round_type, mp->round_type,
4589          mp->single_rate ? "single" : "dual",
4590          mp->color_aware ? "is" : "not",
4591          ntohl (mp->cir_tokens_per_period),
4592          ntohl (mp->pir_tokens_per_period),
4593          ntohl (mp->scale),
4594          ntohl (mp->current_limit),
4595          ntohl (mp->current_bucket),
4596          ntohl (mp->extended_limit),
4597          ntohl (mp->extended_bucket),
4598          clib_net_to_host_u64 (mp->last_update_time),
4599          format_policer_action_type, mp->conform_action.type,
4600          conform_dscp_str,
4601          format_policer_action_type, mp->exceed_action.type,
4602          exceed_dscp_str,
4603          format_policer_action_type, mp->violate_action.type,
4604          violate_dscp_str);
4605
4606   vec_free (conform_dscp_str);
4607   vec_free (exceed_dscp_str);
4608   vec_free (violate_dscp_str);
4609 }
4610
4611 static void vl_api_policer_details_t_handler_json
4612   (vl_api_policer_details_t * mp)
4613 {
4614   vat_main_t *vam = &vat_main;
4615   vat_json_node_t *node;
4616   u8 *rate_type_str, *round_type_str, *type_str;
4617   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4618
4619   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4620   round_type_str =
4621     format (0, "%U", format_policer_round_type, mp->round_type);
4622   type_str = format (0, "%U", format_policer_type, mp->type);
4623   conform_action_str = format (0, "%U", format_policer_action_type,
4624                                mp->conform_action.type);
4625   exceed_action_str = format (0, "%U", format_policer_action_type,
4626                               mp->exceed_action.type);
4627   violate_action_str = format (0, "%U", format_policer_action_type,
4628                                mp->violate_action.type);
4629
4630   if (VAT_JSON_ARRAY != vam->json_tree.type)
4631     {
4632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4633       vat_json_init_array (&vam->json_tree);
4634     }
4635   node = vat_json_array_add (&vam->json_tree);
4636
4637   vat_json_init_object (node);
4638   vat_json_object_add_string_copy (node, "name", mp->name);
4639   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4640   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4641   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4642   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4643   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4644   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4645   vat_json_object_add_string_copy (node, "type", type_str);
4646   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4647   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4648   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4649   vat_json_object_add_uint (node, "cir_tokens_per_period",
4650                             ntohl (mp->cir_tokens_per_period));
4651   vat_json_object_add_uint (node, "eir_tokens_per_period",
4652                             ntohl (mp->pir_tokens_per_period));
4653   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4654   vat_json_object_add_uint (node, "current_bucket",
4655                             ntohl (mp->current_bucket));
4656   vat_json_object_add_uint (node, "extended_limit",
4657                             ntohl (mp->extended_limit));
4658   vat_json_object_add_uint (node, "extended_bucket",
4659                             ntohl (mp->extended_bucket));
4660   vat_json_object_add_uint (node, "last_update_time",
4661                             ntohl (mp->last_update_time));
4662   vat_json_object_add_string_copy (node, "conform_action",
4663                                    conform_action_str);
4664   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4665     {
4666       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4667       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4668       vec_free (dscp_str);
4669     }
4670   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4671   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4672     {
4673       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4674       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4675       vec_free (dscp_str);
4676     }
4677   vat_json_object_add_string_copy (node, "violate_action",
4678                                    violate_action_str);
4679   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4680     {
4681       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4682       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4683       vec_free (dscp_str);
4684     }
4685
4686   vec_free (rate_type_str);
4687   vec_free (round_type_str);
4688   vec_free (type_str);
4689   vec_free (conform_action_str);
4690   vec_free (exceed_action_str);
4691   vec_free (violate_action_str);
4692 }
4693
4694 static void
4695 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4696                                            mp)
4697 {
4698   vat_main_t *vam = &vat_main;
4699   int i, count = ntohl (mp->count);
4700
4701   if (count > 0)
4702     print (vam->ofp, "classify table ids (%d) : ", count);
4703   for (i = 0; i < count; i++)
4704     {
4705       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4706       print (vam->ofp, (i < count - 1) ? "," : "");
4707     }
4708   vam->retval = ntohl (mp->retval);
4709   vam->result_ready = 1;
4710 }
4711
4712 static void
4713   vl_api_classify_table_ids_reply_t_handler_json
4714   (vl_api_classify_table_ids_reply_t * mp)
4715 {
4716   vat_main_t *vam = &vat_main;
4717   int i, count = ntohl (mp->count);
4718
4719   if (count > 0)
4720     {
4721       vat_json_node_t node;
4722
4723       vat_json_init_object (&node);
4724       for (i = 0; i < count; i++)
4725         {
4726           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4727         }
4728       vat_json_print (vam->ofp, &node);
4729       vat_json_free (&node);
4730     }
4731   vam->retval = ntohl (mp->retval);
4732   vam->result_ready = 1;
4733 }
4734
4735 static void
4736   vl_api_classify_table_by_interface_reply_t_handler
4737   (vl_api_classify_table_by_interface_reply_t * mp)
4738 {
4739   vat_main_t *vam = &vat_main;
4740   u32 table_id;
4741
4742   table_id = ntohl (mp->l2_table_id);
4743   if (table_id != ~0)
4744     print (vam->ofp, "l2 table id : %d", table_id);
4745   else
4746     print (vam->ofp, "l2 table id : No input ACL tables configured");
4747   table_id = ntohl (mp->ip4_table_id);
4748   if (table_id != ~0)
4749     print (vam->ofp, "ip4 table id : %d", table_id);
4750   else
4751     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4752   table_id = ntohl (mp->ip6_table_id);
4753   if (table_id != ~0)
4754     print (vam->ofp, "ip6 table id : %d", table_id);
4755   else
4756     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4757   vam->retval = ntohl (mp->retval);
4758   vam->result_ready = 1;
4759 }
4760
4761 static void
4762   vl_api_classify_table_by_interface_reply_t_handler_json
4763   (vl_api_classify_table_by_interface_reply_t * mp)
4764 {
4765   vat_main_t *vam = &vat_main;
4766   vat_json_node_t node;
4767
4768   vat_json_init_object (&node);
4769
4770   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4771   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4772   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4773
4774   vat_json_print (vam->ofp, &node);
4775   vat_json_free (&node);
4776
4777   vam->retval = ntohl (mp->retval);
4778   vam->result_ready = 1;
4779 }
4780
4781 static void vl_api_policer_add_del_reply_t_handler
4782   (vl_api_policer_add_del_reply_t * mp)
4783 {
4784   vat_main_t *vam = &vat_main;
4785   i32 retval = ntohl (mp->retval);
4786   if (vam->async_mode)
4787     {
4788       vam->async_errors += (retval < 0);
4789     }
4790   else
4791     {
4792       vam->retval = retval;
4793       vam->result_ready = 1;
4794       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4795         /*
4796          * Note: this is just barely thread-safe, depends on
4797          * the main thread spinning waiting for an answer...
4798          */
4799         errmsg ("policer index %d", ntohl (mp->policer_index));
4800     }
4801 }
4802
4803 static void vl_api_policer_add_del_reply_t_handler_json
4804   (vl_api_policer_add_del_reply_t * mp)
4805 {
4806   vat_main_t *vam = &vat_main;
4807   vat_json_node_t node;
4808
4809   vat_json_init_object (&node);
4810   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4811   vat_json_object_add_uint (&node, "policer_index",
4812                             ntohl (mp->policer_index));
4813
4814   vat_json_print (vam->ofp, &node);
4815   vat_json_free (&node);
4816
4817   vam->retval = ntohl (mp->retval);
4818   vam->result_ready = 1;
4819 }
4820
4821 /* Format hex dump. */
4822 u8 *
4823 format_hex_bytes (u8 * s, va_list * va)
4824 {
4825   u8 *bytes = va_arg (*va, u8 *);
4826   int n_bytes = va_arg (*va, int);
4827   uword i;
4828
4829   /* Print short or long form depending on byte count. */
4830   uword short_form = n_bytes <= 32;
4831   u32 indent = format_get_indent (s);
4832
4833   if (n_bytes == 0)
4834     return s;
4835
4836   for (i = 0; i < n_bytes; i++)
4837     {
4838       if (!short_form && (i % 32) == 0)
4839         s = format (s, "%08x: ", i);
4840       s = format (s, "%02x", bytes[i]);
4841       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4842         s = format (s, "\n%U", format_white_space, indent);
4843     }
4844
4845   return s;
4846 }
4847
4848 static void
4849 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4850                                             * mp)
4851 {
4852   vat_main_t *vam = &vat_main;
4853   i32 retval = ntohl (mp->retval);
4854   if (retval == 0)
4855     {
4856       print (vam->ofp, "classify table info :");
4857       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4858              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4859              ntohl (mp->miss_next_index));
4860       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4861              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4862              ntohl (mp->match_n_vectors));
4863       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4864              ntohl (mp->mask_length));
4865     }
4866   vam->retval = retval;
4867   vam->result_ready = 1;
4868 }
4869
4870 static void
4871   vl_api_classify_table_info_reply_t_handler_json
4872   (vl_api_classify_table_info_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t node;
4876
4877   i32 retval = ntohl (mp->retval);
4878   if (retval == 0)
4879     {
4880       vat_json_init_object (&node);
4881
4882       vat_json_object_add_int (&node, "sessions",
4883                                ntohl (mp->active_sessions));
4884       vat_json_object_add_int (&node, "nexttbl",
4885                                ntohl (mp->next_table_index));
4886       vat_json_object_add_int (&node, "nextnode",
4887                                ntohl (mp->miss_next_index));
4888       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4889       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4890       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4891       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4892                       ntohl (mp->mask_length), 0);
4893       vat_json_object_add_string_copy (&node, "mask", s);
4894
4895       vat_json_print (vam->ofp, &node);
4896       vat_json_free (&node);
4897     }
4898   vam->retval = ntohl (mp->retval);
4899   vam->result_ready = 1;
4900 }
4901
4902 static void
4903 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4904                                            mp)
4905 {
4906   vat_main_t *vam = &vat_main;
4907
4908   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4909          ntohl (mp->hit_next_index), ntohl (mp->advance),
4910          ntohl (mp->opaque_index));
4911   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4912          ntohl (mp->match_length));
4913 }
4914
4915 static void
4916   vl_api_classify_session_details_t_handler_json
4917   (vl_api_classify_session_details_t * mp)
4918 {
4919   vat_main_t *vam = &vat_main;
4920   vat_json_node_t *node = NULL;
4921
4922   if (VAT_JSON_ARRAY != vam->json_tree.type)
4923     {
4924       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4925       vat_json_init_array (&vam->json_tree);
4926     }
4927   node = vat_json_array_add (&vam->json_tree);
4928
4929   vat_json_init_object (node);
4930   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4931   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4932   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4933   u8 *s =
4934     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4935             0);
4936   vat_json_object_add_string_copy (node, "match", s);
4937 }
4938
4939 static void vl_api_pg_create_interface_reply_t_handler
4940   (vl_api_pg_create_interface_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   vam->retval = ntohl (mp->retval);
4945   vam->result_ready = 1;
4946 }
4947
4948 static void vl_api_pg_create_interface_reply_t_handler_json
4949   (vl_api_pg_create_interface_reply_t * mp)
4950 {
4951   vat_main_t *vam = &vat_main;
4952   vat_json_node_t node;
4953
4954   i32 retval = ntohl (mp->retval);
4955   if (retval == 0)
4956     {
4957       vat_json_init_object (&node);
4958
4959       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4960
4961       vat_json_print (vam->ofp, &node);
4962       vat_json_free (&node);
4963     }
4964   vam->retval = ntohl (mp->retval);
4965   vam->result_ready = 1;
4966 }
4967
4968 static void vl_api_policer_classify_details_t_handler
4969   (vl_api_policer_classify_details_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972
4973   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4974          ntohl (mp->table_index));
4975 }
4976
4977 static void vl_api_policer_classify_details_t_handler_json
4978   (vl_api_policer_classify_details_t * mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981   vat_json_node_t *node;
4982
4983   if (VAT_JSON_ARRAY != vam->json_tree.type)
4984     {
4985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4986       vat_json_init_array (&vam->json_tree);
4987     }
4988   node = vat_json_array_add (&vam->json_tree);
4989
4990   vat_json_init_object (node);
4991   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4992   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4993 }
4994
4995 static void vl_api_flow_classify_details_t_handler
4996   (vl_api_flow_classify_details_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999
5000   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5001          ntohl (mp->table_index));
5002 }
5003
5004 static void vl_api_flow_classify_details_t_handler_json
5005   (vl_api_flow_classify_details_t * mp)
5006 {
5007   vat_main_t *vam = &vat_main;
5008   vat_json_node_t *node;
5009
5010   if (VAT_JSON_ARRAY != vam->json_tree.type)
5011     {
5012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5013       vat_json_init_array (&vam->json_tree);
5014     }
5015   node = vat_json_array_add (&vam->json_tree);
5016
5017   vat_json_init_object (node);
5018   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5019   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5020 }
5021
5022 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5023 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5024 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5025 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5026 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5028 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5029 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5030 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5031 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5032
5033 /*
5034  * Generate boilerplate reply handlers, which
5035  * dig the return value out of the xxx_reply_t API message,
5036  * stick it into vam->retval, and set vam->result_ready
5037  *
5038  * Could also do this by pointing N message decode slots at
5039  * a single function, but that could break in subtle ways.
5040  */
5041
5042 #define foreach_standard_reply_retval_handler           \
5043 _(sw_interface_set_flags_reply)                         \
5044 _(sw_interface_add_del_address_reply)                   \
5045 _(sw_interface_set_rx_mode_reply)                       \
5046 _(sw_interface_set_rx_placement_reply)                  \
5047 _(sw_interface_set_table_reply)                         \
5048 _(sw_interface_set_mpls_enable_reply)                   \
5049 _(sw_interface_set_vpath_reply)                         \
5050 _(sw_interface_set_vxlan_bypass_reply)                  \
5051 _(sw_interface_set_geneve_bypass_reply)                 \
5052 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5053 _(sw_interface_set_l2_bridge_reply)                     \
5054 _(sw_interface_set_bond_weight_reply)                   \
5055 _(bridge_domain_add_del_reply)                          \
5056 _(sw_interface_set_l2_xconnect_reply)                   \
5057 _(l2fib_add_del_reply)                                  \
5058 _(l2fib_flush_int_reply)                                \
5059 _(l2fib_flush_bd_reply)                                 \
5060 _(ip_route_add_del_reply)                               \
5061 _(ip_table_add_del_reply)                               \
5062 _(ip_table_replace_begin_reply)                         \
5063 _(ip_table_flush_reply)                                 \
5064 _(ip_table_replace_end_reply)                           \
5065 _(ip_mroute_add_del_reply)                              \
5066 _(mpls_route_add_del_reply)                             \
5067 _(mpls_table_add_del_reply)                             \
5068 _(mpls_ip_bind_unbind_reply)                            \
5069 _(bier_route_add_del_reply)                             \
5070 _(bier_table_add_del_reply)                             \
5071 _(sw_interface_set_unnumbered_reply)                    \
5072 _(set_ip_flow_hash_reply)                               \
5073 _(sw_interface_ip6_enable_disable_reply)                \
5074 _(l2_patch_add_del_reply)                               \
5075 _(sr_mpls_policy_add_reply)                             \
5076 _(sr_mpls_policy_mod_reply)                             \
5077 _(sr_mpls_policy_del_reply)                             \
5078 _(sr_policy_add_reply)                                  \
5079 _(sr_policy_mod_reply)                                  \
5080 _(sr_policy_del_reply)                                  \
5081 _(sr_localsid_add_del_reply)                            \
5082 _(sr_steering_add_del_reply)                            \
5083 _(classify_add_del_session_reply)                       \
5084 _(classify_set_interface_ip_table_reply)                \
5085 _(classify_set_interface_l2_tables_reply)               \
5086 _(l2tpv3_set_tunnel_cookies_reply)                      \
5087 _(l2tpv3_interface_enable_disable_reply)                \
5088 _(l2tpv3_set_lookup_key_reply)                          \
5089 _(l2_fib_clear_table_reply)                             \
5090 _(l2_interface_efp_filter_reply)                        \
5091 _(l2_interface_vlan_tag_rewrite_reply)                  \
5092 _(modify_vhost_user_if_reply)                           \
5093 _(delete_vhost_user_if_reply)                           \
5094 _(want_l2_macs_events_reply)                            \
5095 _(input_acl_set_interface_reply)                        \
5096 _(ipsec_spd_add_del_reply)                              \
5097 _(ipsec_interface_add_del_spd_reply)                    \
5098 _(ipsec_spd_entry_add_del_reply)                        \
5099 _(ipsec_sad_entry_add_del_reply)                        \
5100 _(ipsec_tunnel_if_add_del_reply)                        \
5101 _(ipsec_tunnel_if_set_sa_reply)                         \
5102 _(delete_loopback_reply)                                \
5103 _(bd_ip_mac_add_del_reply)                              \
5104 _(bd_ip_mac_flush_reply)                                \
5105 _(want_interface_events_reply)                          \
5106 _(cop_interface_enable_disable_reply)                   \
5107 _(cop_whitelist_enable_disable_reply)                   \
5108 _(sw_interface_clear_stats_reply)                       \
5109 _(ioam_enable_reply)                                    \
5110 _(ioam_disable_reply)                                   \
5111 _(one_add_del_locator_reply)                            \
5112 _(one_add_del_local_eid_reply)                          \
5113 _(one_add_del_remote_mapping_reply)                     \
5114 _(one_add_del_adjacency_reply)                          \
5115 _(one_add_del_map_resolver_reply)                       \
5116 _(one_add_del_map_server_reply)                         \
5117 _(one_enable_disable_reply)                             \
5118 _(one_rloc_probe_enable_disable_reply)                  \
5119 _(one_map_register_enable_disable_reply)                \
5120 _(one_map_register_set_ttl_reply)                       \
5121 _(one_set_transport_protocol_reply)                     \
5122 _(one_map_register_fallback_threshold_reply)            \
5123 _(one_pitr_set_locator_set_reply)                       \
5124 _(one_map_request_mode_reply)                           \
5125 _(one_add_del_map_request_itr_rlocs_reply)              \
5126 _(one_eid_table_add_del_map_reply)                      \
5127 _(one_use_petr_reply)                                   \
5128 _(one_stats_enable_disable_reply)                       \
5129 _(one_add_del_l2_arp_entry_reply)                       \
5130 _(one_add_del_ndp_entry_reply)                          \
5131 _(one_stats_flush_reply)                                \
5132 _(one_enable_disable_xtr_mode_reply)                    \
5133 _(one_enable_disable_pitr_mode_reply)                   \
5134 _(one_enable_disable_petr_mode_reply)                   \
5135 _(gpe_enable_disable_reply)                             \
5136 _(gpe_set_encap_mode_reply)                             \
5137 _(gpe_add_del_iface_reply)                              \
5138 _(gpe_add_del_native_fwd_rpath_reply)                   \
5139 _(af_packet_delete_reply)                               \
5140 _(policer_classify_set_interface_reply)                 \
5141 _(set_ipfix_exporter_reply)                             \
5142 _(set_ipfix_classify_stream_reply)                      \
5143 _(ipfix_classify_table_add_del_reply)                   \
5144 _(flow_classify_set_interface_reply)                    \
5145 _(sw_interface_span_enable_disable_reply)               \
5146 _(pg_capture_reply)                                     \
5147 _(pg_enable_disable_reply)                              \
5148 _(ip_source_and_port_range_check_add_del_reply)         \
5149 _(ip_source_and_port_range_check_interface_add_del_reply)\
5150 _(delete_subif_reply)                                   \
5151 _(l2_interface_pbb_tag_rewrite_reply)                   \
5152 _(set_punt_reply)                                       \
5153 _(feature_enable_disable_reply)                         \
5154 _(feature_gso_enable_disable_reply)                     \
5155 _(sw_interface_tag_add_del_reply)                       \
5156 _(sw_interface_add_del_mac_address_reply)               \
5157 _(hw_interface_set_mtu_reply)                           \
5158 _(p2p_ethernet_add_reply)                               \
5159 _(p2p_ethernet_del_reply)                               \
5160 _(lldp_config_reply)                                    \
5161 _(sw_interface_set_lldp_reply)                          \
5162 _(tcp_configure_src_addresses_reply)                    \
5163 _(session_rule_add_del_reply)                           \
5164 _(ip_container_proxy_add_del_reply)                     \
5165 _(output_acl_set_interface_reply)                       \
5166 _(qos_record_enable_disable_reply)
5167
5168 #define _(n)                                    \
5169     static void vl_api_##n##_t_handler          \
5170     (vl_api_##n##_t * mp)                       \
5171     {                                           \
5172         vat_main_t * vam = &vat_main;           \
5173         i32 retval = ntohl(mp->retval);         \
5174         if (vam->async_mode) {                  \
5175             vam->async_errors += (retval < 0);  \
5176         } else {                                \
5177             vam->retval = retval;               \
5178             vam->result_ready = 1;              \
5179         }                                       \
5180     }
5181 foreach_standard_reply_retval_handler;
5182 #undef _
5183
5184 #define _(n)                                    \
5185     static void vl_api_##n##_t_handler_json     \
5186     (vl_api_##n##_t * mp)                       \
5187     {                                           \
5188         vat_main_t * vam = &vat_main;           \
5189         vat_json_node_t node;                   \
5190         vat_json_init_object(&node);            \
5191         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5192         vat_json_print(vam->ofp, &node);        \
5193         vam->retval = ntohl(mp->retval);        \
5194         vam->result_ready = 1;                  \
5195     }
5196 foreach_standard_reply_retval_handler;
5197 #undef _
5198
5199 /*
5200  * Table of message reply handlers, must include boilerplate handlers
5201  * we just generated
5202  */
5203
5204 #define foreach_vpe_api_reply_msg                                       \
5205 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5206 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5207 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5208 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5209 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5210 _(CLI_REPLY, cli_reply)                                                 \
5211 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5212 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5213   sw_interface_add_del_address_reply)                                   \
5214 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5215 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5216 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5217 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5218 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5219 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5220 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5221 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5222 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5223 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5224   sw_interface_set_l2_xconnect_reply)                                   \
5225 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5226   sw_interface_set_l2_bridge_reply)                                     \
5227 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5228 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5229 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5230 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5231 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5232 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5233 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5234 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5235 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5236 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5237 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5238 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5239 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5240 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5241 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5242 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5243 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5244 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5245 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5246 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5247 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5248 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5249 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5250 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5251 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5252 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5253 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5254 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5255 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5256 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5257 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5258 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5259 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5260 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5261   sw_interface_set_unnumbered_reply)                                    \
5262 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5263 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5264 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5265 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5266   sw_interface_ip6_enable_disable_reply)                                \
5267 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5268 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5269 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5270 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5271 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5272 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5273 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5274 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5275 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5276 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5277 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5278 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5279 classify_set_interface_ip_table_reply)                                  \
5280 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5281   classify_set_interface_l2_tables_reply)                               \
5282 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5283 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5284 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5285 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5286 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5287   l2tpv3_interface_enable_disable_reply)                                \
5288 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5289 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5290 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5291 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5292 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5293 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5294 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5295 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5296 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5297 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5298 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5299 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5300 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5301 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5302 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5303 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5304 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5305 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5306 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5307 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5308 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5309 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5310 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5311 _(L2_MACS_EVENT, l2_macs_event)                                         \
5312 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5313 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5314 _(IP_DETAILS, ip_details)                                               \
5315 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5316 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5317 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5318 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5319 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5320 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5321 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5322 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5323 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5324 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5325 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5326 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5327 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5328 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5329 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5330 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5331 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5332 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5333 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5334 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5335 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5336 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5337 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5338 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5339 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5340 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5341 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5342 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5343   one_map_register_enable_disable_reply)                                \
5344 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5345 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5346 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5347 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5348   one_map_register_fallback_threshold_reply)                            \
5349 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5350   one_rloc_probe_enable_disable_reply)                                  \
5351 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5352 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5353 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5354 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5355 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5356 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5357 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5358 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5359 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5360 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5361 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5362 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5363 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5364 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5365 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5366 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5367   show_one_stats_enable_disable_reply)                                  \
5368 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5369 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5370 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5371 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5372 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5373 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5374 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5375 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5376   one_enable_disable_pitr_mode_reply)                                   \
5377 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5378   one_enable_disable_petr_mode_reply)                                   \
5379 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5380 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5381 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5382 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5383 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5384 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5385 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5386 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5387 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5388 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5389 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5390 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5391   gpe_add_del_native_fwd_rpath_reply)                                   \
5392 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5393   gpe_fwd_entry_path_details)                                           \
5394 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5395 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5396   one_add_del_map_request_itr_rlocs_reply)                              \
5397 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5398   one_get_map_request_itr_rlocs_reply)                                  \
5399 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5400 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5401 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5402 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5403 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5404 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5405   show_one_map_register_state_reply)                                    \
5406 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5407 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5408   show_one_map_register_fallback_threshold_reply)                       \
5409 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5410 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5411 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5412 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5413 _(POLICER_DETAILS, policer_details)                                     \
5414 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5415 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5416 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5417 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5418 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5419 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5420 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5421 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5422 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5423 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5424 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5425 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5426 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5427 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5428 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5429 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5430 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5431 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5432 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5433 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5434 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5435 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5436 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5437 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5438  ip_source_and_port_range_check_add_del_reply)                          \
5439 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5440  ip_source_and_port_range_check_interface_add_del_reply)                \
5441 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5442 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5443 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5444 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5445 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5446 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5447 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5448 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5449 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5450 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5451 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5452 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5453 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5454 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5455 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5456 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5457 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5458 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5459 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5460 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5461 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5462 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5463 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5464
5465 #define foreach_standalone_reply_msg                                    \
5466 _(SW_INTERFACE_EVENT, sw_interface_event)
5467
5468 typedef struct
5469 {
5470   u8 *name;
5471   u32 value;
5472 } name_sort_t;
5473
5474 #define STR_VTR_OP_CASE(op)     \
5475     case L2_VTR_ ## op:         \
5476         return "" # op;
5477
5478 static const char *
5479 str_vtr_op (u32 vtr_op)
5480 {
5481   switch (vtr_op)
5482     {
5483       STR_VTR_OP_CASE (DISABLED);
5484       STR_VTR_OP_CASE (PUSH_1);
5485       STR_VTR_OP_CASE (PUSH_2);
5486       STR_VTR_OP_CASE (POP_1);
5487       STR_VTR_OP_CASE (POP_2);
5488       STR_VTR_OP_CASE (TRANSLATE_1_1);
5489       STR_VTR_OP_CASE (TRANSLATE_1_2);
5490       STR_VTR_OP_CASE (TRANSLATE_2_1);
5491       STR_VTR_OP_CASE (TRANSLATE_2_2);
5492     }
5493
5494   return "UNKNOWN";
5495 }
5496
5497 static int
5498 dump_sub_interface_table (vat_main_t * vam)
5499 {
5500   const sw_interface_subif_t *sub = NULL;
5501
5502   if (vam->json_output)
5503     {
5504       clib_warning
5505         ("JSON output supported only for VPE API calls and dump_stats_table");
5506       return -99;
5507     }
5508
5509   print (vam->ofp,
5510          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5511          "Interface", "sw_if_index",
5512          "sub id", "dot1ad", "tags", "outer id",
5513          "inner id", "exact", "default", "outer any", "inner any");
5514
5515   vec_foreach (sub, vam->sw_if_subif_table)
5516   {
5517     print (vam->ofp,
5518            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5519            sub->interface_name,
5520            sub->sw_if_index,
5521            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5522            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5523            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5524            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5525     if (sub->vtr_op != L2_VTR_DISABLED)
5526       {
5527         print (vam->ofp,
5528                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5529                "tag1: %d tag2: %d ]",
5530                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5531                sub->vtr_tag1, sub->vtr_tag2);
5532       }
5533   }
5534
5535   return 0;
5536 }
5537
5538 static int
5539 name_sort_cmp (void *a1, void *a2)
5540 {
5541   name_sort_t *n1 = a1;
5542   name_sort_t *n2 = a2;
5543
5544   return strcmp ((char *) n1->name, (char *) n2->name);
5545 }
5546
5547 static int
5548 dump_interface_table (vat_main_t * vam)
5549 {
5550   hash_pair_t *p;
5551   name_sort_t *nses = 0, *ns;
5552
5553   if (vam->json_output)
5554     {
5555       clib_warning
5556         ("JSON output supported only for VPE API calls and dump_stats_table");
5557       return -99;
5558     }
5559
5560   /* *INDENT-OFF* */
5561   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5562   ({
5563     vec_add2 (nses, ns, 1);
5564     ns->name = (u8 *)(p->key);
5565     ns->value = (u32) p->value[0];
5566   }));
5567   /* *INDENT-ON* */
5568
5569   vec_sort_with_function (nses, name_sort_cmp);
5570
5571   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5572   vec_foreach (ns, nses)
5573   {
5574     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5575   }
5576   vec_free (nses);
5577   return 0;
5578 }
5579
5580 static int
5581 dump_ip_table (vat_main_t * vam, int is_ipv6)
5582 {
5583   const ip_details_t *det = NULL;
5584   const ip_address_details_t *address = NULL;
5585   u32 i = ~0;
5586
5587   print (vam->ofp, "%-12s", "sw_if_index");
5588
5589   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5590   {
5591     i++;
5592     if (!det->present)
5593       {
5594         continue;
5595       }
5596     print (vam->ofp, "%-12d", i);
5597     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5598     if (!det->addr)
5599       {
5600         continue;
5601       }
5602     vec_foreach (address, det->addr)
5603     {
5604       print (vam->ofp,
5605              "            %-30U%-13d",
5606              is_ipv6 ? format_ip6_address : format_ip4_address,
5607              address->ip, address->prefix_length);
5608     }
5609   }
5610
5611   return 0;
5612 }
5613
5614 static int
5615 dump_ipv4_table (vat_main_t * vam)
5616 {
5617   if (vam->json_output)
5618     {
5619       clib_warning
5620         ("JSON output supported only for VPE API calls and dump_stats_table");
5621       return -99;
5622     }
5623
5624   return dump_ip_table (vam, 0);
5625 }
5626
5627 static int
5628 dump_ipv6_table (vat_main_t * vam)
5629 {
5630   if (vam->json_output)
5631     {
5632       clib_warning
5633         ("JSON output supported only for VPE API calls and dump_stats_table");
5634       return -99;
5635     }
5636
5637   return dump_ip_table (vam, 1);
5638 }
5639
5640 /*
5641  * Pass CLI buffers directly in the CLI_INBAND API message,
5642  * instead of an additional shared memory area.
5643  */
5644 static int
5645 exec_inband (vat_main_t * vam)
5646 {
5647   vl_api_cli_inband_t *mp;
5648   unformat_input_t *i = vam->input;
5649   int ret;
5650
5651   if (vec_len (i->buffer) == 0)
5652     return -1;
5653
5654   if (vam->exec_mode == 0 && unformat (i, "mode"))
5655     {
5656       vam->exec_mode = 1;
5657       return 0;
5658     }
5659   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5660     {
5661       vam->exec_mode = 0;
5662       return 0;
5663     }
5664
5665   /*
5666    * In order for the CLI command to work, it
5667    * must be a vector ending in \n, not a C-string ending
5668    * in \n\0.
5669    */
5670   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5671   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5672
5673   S (mp);
5674   W (ret);
5675   /* json responses may or may not include a useful reply... */
5676   if (vec_len (vam->cmd_reply))
5677     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5678   return ret;
5679 }
5680
5681 int
5682 exec (vat_main_t * vam)
5683 {
5684   return exec_inband (vam);
5685 }
5686
5687 static int
5688 api_create_loopback (vat_main_t * vam)
5689 {
5690   unformat_input_t *i = vam->input;
5691   vl_api_create_loopback_t *mp;
5692   vl_api_create_loopback_instance_t *mp_lbi;
5693   u8 mac_address[6];
5694   u8 mac_set = 0;
5695   u8 is_specified = 0;
5696   u32 user_instance = 0;
5697   int ret;
5698
5699   clib_memset (mac_address, 0, sizeof (mac_address));
5700
5701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5702     {
5703       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5704         mac_set = 1;
5705       if (unformat (i, "instance %d", &user_instance))
5706         is_specified = 1;
5707       else
5708         break;
5709     }
5710
5711   if (is_specified)
5712     {
5713       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5714       mp_lbi->is_specified = is_specified;
5715       if (is_specified)
5716         mp_lbi->user_instance = htonl (user_instance);
5717       if (mac_set)
5718         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5719       S (mp_lbi);
5720     }
5721   else
5722     {
5723       /* Construct the API message */
5724       M (CREATE_LOOPBACK, mp);
5725       if (mac_set)
5726         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5727       S (mp);
5728     }
5729
5730   W (ret);
5731   return ret;
5732 }
5733
5734 static int
5735 api_delete_loopback (vat_main_t * vam)
5736 {
5737   unformat_input_t *i = vam->input;
5738   vl_api_delete_loopback_t *mp;
5739   u32 sw_if_index = ~0;
5740   int ret;
5741
5742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5743     {
5744       if (unformat (i, "sw_if_index %d", &sw_if_index))
5745         ;
5746       else
5747         break;
5748     }
5749
5750   if (sw_if_index == ~0)
5751     {
5752       errmsg ("missing sw_if_index");
5753       return -99;
5754     }
5755
5756   /* Construct the API message */
5757   M (DELETE_LOOPBACK, mp);
5758   mp->sw_if_index = ntohl (sw_if_index);
5759
5760   S (mp);
5761   W (ret);
5762   return ret;
5763 }
5764
5765 static int
5766 api_want_interface_events (vat_main_t * vam)
5767 {
5768   unformat_input_t *i = vam->input;
5769   vl_api_want_interface_events_t *mp;
5770   int enable = -1;
5771   int ret;
5772
5773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5774     {
5775       if (unformat (i, "enable"))
5776         enable = 1;
5777       else if (unformat (i, "disable"))
5778         enable = 0;
5779       else
5780         break;
5781     }
5782
5783   if (enable == -1)
5784     {
5785       errmsg ("missing enable|disable");
5786       return -99;
5787     }
5788
5789   M (WANT_INTERFACE_EVENTS, mp);
5790   mp->enable_disable = enable;
5791
5792   vam->interface_event_display = enable;
5793
5794   S (mp);
5795   W (ret);
5796   return ret;
5797 }
5798
5799
5800 /* Note: non-static, called once to set up the initial intfc table */
5801 int
5802 api_sw_interface_dump (vat_main_t * vam)
5803 {
5804   vl_api_sw_interface_dump_t *mp;
5805   vl_api_control_ping_t *mp_ping;
5806   hash_pair_t *p;
5807   name_sort_t *nses = 0, *ns;
5808   sw_interface_subif_t *sub = NULL;
5809   int ret;
5810
5811   /* Toss the old name table */
5812   /* *INDENT-OFF* */
5813   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5814   ({
5815     vec_add2 (nses, ns, 1);
5816     ns->name = (u8 *)(p->key);
5817     ns->value = (u32) p->value[0];
5818   }));
5819   /* *INDENT-ON* */
5820
5821   hash_free (vam->sw_if_index_by_interface_name);
5822
5823   vec_foreach (ns, nses) vec_free (ns->name);
5824
5825   vec_free (nses);
5826
5827   vec_foreach (sub, vam->sw_if_subif_table)
5828   {
5829     vec_free (sub->interface_name);
5830   }
5831   vec_free (vam->sw_if_subif_table);
5832
5833   /* recreate the interface name hash table */
5834   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5835
5836   /*
5837    * Ask for all interface names. Otherwise, the epic catalog of
5838    * name filters becomes ridiculously long, and vat ends up needing
5839    * to be taught about new interface types.
5840    */
5841   M (SW_INTERFACE_DUMP, mp);
5842   S (mp);
5843
5844   /* Use a control ping for synchronization */
5845   MPING (CONTROL_PING, mp_ping);
5846   S (mp_ping);
5847
5848   W (ret);
5849   return ret;
5850 }
5851
5852 static int
5853 api_sw_interface_set_flags (vat_main_t * vam)
5854 {
5855   unformat_input_t *i = vam->input;
5856   vl_api_sw_interface_set_flags_t *mp;
5857   u32 sw_if_index;
5858   u8 sw_if_index_set = 0;
5859   u8 admin_up = 0;
5860   int ret;
5861
5862   /* Parse args required to build the message */
5863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5864     {
5865       if (unformat (i, "admin-up"))
5866         admin_up = 1;
5867       else if (unformat (i, "admin-down"))
5868         admin_up = 0;
5869       else
5870         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5871         sw_if_index_set = 1;
5872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5873         sw_if_index_set = 1;
5874       else
5875         break;
5876     }
5877
5878   if (sw_if_index_set == 0)
5879     {
5880       errmsg ("missing interface name or sw_if_index");
5881       return -99;
5882     }
5883
5884   /* Construct the API message */
5885   M (SW_INTERFACE_SET_FLAGS, mp);
5886   mp->sw_if_index = ntohl (sw_if_index);
5887   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5888
5889   /* send it... */
5890   S (mp);
5891
5892   /* Wait for a reply, return the good/bad news... */
5893   W (ret);
5894   return ret;
5895 }
5896
5897 static int
5898 api_sw_interface_set_rx_mode (vat_main_t * vam)
5899 {
5900   unformat_input_t *i = vam->input;
5901   vl_api_sw_interface_set_rx_mode_t *mp;
5902   u32 sw_if_index;
5903   u8 sw_if_index_set = 0;
5904   int ret;
5905   u8 queue_id_valid = 0;
5906   u32 queue_id;
5907   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5908
5909   /* Parse args required to build the message */
5910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5911     {
5912       if (unformat (i, "queue %d", &queue_id))
5913         queue_id_valid = 1;
5914       else if (unformat (i, "polling"))
5915         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5916       else if (unformat (i, "interrupt"))
5917         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5918       else if (unformat (i, "adaptive"))
5919         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5920       else
5921         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5922         sw_if_index_set = 1;
5923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5924         sw_if_index_set = 1;
5925       else
5926         break;
5927     }
5928
5929   if (sw_if_index_set == 0)
5930     {
5931       errmsg ("missing interface name or sw_if_index");
5932       return -99;
5933     }
5934   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5935     {
5936       errmsg ("missing rx-mode");
5937       return -99;
5938     }
5939
5940   /* Construct the API message */
5941   M (SW_INTERFACE_SET_RX_MODE, mp);
5942   mp->sw_if_index = ntohl (sw_if_index);
5943   mp->mode = (vl_api_rx_mode_t) mode;
5944   mp->queue_id_valid = queue_id_valid;
5945   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5946
5947   /* send it... */
5948   S (mp);
5949
5950   /* Wait for a reply, return the good/bad news... */
5951   W (ret);
5952   return ret;
5953 }
5954
5955 static int
5956 api_sw_interface_set_rx_placement (vat_main_t * vam)
5957 {
5958   unformat_input_t *i = vam->input;
5959   vl_api_sw_interface_set_rx_placement_t *mp;
5960   u32 sw_if_index;
5961   u8 sw_if_index_set = 0;
5962   int ret;
5963   u8 is_main = 0;
5964   u32 queue_id, thread_index;
5965
5966   /* Parse args required to build the message */
5967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5968     {
5969       if (unformat (i, "queue %d", &queue_id))
5970         ;
5971       else if (unformat (i, "main"))
5972         is_main = 1;
5973       else if (unformat (i, "worker %d", &thread_index))
5974         ;
5975       else
5976         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5977         sw_if_index_set = 1;
5978       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5979         sw_if_index_set = 1;
5980       else
5981         break;
5982     }
5983
5984   if (sw_if_index_set == 0)
5985     {
5986       errmsg ("missing interface name or sw_if_index");
5987       return -99;
5988     }
5989
5990   if (is_main)
5991     thread_index = 0;
5992   /* Construct the API message */
5993   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5994   mp->sw_if_index = ntohl (sw_if_index);
5995   mp->worker_id = ntohl (thread_index);
5996   mp->queue_id = ntohl (queue_id);
5997   mp->is_main = is_main;
5998
5999   /* send it... */
6000   S (mp);
6001   /* Wait for a reply, return the good/bad news... */
6002   W (ret);
6003   return ret;
6004 }
6005
6006 static void vl_api_sw_interface_rx_placement_details_t_handler
6007   (vl_api_sw_interface_rx_placement_details_t * mp)
6008 {
6009   vat_main_t *vam = &vat_main;
6010   u32 worker_id = ntohl (mp->worker_id);
6011
6012   print (vam->ofp,
6013          "\n%-11d %-11s %-6d %-5d %-9s",
6014          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6015          worker_id, ntohl (mp->queue_id),
6016          (mp->mode ==
6017           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6018 }
6019
6020 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6021   (vl_api_sw_interface_rx_placement_details_t * mp)
6022 {
6023   vat_main_t *vam = &vat_main;
6024   vat_json_node_t *node = NULL;
6025
6026   if (VAT_JSON_ARRAY != vam->json_tree.type)
6027     {
6028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6029       vat_json_init_array (&vam->json_tree);
6030     }
6031   node = vat_json_array_add (&vam->json_tree);
6032
6033   vat_json_init_object (node);
6034   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6035   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6036   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6037   vat_json_object_add_uint (node, "mode", mp->mode);
6038 }
6039
6040 static int
6041 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_sw_interface_rx_placement_dump_t *mp;
6045   vl_api_control_ping_t *mp_ping;
6046   int ret;
6047   u32 sw_if_index;
6048   u8 sw_if_index_set = 0;
6049
6050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6051     {
6052       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6053         sw_if_index_set++;
6054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6055         sw_if_index_set++;
6056       else
6057         break;
6058     }
6059
6060   print (vam->ofp,
6061          "\n%-11s %-11s %-6s %-5s %-4s",
6062          "sw_if_index", "main/worker", "thread", "queue", "mode");
6063
6064   /* Dump Interface rx placement */
6065   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6066
6067   if (sw_if_index_set)
6068     mp->sw_if_index = htonl (sw_if_index);
6069   else
6070     mp->sw_if_index = ~0;
6071
6072   S (mp);
6073
6074   /* Use a control ping for synchronization */
6075   MPING (CONTROL_PING, mp_ping);
6076   S (mp_ping);
6077
6078   W (ret);
6079   return ret;
6080 }
6081
6082 static int
6083 api_sw_interface_clear_stats (vat_main_t * vam)
6084 {
6085   unformat_input_t *i = vam->input;
6086   vl_api_sw_interface_clear_stats_t *mp;
6087   u32 sw_if_index;
6088   u8 sw_if_index_set = 0;
6089   int ret;
6090
6091   /* Parse args required to build the message */
6092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6093     {
6094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6095         sw_if_index_set = 1;
6096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6097         sw_if_index_set = 1;
6098       else
6099         break;
6100     }
6101
6102   /* Construct the API message */
6103   M (SW_INTERFACE_CLEAR_STATS, mp);
6104
6105   if (sw_if_index_set == 1)
6106     mp->sw_if_index = ntohl (sw_if_index);
6107   else
6108     mp->sw_if_index = ~0;
6109
6110   /* send it... */
6111   S (mp);
6112
6113   /* Wait for a reply, return the good/bad news... */
6114   W (ret);
6115   return ret;
6116 }
6117
6118 static int
6119 api_sw_interface_add_del_address (vat_main_t * vam)
6120 {
6121   unformat_input_t *i = vam->input;
6122   vl_api_sw_interface_add_del_address_t *mp;
6123   u32 sw_if_index;
6124   u8 sw_if_index_set = 0;
6125   u8 is_add = 1, del_all = 0;
6126   u32 address_length = 0;
6127   u8 v4_address_set = 0;
6128   u8 v6_address_set = 0;
6129   ip4_address_t v4address;
6130   ip6_address_t v6address;
6131   int ret;
6132
6133   /* Parse args required to build the message */
6134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6135     {
6136       if (unformat (i, "del-all"))
6137         del_all = 1;
6138       else if (unformat (i, "del"))
6139         is_add = 0;
6140       else
6141         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6142         sw_if_index_set = 1;
6143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6144         sw_if_index_set = 1;
6145       else if (unformat (i, "%U/%d",
6146                          unformat_ip4_address, &v4address, &address_length))
6147         v4_address_set = 1;
6148       else if (unformat (i, "%U/%d",
6149                          unformat_ip6_address, &v6address, &address_length))
6150         v6_address_set = 1;
6151       else
6152         break;
6153     }
6154
6155   if (sw_if_index_set == 0)
6156     {
6157       errmsg ("missing interface name or sw_if_index");
6158       return -99;
6159     }
6160   if (v4_address_set && v6_address_set)
6161     {
6162       errmsg ("both v4 and v6 addresses set");
6163       return -99;
6164     }
6165   if (!v4_address_set && !v6_address_set && !del_all)
6166     {
6167       errmsg ("no addresses set");
6168       return -99;
6169     }
6170
6171   /* Construct the API message */
6172   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6173
6174   mp->sw_if_index = ntohl (sw_if_index);
6175   mp->is_add = is_add;
6176   mp->del_all = del_all;
6177   if (v6_address_set)
6178     {
6179       mp->prefix.address.af = ADDRESS_IP6;
6180       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6181     }
6182   else
6183     {
6184       mp->prefix.address.af = ADDRESS_IP4;
6185       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6186     }
6187   mp->prefix.len = address_length;
6188
6189   /* send it... */
6190   S (mp);
6191
6192   /* Wait for a reply, return good/bad news  */
6193   W (ret);
6194   return ret;
6195 }
6196
6197 static int
6198 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6199 {
6200   unformat_input_t *i = vam->input;
6201   vl_api_sw_interface_set_mpls_enable_t *mp;
6202   u32 sw_if_index;
6203   u8 sw_if_index_set = 0;
6204   u8 enable = 1;
6205   int ret;
6206
6207   /* Parse args required to build the message */
6208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6209     {
6210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6211         sw_if_index_set = 1;
6212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6213         sw_if_index_set = 1;
6214       else if (unformat (i, "disable"))
6215         enable = 0;
6216       else if (unformat (i, "dis"))
6217         enable = 0;
6218       else
6219         break;
6220     }
6221
6222   if (sw_if_index_set == 0)
6223     {
6224       errmsg ("missing interface name or sw_if_index");
6225       return -99;
6226     }
6227
6228   /* Construct the API message */
6229   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6230
6231   mp->sw_if_index = ntohl (sw_if_index);
6232   mp->enable = enable;
6233
6234   /* send it... */
6235   S (mp);
6236
6237   /* Wait for a reply... */
6238   W (ret);
6239   return ret;
6240 }
6241
6242 static int
6243 api_sw_interface_set_table (vat_main_t * vam)
6244 {
6245   unformat_input_t *i = vam->input;
6246   vl_api_sw_interface_set_table_t *mp;
6247   u32 sw_if_index, vrf_id = 0;
6248   u8 sw_if_index_set = 0;
6249   u8 is_ipv6 = 0;
6250   int ret;
6251
6252   /* Parse args required to build the message */
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6256         sw_if_index_set = 1;
6257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6258         sw_if_index_set = 1;
6259       else if (unformat (i, "vrf %d", &vrf_id))
6260         ;
6261       else if (unformat (i, "ipv6"))
6262         is_ipv6 = 1;
6263       else
6264         break;
6265     }
6266
6267   if (sw_if_index_set == 0)
6268     {
6269       errmsg ("missing interface name or sw_if_index");
6270       return -99;
6271     }
6272
6273   /* Construct the API message */
6274   M (SW_INTERFACE_SET_TABLE, mp);
6275
6276   mp->sw_if_index = ntohl (sw_if_index);
6277   mp->is_ipv6 = is_ipv6;
6278   mp->vrf_id = ntohl (vrf_id);
6279
6280   /* send it... */
6281   S (mp);
6282
6283   /* Wait for a reply... */
6284   W (ret);
6285   return ret;
6286 }
6287
6288 static void vl_api_sw_interface_get_table_reply_t_handler
6289   (vl_api_sw_interface_get_table_reply_t * mp)
6290 {
6291   vat_main_t *vam = &vat_main;
6292
6293   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6294
6295   vam->retval = ntohl (mp->retval);
6296   vam->result_ready = 1;
6297
6298 }
6299
6300 static void vl_api_sw_interface_get_table_reply_t_handler_json
6301   (vl_api_sw_interface_get_table_reply_t * mp)
6302 {
6303   vat_main_t *vam = &vat_main;
6304   vat_json_node_t node;
6305
6306   vat_json_init_object (&node);
6307   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6308   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6309
6310   vat_json_print (vam->ofp, &node);
6311   vat_json_free (&node);
6312
6313   vam->retval = ntohl (mp->retval);
6314   vam->result_ready = 1;
6315 }
6316
6317 static int
6318 api_sw_interface_get_table (vat_main_t * vam)
6319 {
6320   unformat_input_t *i = vam->input;
6321   vl_api_sw_interface_get_table_t *mp;
6322   u32 sw_if_index;
6323   u8 sw_if_index_set = 0;
6324   u8 is_ipv6 = 0;
6325   int ret;
6326
6327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6328     {
6329       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6330         sw_if_index_set = 1;
6331       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6332         sw_if_index_set = 1;
6333       else if (unformat (i, "ipv6"))
6334         is_ipv6 = 1;
6335       else
6336         break;
6337     }
6338
6339   if (sw_if_index_set == 0)
6340     {
6341       errmsg ("missing interface name or sw_if_index");
6342       return -99;
6343     }
6344
6345   M (SW_INTERFACE_GET_TABLE, mp);
6346   mp->sw_if_index = htonl (sw_if_index);
6347   mp->is_ipv6 = is_ipv6;
6348
6349   S (mp);
6350   W (ret);
6351   return ret;
6352 }
6353
6354 static int
6355 api_sw_interface_set_vpath (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_sw_interface_set_vpath_t *mp;
6359   u32 sw_if_index = 0;
6360   u8 sw_if_index_set = 0;
6361   u8 is_enable = 0;
6362   int ret;
6363
6364   /* Parse args required to build the message */
6365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6366     {
6367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6368         sw_if_index_set = 1;
6369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "enable"))
6372         is_enable = 1;
6373       else if (unformat (i, "disable"))
6374         is_enable = 0;
6375       else
6376         break;
6377     }
6378
6379   if (sw_if_index_set == 0)
6380     {
6381       errmsg ("missing interface name or sw_if_index");
6382       return -99;
6383     }
6384
6385   /* Construct the API message */
6386   M (SW_INTERFACE_SET_VPATH, mp);
6387
6388   mp->sw_if_index = ntohl (sw_if_index);
6389   mp->enable = is_enable;
6390
6391   /* send it... */
6392   S (mp);
6393
6394   /* Wait for a reply... */
6395   W (ret);
6396   return ret;
6397 }
6398
6399 static int
6400 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6401 {
6402   unformat_input_t *i = vam->input;
6403   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6404   u32 sw_if_index = 0;
6405   u8 sw_if_index_set = 0;
6406   u8 is_enable = 1;
6407   u8 is_ipv6 = 0;
6408   int ret;
6409
6410   /* Parse args required to build the message */
6411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6412     {
6413       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6414         sw_if_index_set = 1;
6415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6416         sw_if_index_set = 1;
6417       else if (unformat (i, "enable"))
6418         is_enable = 1;
6419       else if (unformat (i, "disable"))
6420         is_enable = 0;
6421       else if (unformat (i, "ip4"))
6422         is_ipv6 = 0;
6423       else if (unformat (i, "ip6"))
6424         is_ipv6 = 1;
6425       else
6426         break;
6427     }
6428
6429   if (sw_if_index_set == 0)
6430     {
6431       errmsg ("missing interface name or sw_if_index");
6432       return -99;
6433     }
6434
6435   /* Construct the API message */
6436   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6437
6438   mp->sw_if_index = ntohl (sw_if_index);
6439   mp->enable = is_enable;
6440   mp->is_ipv6 = is_ipv6;
6441
6442   /* send it... */
6443   S (mp);
6444
6445   /* Wait for a reply... */
6446   W (ret);
6447   return ret;
6448 }
6449
6450 static int
6451 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_sw_interface_set_geneve_bypass_t *mp;
6455   u32 sw_if_index = 0;
6456   u8 sw_if_index_set = 0;
6457   u8 is_enable = 1;
6458   u8 is_ipv6 = 0;
6459   int ret;
6460
6461   /* Parse args required to build the message */
6462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6463     {
6464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6465         sw_if_index_set = 1;
6466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6467         sw_if_index_set = 1;
6468       else if (unformat (i, "enable"))
6469         is_enable = 1;
6470       else if (unformat (i, "disable"))
6471         is_enable = 0;
6472       else if (unformat (i, "ip4"))
6473         is_ipv6 = 0;
6474       else if (unformat (i, "ip6"))
6475         is_ipv6 = 1;
6476       else
6477         break;
6478     }
6479
6480   if (sw_if_index_set == 0)
6481     {
6482       errmsg ("missing interface name or sw_if_index");
6483       return -99;
6484     }
6485
6486   /* Construct the API message */
6487   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6488
6489   mp->sw_if_index = ntohl (sw_if_index);
6490   mp->enable = is_enable;
6491   mp->is_ipv6 = is_ipv6;
6492
6493   /* send it... */
6494   S (mp);
6495
6496   /* Wait for a reply... */
6497   W (ret);
6498   return ret;
6499 }
6500
6501 static int
6502 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6503 {
6504   unformat_input_t *i = vam->input;
6505   vl_api_sw_interface_set_l2_xconnect_t *mp;
6506   u32 rx_sw_if_index;
6507   u8 rx_sw_if_index_set = 0;
6508   u32 tx_sw_if_index;
6509   u8 tx_sw_if_index_set = 0;
6510   u8 enable = 1;
6511   int ret;
6512
6513   /* Parse args required to build the message */
6514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6515     {
6516       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6517         rx_sw_if_index_set = 1;
6518       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6519         tx_sw_if_index_set = 1;
6520       else if (unformat (i, "rx"))
6521         {
6522           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523             {
6524               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6525                             &rx_sw_if_index))
6526                 rx_sw_if_index_set = 1;
6527             }
6528           else
6529             break;
6530         }
6531       else if (unformat (i, "tx"))
6532         {
6533           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6534             {
6535               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6536                             &tx_sw_if_index))
6537                 tx_sw_if_index_set = 1;
6538             }
6539           else
6540             break;
6541         }
6542       else if (unformat (i, "enable"))
6543         enable = 1;
6544       else if (unformat (i, "disable"))
6545         enable = 0;
6546       else
6547         break;
6548     }
6549
6550   if (rx_sw_if_index_set == 0)
6551     {
6552       errmsg ("missing rx interface name or rx_sw_if_index");
6553       return -99;
6554     }
6555
6556   if (enable && (tx_sw_if_index_set == 0))
6557     {
6558       errmsg ("missing tx interface name or tx_sw_if_index");
6559       return -99;
6560     }
6561
6562   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6563
6564   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6565   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6566   mp->enable = enable;
6567
6568   S (mp);
6569   W (ret);
6570   return ret;
6571 }
6572
6573 static int
6574 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6575 {
6576   unformat_input_t *i = vam->input;
6577   vl_api_sw_interface_set_l2_bridge_t *mp;
6578   vl_api_l2_port_type_t port_type;
6579   u32 rx_sw_if_index;
6580   u8 rx_sw_if_index_set = 0;
6581   u32 bd_id;
6582   u8 bd_id_set = 0;
6583   u32 shg = 0;
6584   u8 enable = 1;
6585   int ret;
6586
6587   port_type = L2_API_PORT_TYPE_NORMAL;
6588
6589   /* Parse args required to build the message */
6590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6591     {
6592       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6593         rx_sw_if_index_set = 1;
6594       else if (unformat (i, "bd_id %d", &bd_id))
6595         bd_id_set = 1;
6596       else
6597         if (unformat
6598             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6599         rx_sw_if_index_set = 1;
6600       else if (unformat (i, "shg %d", &shg))
6601         ;
6602       else if (unformat (i, "bvi"))
6603         port_type = L2_API_PORT_TYPE_BVI;
6604       else if (unformat (i, "uu-fwd"))
6605         port_type = L2_API_PORT_TYPE_UU_FWD;
6606       else if (unformat (i, "enable"))
6607         enable = 1;
6608       else if (unformat (i, "disable"))
6609         enable = 0;
6610       else
6611         break;
6612     }
6613
6614   if (rx_sw_if_index_set == 0)
6615     {
6616       errmsg ("missing rx interface name or sw_if_index");
6617       return -99;
6618     }
6619
6620   if (enable && (bd_id_set == 0))
6621     {
6622       errmsg ("missing bridge domain");
6623       return -99;
6624     }
6625
6626   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6627
6628   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6629   mp->bd_id = ntohl (bd_id);
6630   mp->shg = (u8) shg;
6631   mp->port_type = ntohl (port_type);
6632   mp->enable = enable;
6633
6634   S (mp);
6635   W (ret);
6636   return ret;
6637 }
6638
6639 static int
6640 api_bridge_domain_dump (vat_main_t * vam)
6641 {
6642   unformat_input_t *i = vam->input;
6643   vl_api_bridge_domain_dump_t *mp;
6644   vl_api_control_ping_t *mp_ping;
6645   u32 bd_id = ~0;
6646   int ret;
6647
6648   /* Parse args required to build the message */
6649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6650     {
6651       if (unformat (i, "bd_id %d", &bd_id))
6652         ;
6653       else
6654         break;
6655     }
6656
6657   M (BRIDGE_DOMAIN_DUMP, mp);
6658   mp->bd_id = ntohl (bd_id);
6659   S (mp);
6660
6661   /* Use a control ping for synchronization */
6662   MPING (CONTROL_PING, mp_ping);
6663   S (mp_ping);
6664
6665   W (ret);
6666   return ret;
6667 }
6668
6669 static int
6670 api_bridge_domain_add_del (vat_main_t * vam)
6671 {
6672   unformat_input_t *i = vam->input;
6673   vl_api_bridge_domain_add_del_t *mp;
6674   u32 bd_id = ~0;
6675   u8 is_add = 1;
6676   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6677   u8 *bd_tag = NULL;
6678   u32 mac_age = 0;
6679   int ret;
6680
6681   /* Parse args required to build the message */
6682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6683     {
6684       if (unformat (i, "bd_id %d", &bd_id))
6685         ;
6686       else if (unformat (i, "flood %d", &flood))
6687         ;
6688       else if (unformat (i, "uu-flood %d", &uu_flood))
6689         ;
6690       else if (unformat (i, "forward %d", &forward))
6691         ;
6692       else if (unformat (i, "learn %d", &learn))
6693         ;
6694       else if (unformat (i, "arp-term %d", &arp_term))
6695         ;
6696       else if (unformat (i, "mac-age %d", &mac_age))
6697         ;
6698       else if (unformat (i, "bd-tag %s", &bd_tag))
6699         ;
6700       else if (unformat (i, "del"))
6701         {
6702           is_add = 0;
6703           flood = uu_flood = forward = learn = 0;
6704         }
6705       else
6706         break;
6707     }
6708
6709   if (bd_id == ~0)
6710     {
6711       errmsg ("missing bridge domain");
6712       ret = -99;
6713       goto done;
6714     }
6715
6716   if (mac_age > 255)
6717     {
6718       errmsg ("mac age must be less than 256 ");
6719       ret = -99;
6720       goto done;
6721     }
6722
6723   if ((bd_tag) && (vec_len (bd_tag) > 63))
6724     {
6725       errmsg ("bd-tag cannot be longer than 63");
6726       ret = -99;
6727       goto done;
6728     }
6729
6730   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6731
6732   mp->bd_id = ntohl (bd_id);
6733   mp->flood = flood;
6734   mp->uu_flood = uu_flood;
6735   mp->forward = forward;
6736   mp->learn = learn;
6737   mp->arp_term = arp_term;
6738   mp->is_add = is_add;
6739   mp->mac_age = (u8) mac_age;
6740   if (bd_tag)
6741     {
6742       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6743       mp->bd_tag[vec_len (bd_tag)] = 0;
6744     }
6745   S (mp);
6746   W (ret);
6747
6748 done:
6749   vec_free (bd_tag);
6750   return ret;
6751 }
6752
6753 static int
6754 api_l2fib_flush_bd (vat_main_t * vam)
6755 {
6756   unformat_input_t *i = vam->input;
6757   vl_api_l2fib_flush_bd_t *mp;
6758   u32 bd_id = ~0;
6759   int ret;
6760
6761   /* Parse args required to build the message */
6762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6763     {
6764       if (unformat (i, "bd_id %d", &bd_id));
6765       else
6766         break;
6767     }
6768
6769   if (bd_id == ~0)
6770     {
6771       errmsg ("missing bridge domain");
6772       return -99;
6773     }
6774
6775   M (L2FIB_FLUSH_BD, mp);
6776
6777   mp->bd_id = htonl (bd_id);
6778
6779   S (mp);
6780   W (ret);
6781   return ret;
6782 }
6783
6784 static int
6785 api_l2fib_flush_int (vat_main_t * vam)
6786 {
6787   unformat_input_t *i = vam->input;
6788   vl_api_l2fib_flush_int_t *mp;
6789   u32 sw_if_index = ~0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "sw_if_index %d", &sw_if_index));
6796       else
6797         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6798       else
6799         break;
6800     }
6801
6802   if (sw_if_index == ~0)
6803     {
6804       errmsg ("missing interface name or sw_if_index");
6805       return -99;
6806     }
6807
6808   M (L2FIB_FLUSH_INT, mp);
6809
6810   mp->sw_if_index = ntohl (sw_if_index);
6811
6812   S (mp);
6813   W (ret);
6814   return ret;
6815 }
6816
6817 static int
6818 api_l2fib_add_del (vat_main_t * vam)
6819 {
6820   unformat_input_t *i = vam->input;
6821   vl_api_l2fib_add_del_t *mp;
6822   f64 timeout;
6823   u8 mac[6] = { 0 };
6824   u8 mac_set = 0;
6825   u32 bd_id;
6826   u8 bd_id_set = 0;
6827   u32 sw_if_index = 0;
6828   u8 sw_if_index_set = 0;
6829   u8 is_add = 1;
6830   u8 static_mac = 0;
6831   u8 filter_mac = 0;
6832   u8 bvi_mac = 0;
6833   int count = 1;
6834   f64 before = 0;
6835   int j;
6836
6837   /* Parse args required to build the message */
6838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839     {
6840       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6841         mac_set = 1;
6842       else if (unformat (i, "bd_id %d", &bd_id))
6843         bd_id_set = 1;
6844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6845         sw_if_index_set = 1;
6846       else if (unformat (i, "sw_if"))
6847         {
6848           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6849             {
6850               if (unformat
6851                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6852                 sw_if_index_set = 1;
6853             }
6854           else
6855             break;
6856         }
6857       else if (unformat (i, "static"))
6858         static_mac = 1;
6859       else if (unformat (i, "filter"))
6860         {
6861           filter_mac = 1;
6862           static_mac = 1;
6863         }
6864       else if (unformat (i, "bvi"))
6865         {
6866           bvi_mac = 1;
6867           static_mac = 1;
6868         }
6869       else if (unformat (i, "del"))
6870         is_add = 0;
6871       else if (unformat (i, "count %d", &count))
6872         ;
6873       else
6874         break;
6875     }
6876
6877   if (mac_set == 0)
6878     {
6879       errmsg ("missing mac address");
6880       return -99;
6881     }
6882
6883   if (bd_id_set == 0)
6884     {
6885       errmsg ("missing bridge domain");
6886       return -99;
6887     }
6888
6889   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6890     {
6891       errmsg ("missing interface name or sw_if_index");
6892       return -99;
6893     }
6894
6895   if (count > 1)
6896     {
6897       /* Turn on async mode */
6898       vam->async_mode = 1;
6899       vam->async_errors = 0;
6900       before = vat_time_now (vam);
6901     }
6902
6903   for (j = 0; j < count; j++)
6904     {
6905       M (L2FIB_ADD_DEL, mp);
6906
6907       clib_memcpy (mp->mac, mac, 6);
6908       mp->bd_id = ntohl (bd_id);
6909       mp->is_add = is_add;
6910       mp->sw_if_index = ntohl (sw_if_index);
6911
6912       if (is_add)
6913         {
6914           mp->static_mac = static_mac;
6915           mp->filter_mac = filter_mac;
6916           mp->bvi_mac = bvi_mac;
6917         }
6918       increment_mac_address (mac);
6919       /* send it... */
6920       S (mp);
6921     }
6922
6923   if (count > 1)
6924     {
6925       vl_api_control_ping_t *mp_ping;
6926       f64 after;
6927
6928       /* Shut off async mode */
6929       vam->async_mode = 0;
6930
6931       MPING (CONTROL_PING, mp_ping);
6932       S (mp_ping);
6933
6934       timeout = vat_time_now (vam) + 1.0;
6935       while (vat_time_now (vam) < timeout)
6936         if (vam->result_ready == 1)
6937           goto out;
6938       vam->retval = -99;
6939
6940     out:
6941       if (vam->retval == -99)
6942         errmsg ("timeout");
6943
6944       if (vam->async_errors > 0)
6945         {
6946           errmsg ("%d asynchronous errors", vam->async_errors);
6947           vam->retval = -98;
6948         }
6949       vam->async_errors = 0;
6950       after = vat_time_now (vam);
6951
6952       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6953              count, after - before, count / (after - before));
6954     }
6955   else
6956     {
6957       int ret;
6958
6959       /* Wait for a reply... */
6960       W (ret);
6961       return ret;
6962     }
6963   /* Return the good/bad news */
6964   return (vam->retval);
6965 }
6966
6967 static int
6968 api_bridge_domain_set_mac_age (vat_main_t * vam)
6969 {
6970   unformat_input_t *i = vam->input;
6971   vl_api_bridge_domain_set_mac_age_t *mp;
6972   u32 bd_id = ~0;
6973   u32 mac_age = 0;
6974   int ret;
6975
6976   /* Parse args required to build the message */
6977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6978     {
6979       if (unformat (i, "bd_id %d", &bd_id));
6980       else if (unformat (i, "mac-age %d", &mac_age));
6981       else
6982         break;
6983     }
6984
6985   if (bd_id == ~0)
6986     {
6987       errmsg ("missing bridge domain");
6988       return -99;
6989     }
6990
6991   if (mac_age > 255)
6992     {
6993       errmsg ("mac age must be less than 256 ");
6994       return -99;
6995     }
6996
6997   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6998
6999   mp->bd_id = htonl (bd_id);
7000   mp->mac_age = (u8) mac_age;
7001
7002   S (mp);
7003   W (ret);
7004   return ret;
7005 }
7006
7007 static int
7008 api_l2_flags (vat_main_t * vam)
7009 {
7010   unformat_input_t *i = vam->input;
7011   vl_api_l2_flags_t *mp;
7012   u32 sw_if_index;
7013   u32 flags = 0;
7014   u8 sw_if_index_set = 0;
7015   u8 is_set = 0;
7016   int ret;
7017
7018   /* Parse args required to build the message */
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "sw_if_index %d", &sw_if_index))
7022         sw_if_index_set = 1;
7023       else if (unformat (i, "sw_if"))
7024         {
7025           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7026             {
7027               if (unformat
7028                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7029                 sw_if_index_set = 1;
7030             }
7031           else
7032             break;
7033         }
7034       else if (unformat (i, "learn"))
7035         flags |= L2_LEARN;
7036       else if (unformat (i, "forward"))
7037         flags |= L2_FWD;
7038       else if (unformat (i, "flood"))
7039         flags |= L2_FLOOD;
7040       else if (unformat (i, "uu-flood"))
7041         flags |= L2_UU_FLOOD;
7042       else if (unformat (i, "arp-term"))
7043         flags |= L2_ARP_TERM;
7044       else if (unformat (i, "off"))
7045         is_set = 0;
7046       else if (unformat (i, "disable"))
7047         is_set = 0;
7048       else
7049         break;
7050     }
7051
7052   if (sw_if_index_set == 0)
7053     {
7054       errmsg ("missing interface name or sw_if_index");
7055       return -99;
7056     }
7057
7058   M (L2_FLAGS, mp);
7059
7060   mp->sw_if_index = ntohl (sw_if_index);
7061   mp->feature_bitmap = ntohl (flags);
7062   mp->is_set = is_set;
7063
7064   S (mp);
7065   W (ret);
7066   return ret;
7067 }
7068
7069 static int
7070 api_bridge_flags (vat_main_t * vam)
7071 {
7072   unformat_input_t *i = vam->input;
7073   vl_api_bridge_flags_t *mp;
7074   u32 bd_id;
7075   u8 bd_id_set = 0;
7076   u8 is_set = 1;
7077   bd_flags_t flags = 0;
7078   int ret;
7079
7080   /* Parse args required to build the message */
7081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7082     {
7083       if (unformat (i, "bd_id %d", &bd_id))
7084         bd_id_set = 1;
7085       else if (unformat (i, "learn"))
7086         flags |= BRIDGE_API_FLAG_LEARN;
7087       else if (unformat (i, "forward"))
7088         flags |= BRIDGE_API_FLAG_FWD;
7089       else if (unformat (i, "flood"))
7090         flags |= BRIDGE_API_FLAG_FLOOD;
7091       else if (unformat (i, "uu-flood"))
7092         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7093       else if (unformat (i, "arp-term"))
7094         flags |= BRIDGE_API_FLAG_ARP_TERM;
7095       else if (unformat (i, "off"))
7096         is_set = 0;
7097       else if (unformat (i, "disable"))
7098         is_set = 0;
7099       else
7100         break;
7101     }
7102
7103   if (bd_id_set == 0)
7104     {
7105       errmsg ("missing bridge domain");
7106       return -99;
7107     }
7108
7109   M (BRIDGE_FLAGS, mp);
7110
7111   mp->bd_id = ntohl (bd_id);
7112   mp->flags = ntohl (flags);
7113   mp->is_set = is_set;
7114
7115   S (mp);
7116   W (ret);
7117   return ret;
7118 }
7119
7120 static int
7121 api_bd_ip_mac_add_del (vat_main_t * vam)
7122 {
7123   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7124   vl_api_mac_address_t mac = { 0 };
7125   unformat_input_t *i = vam->input;
7126   vl_api_bd_ip_mac_add_del_t *mp;
7127   u32 bd_id;
7128   u8 is_add = 1;
7129   u8 bd_id_set = 0;
7130   u8 ip_set = 0;
7131   u8 mac_set = 0;
7132   int ret;
7133
7134
7135   /* Parse args required to build the message */
7136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7137     {
7138       if (unformat (i, "bd_id %d", &bd_id))
7139         {
7140           bd_id_set++;
7141         }
7142       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7143         {
7144           ip_set++;
7145         }
7146       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7147         {
7148           mac_set++;
7149         }
7150       else if (unformat (i, "del"))
7151         is_add = 0;
7152       else
7153         break;
7154     }
7155
7156   if (bd_id_set == 0)
7157     {
7158       errmsg ("missing bridge domain");
7159       return -99;
7160     }
7161   else if (ip_set == 0)
7162     {
7163       errmsg ("missing IP address");
7164       return -99;
7165     }
7166   else if (mac_set == 0)
7167     {
7168       errmsg ("missing MAC address");
7169       return -99;
7170     }
7171
7172   M (BD_IP_MAC_ADD_DEL, mp);
7173
7174   mp->entry.bd_id = ntohl (bd_id);
7175   mp->is_add = is_add;
7176
7177   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7178   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7179
7180   S (mp);
7181   W (ret);
7182   return ret;
7183 }
7184
7185 static int
7186 api_bd_ip_mac_flush (vat_main_t * vam)
7187 {
7188   unformat_input_t *i = vam->input;
7189   vl_api_bd_ip_mac_flush_t *mp;
7190   u32 bd_id;
7191   u8 bd_id_set = 0;
7192   int ret;
7193
7194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7195     {
7196       if (unformat (i, "bd_id %d", &bd_id))
7197         {
7198           bd_id_set++;
7199         }
7200       else
7201         break;
7202     }
7203
7204   if (bd_id_set == 0)
7205     {
7206       errmsg ("missing bridge domain");
7207       return -99;
7208     }
7209
7210   M (BD_IP_MAC_FLUSH, mp);
7211
7212   mp->bd_id = ntohl (bd_id);
7213
7214   S (mp);
7215   W (ret);
7216   return ret;
7217 }
7218
7219 static void vl_api_bd_ip_mac_details_t_handler
7220   (vl_api_bd_ip_mac_details_t * mp)
7221 {
7222   vat_main_t *vam = &vat_main;
7223
7224   print (vam->ofp,
7225          "\n%-5d %U %U",
7226          ntohl (mp->entry.bd_id),
7227          format_vl_api_mac_address, mp->entry.mac,
7228          format_vl_api_address, &mp->entry.ip);
7229 }
7230
7231 static void vl_api_bd_ip_mac_details_t_handler_json
7232   (vl_api_bd_ip_mac_details_t * mp)
7233 {
7234   vat_main_t *vam = &vat_main;
7235   vat_json_node_t *node = NULL;
7236
7237   if (VAT_JSON_ARRAY != vam->json_tree.type)
7238     {
7239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7240       vat_json_init_array (&vam->json_tree);
7241     }
7242   node = vat_json_array_add (&vam->json_tree);
7243
7244   vat_json_init_object (node);
7245   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7246   vat_json_object_add_string_copy (node, "mac_address",
7247                                    format (0, "%U", format_vl_api_mac_address,
7248                                            &mp->entry.mac));
7249   u8 *ip = 0;
7250
7251   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7252   vat_json_object_add_string_copy (node, "ip_address", ip);
7253   vec_free (ip);
7254 }
7255
7256 static int
7257 api_bd_ip_mac_dump (vat_main_t * vam)
7258 {
7259   unformat_input_t *i = vam->input;
7260   vl_api_bd_ip_mac_dump_t *mp;
7261   vl_api_control_ping_t *mp_ping;
7262   int ret;
7263   u32 bd_id;
7264   u8 bd_id_set = 0;
7265
7266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7267     {
7268       if (unformat (i, "bd_id %d", &bd_id))
7269         {
7270           bd_id_set++;
7271         }
7272       else
7273         break;
7274     }
7275
7276   print (vam->ofp,
7277          "\n%-5s %-7s %-20s %-30s",
7278          "bd_id", "is_ipv6", "mac_address", "ip_address");
7279
7280   /* Dump Bridge Domain Ip to Mac entries */
7281   M (BD_IP_MAC_DUMP, mp);
7282
7283   if (bd_id_set)
7284     mp->bd_id = htonl (bd_id);
7285   else
7286     mp->bd_id = ~0;
7287
7288   S (mp);
7289
7290   /* Use a control ping for synchronization */
7291   MPING (CONTROL_PING, mp_ping);
7292   S (mp_ping);
7293
7294   W (ret);
7295   return ret;
7296 }
7297
7298 static int
7299 api_tap_create_v2 (vat_main_t * vam)
7300 {
7301   unformat_input_t *i = vam->input;
7302   vl_api_tap_create_v2_t *mp;
7303   u8 mac_address[6];
7304   u8 random_mac = 1;
7305   u32 id = ~0;
7306   u32 num_rx_queues = 0;
7307   u8 *host_if_name = 0;
7308   u8 host_if_name_set = 0;
7309   u8 *host_ns = 0;
7310   u8 host_ns_set = 0;
7311   u8 host_mac_addr[6];
7312   u8 host_mac_addr_set = 0;
7313   u8 *host_bridge = 0;
7314   u8 host_bridge_set = 0;
7315   u8 host_ip4_prefix_set = 0;
7316   u8 host_ip6_prefix_set = 0;
7317   ip4_address_t host_ip4_addr;
7318   ip4_address_t host_ip4_gw;
7319   u8 host_ip4_gw_set = 0;
7320   u32 host_ip4_prefix_len = 0;
7321   ip6_address_t host_ip6_addr;
7322   ip6_address_t host_ip6_gw;
7323   u8 host_ip6_gw_set = 0;
7324   u32 host_ip6_prefix_len = 0;
7325   u32 host_mtu_size = 0;
7326   u8 host_mtu_set = 0;
7327   u32 tap_flags = 0;
7328   int ret;
7329   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7330
7331   clib_memset (mac_address, 0, sizeof (mac_address));
7332
7333   /* Parse args required to build the message */
7334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7335     {
7336       if (unformat (i, "id %u", &id))
7337         ;
7338       else
7339         if (unformat
7340             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7341         random_mac = 0;
7342       else if (unformat (i, "host-if-name %s", &host_if_name))
7343         host_if_name_set = 1;
7344       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7345         ;
7346       else if (unformat (i, "host-ns %s", &host_ns))
7347         host_ns_set = 1;
7348       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7349                          host_mac_addr))
7350         host_mac_addr_set = 1;
7351       else if (unformat (i, "host-bridge %s", &host_bridge))
7352         host_bridge_set = 1;
7353       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7354                          &host_ip4_addr, &host_ip4_prefix_len))
7355         host_ip4_prefix_set = 1;
7356       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7357                          &host_ip6_addr, &host_ip6_prefix_len))
7358         host_ip6_prefix_set = 1;
7359       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7360                          &host_ip4_gw))
7361         host_ip4_gw_set = 1;
7362       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7363                          &host_ip6_gw))
7364         host_ip6_gw_set = 1;
7365       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7366         ;
7367       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7368         ;
7369       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7370         host_mtu_set = 1;
7371       else if (unformat (i, "no-gso"))
7372         tap_flags &= ~TAP_FLAG_GSO;
7373       else if (unformat (i, "gso"))
7374         tap_flags |= TAP_FLAG_GSO;
7375       else if (unformat (i, "csum-offload"))
7376         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7377       else if (unformat (i, "persist"))
7378         tap_flags |= TAP_FLAG_PERSIST;
7379       else if (unformat (i, "attach"))
7380         tap_flags |= TAP_FLAG_ATTACH;
7381       else
7382         break;
7383     }
7384
7385   if (vec_len (host_if_name) > 63)
7386     {
7387       errmsg ("tap name too long. ");
7388       return -99;
7389     }
7390   if (vec_len (host_ns) > 63)
7391     {
7392       errmsg ("host name space too long. ");
7393       return -99;
7394     }
7395   if (vec_len (host_bridge) > 63)
7396     {
7397       errmsg ("host bridge name too long. ");
7398       return -99;
7399     }
7400   if (host_ip4_prefix_len > 32)
7401     {
7402       errmsg ("host ip4 prefix length not valid. ");
7403       return -99;
7404     }
7405   if (host_ip6_prefix_len > 128)
7406     {
7407       errmsg ("host ip6 prefix length not valid. ");
7408       return -99;
7409     }
7410   if (!is_pow2 (rx_ring_sz))
7411     {
7412       errmsg ("rx ring size must be power of 2. ");
7413       return -99;
7414     }
7415   if (rx_ring_sz > 32768)
7416     {
7417       errmsg ("rx ring size must be 32768 or lower. ");
7418       return -99;
7419     }
7420   if (!is_pow2 (tx_ring_sz))
7421     {
7422       errmsg ("tx ring size must be power of 2. ");
7423       return -99;
7424     }
7425   if (tx_ring_sz > 32768)
7426     {
7427       errmsg ("tx ring size must be 32768 or lower. ");
7428       return -99;
7429     }
7430   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7431     {
7432       errmsg ("host MTU size must be in between 64 and 65355. ");
7433       return -99;
7434     }
7435
7436   /* Construct the API message */
7437   M (TAP_CREATE_V2, mp);
7438
7439   mp->id = ntohl (id);
7440   mp->use_random_mac = random_mac;
7441   mp->num_rx_queues = (u8) num_rx_queues;
7442   mp->tx_ring_sz = ntohs (tx_ring_sz);
7443   mp->rx_ring_sz = ntohs (rx_ring_sz);
7444   mp->host_mtu_set = host_mtu_set;
7445   mp->host_mtu_size = ntohl (host_mtu_size);
7446   mp->host_mac_addr_set = host_mac_addr_set;
7447   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7448   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7449   mp->host_ip4_gw_set = host_ip4_gw_set;
7450   mp->host_ip6_gw_set = host_ip6_gw_set;
7451   mp->tap_flags = ntohl (tap_flags);
7452   mp->host_namespace_set = host_ns_set;
7453   mp->host_if_name_set = host_if_name_set;
7454   mp->host_bridge_set = host_bridge_set;
7455
7456   if (random_mac == 0)
7457     clib_memcpy (mp->mac_address, mac_address, 6);
7458   if (host_mac_addr_set)
7459     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7460   if (host_if_name_set)
7461     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7462   if (host_ns_set)
7463     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7464   if (host_bridge_set)
7465     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7466   if (host_ip4_prefix_set)
7467     {
7468       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7469       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7470     }
7471   if (host_ip6_prefix_set)
7472     {
7473       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7474       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7475     }
7476   if (host_ip4_gw_set)
7477     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7478   if (host_ip6_gw_set)
7479     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7480
7481   vec_free (host_ns);
7482   vec_free (host_if_name);
7483   vec_free (host_bridge);
7484
7485   /* send it... */
7486   S (mp);
7487
7488   /* Wait for a reply... */
7489   W (ret);
7490   return ret;
7491 }
7492
7493 static int
7494 api_tap_delete_v2 (vat_main_t * vam)
7495 {
7496   unformat_input_t *i = vam->input;
7497   vl_api_tap_delete_v2_t *mp;
7498   u32 sw_if_index = ~0;
7499   u8 sw_if_index_set = 0;
7500   int ret;
7501
7502   /* Parse args required to build the message */
7503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7504     {
7505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7506         sw_if_index_set = 1;
7507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7508         sw_if_index_set = 1;
7509       else
7510         break;
7511     }
7512
7513   if (sw_if_index_set == 0)
7514     {
7515       errmsg ("missing vpp interface name. ");
7516       return -99;
7517     }
7518
7519   /* Construct the API message */
7520   M (TAP_DELETE_V2, mp);
7521
7522   mp->sw_if_index = ntohl (sw_if_index);
7523
7524   /* send it... */
7525   S (mp);
7526
7527   /* Wait for a reply... */
7528   W (ret);
7529   return ret;
7530 }
7531
7532 uword
7533 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7534 {
7535   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7536   u32 x[4];
7537
7538   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7539     return 0;
7540
7541   addr->domain = x[0];
7542   addr->bus = x[1];
7543   addr->slot = x[2];
7544   addr->function = x[3];
7545
7546   return 1;
7547 }
7548
7549 static int
7550 api_virtio_pci_create (vat_main_t * vam)
7551 {
7552   unformat_input_t *i = vam->input;
7553   vl_api_virtio_pci_create_t *mp;
7554   u8 mac_address[6];
7555   u8 random_mac = 1;
7556   u8 gso_enabled = 0;
7557   u8 checksum_offload_enabled = 0;
7558   u32 pci_addr = 0;
7559   u64 features = (u64) ~ (0ULL);
7560   int ret;
7561
7562   clib_memset (mac_address, 0, sizeof (mac_address));
7563
7564   /* Parse args required to build the message */
7565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7566     {
7567       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7568         {
7569           random_mac = 0;
7570         }
7571       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7572         ;
7573       else if (unformat (i, "features 0x%llx", &features))
7574         ;
7575       else if (unformat (i, "gso-enabled"))
7576         gso_enabled = 1;
7577       else if (unformat (i, "csum-offload-enabled"))
7578         checksum_offload_enabled = 1;
7579       else
7580         break;
7581     }
7582
7583   if (pci_addr == 0)
7584     {
7585       errmsg ("pci address must be non zero. ");
7586       return -99;
7587     }
7588
7589   /* Construct the API message */
7590   M (VIRTIO_PCI_CREATE, mp);
7591
7592   mp->use_random_mac = random_mac;
7593
7594   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7595   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7596   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7597   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7598
7599   mp->features = clib_host_to_net_u64 (features);
7600   mp->gso_enabled = gso_enabled;
7601   mp->checksum_offload_enabled = checksum_offload_enabled;
7602
7603   if (random_mac == 0)
7604     clib_memcpy (mp->mac_address, mac_address, 6);
7605
7606   /* send it... */
7607   S (mp);
7608
7609   /* Wait for a reply... */
7610   W (ret);
7611   return ret;
7612 }
7613
7614 static int
7615 api_virtio_pci_delete (vat_main_t * vam)
7616 {
7617   unformat_input_t *i = vam->input;
7618   vl_api_virtio_pci_delete_t *mp;
7619   u32 sw_if_index = ~0;
7620   u8 sw_if_index_set = 0;
7621   int ret;
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7629         sw_if_index_set = 1;
7630       else
7631         break;
7632     }
7633
7634   if (sw_if_index_set == 0)
7635     {
7636       errmsg ("missing vpp interface name. ");
7637       return -99;
7638     }
7639
7640   /* Construct the API message */
7641   M (VIRTIO_PCI_DELETE, mp);
7642
7643   mp->sw_if_index = htonl (sw_if_index);
7644
7645   /* send it... */
7646   S (mp);
7647
7648   /* Wait for a reply... */
7649   W (ret);
7650   return ret;
7651 }
7652
7653 static int
7654 api_bond_create (vat_main_t * vam)
7655 {
7656   unformat_input_t *i = vam->input;
7657   vl_api_bond_create_t *mp;
7658   u8 mac_address[6];
7659   u8 custom_mac = 0;
7660   int ret;
7661   u8 mode;
7662   u8 lb;
7663   u8 mode_is_set = 0;
7664   u32 id = ~0;
7665   u8 numa_only = 0;
7666
7667   clib_memset (mac_address, 0, sizeof (mac_address));
7668   lb = BOND_LB_L2;
7669
7670   /* Parse args required to build the message */
7671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7674         mode_is_set = 1;
7675       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7676                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7677         ;
7678       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7679                          mac_address))
7680         custom_mac = 1;
7681       else if (unformat (i, "numa-only"))
7682         numa_only = 1;
7683       else if (unformat (i, "id %u", &id))
7684         ;
7685       else
7686         break;
7687     }
7688
7689   if (mode_is_set == 0)
7690     {
7691       errmsg ("Missing bond mode. ");
7692       return -99;
7693     }
7694
7695   /* Construct the API message */
7696   M (BOND_CREATE, mp);
7697
7698   mp->use_custom_mac = custom_mac;
7699
7700   mp->mode = htonl (mode);
7701   mp->lb = htonl (lb);
7702   mp->id = htonl (id);
7703   mp->numa_only = numa_only;
7704
7705   if (custom_mac)
7706     clib_memcpy (mp->mac_address, mac_address, 6);
7707
7708   /* send it... */
7709   S (mp);
7710
7711   /* Wait for a reply... */
7712   W (ret);
7713   return ret;
7714 }
7715
7716 static int
7717 api_bond_delete (vat_main_t * vam)
7718 {
7719   unformat_input_t *i = vam->input;
7720   vl_api_bond_delete_t *mp;
7721   u32 sw_if_index = ~0;
7722   u8 sw_if_index_set = 0;
7723   int ret;
7724
7725   /* Parse args required to build the message */
7726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7727     {
7728       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7729         sw_if_index_set = 1;
7730       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7731         sw_if_index_set = 1;
7732       else
7733         break;
7734     }
7735
7736   if (sw_if_index_set == 0)
7737     {
7738       errmsg ("missing vpp interface name. ");
7739       return -99;
7740     }
7741
7742   /* Construct the API message */
7743   M (BOND_DELETE, mp);
7744
7745   mp->sw_if_index = ntohl (sw_if_index);
7746
7747   /* send it... */
7748   S (mp);
7749
7750   /* Wait for a reply... */
7751   W (ret);
7752   return ret;
7753 }
7754
7755 static int
7756 api_bond_enslave (vat_main_t * vam)
7757 {
7758   unformat_input_t *i = vam->input;
7759   vl_api_bond_enslave_t *mp;
7760   u32 bond_sw_if_index;
7761   int ret;
7762   u8 is_passive;
7763   u8 is_long_timeout;
7764   u32 bond_sw_if_index_is_set = 0;
7765   u32 sw_if_index;
7766   u8 sw_if_index_is_set = 0;
7767
7768   /* Parse args required to build the message */
7769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7770     {
7771       if (unformat (i, "sw_if_index %d", &sw_if_index))
7772         sw_if_index_is_set = 1;
7773       else if (unformat (i, "bond %u", &bond_sw_if_index))
7774         bond_sw_if_index_is_set = 1;
7775       else if (unformat (i, "passive %d", &is_passive))
7776         ;
7777       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7778         ;
7779       else
7780         break;
7781     }
7782
7783   if (bond_sw_if_index_is_set == 0)
7784     {
7785       errmsg ("Missing bond sw_if_index. ");
7786       return -99;
7787     }
7788   if (sw_if_index_is_set == 0)
7789     {
7790       errmsg ("Missing slave sw_if_index. ");
7791       return -99;
7792     }
7793
7794   /* Construct the API message */
7795   M (BOND_ENSLAVE, mp);
7796
7797   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7798   mp->sw_if_index = ntohl (sw_if_index);
7799   mp->is_long_timeout = is_long_timeout;
7800   mp->is_passive = is_passive;
7801
7802   /* send it... */
7803   S (mp);
7804
7805   /* Wait for a reply... */
7806   W (ret);
7807   return ret;
7808 }
7809
7810 static int
7811 api_bond_detach_slave (vat_main_t * vam)
7812 {
7813   unformat_input_t *i = vam->input;
7814   vl_api_bond_detach_slave_t *mp;
7815   u32 sw_if_index = ~0;
7816   u8 sw_if_index_set = 0;
7817   int ret;
7818
7819   /* Parse args required to build the message */
7820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7821     {
7822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7823         sw_if_index_set = 1;
7824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7825         sw_if_index_set = 1;
7826       else
7827         break;
7828     }
7829
7830   if (sw_if_index_set == 0)
7831     {
7832       errmsg ("missing vpp interface name. ");
7833       return -99;
7834     }
7835
7836   /* Construct the API message */
7837   M (BOND_DETACH_SLAVE, mp);
7838
7839   mp->sw_if_index = ntohl (sw_if_index);
7840
7841   /* send it... */
7842   S (mp);
7843
7844   /* Wait for a reply... */
7845   W (ret);
7846   return ret;
7847 }
7848
7849 static int
7850 api_ip_table_add_del (vat_main_t * vam)
7851 {
7852   unformat_input_t *i = vam->input;
7853   vl_api_ip_table_add_del_t *mp;
7854   u32 table_id = ~0;
7855   u8 is_ipv6 = 0;
7856   u8 is_add = 1;
7857   int ret = 0;
7858
7859   /* Parse args required to build the message */
7860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7861     {
7862       if (unformat (i, "ipv6"))
7863         is_ipv6 = 1;
7864       else if (unformat (i, "del"))
7865         is_add = 0;
7866       else if (unformat (i, "add"))
7867         is_add = 1;
7868       else if (unformat (i, "table %d", &table_id))
7869         ;
7870       else
7871         {
7872           clib_warning ("parse error '%U'", format_unformat_error, i);
7873           return -99;
7874         }
7875     }
7876
7877   if (~0 == table_id)
7878     {
7879       errmsg ("missing table-ID");
7880       return -99;
7881     }
7882
7883   /* Construct the API message */
7884   M (IP_TABLE_ADD_DEL, mp);
7885
7886   mp->table.table_id = ntohl (table_id);
7887   mp->table.is_ip6 = is_ipv6;
7888   mp->is_add = is_add;
7889
7890   /* send it... */
7891   S (mp);
7892
7893   /* Wait for a reply... */
7894   W (ret);
7895
7896   return ret;
7897 }
7898
7899 uword
7900 unformat_fib_path (unformat_input_t * input, va_list * args)
7901 {
7902   vat_main_t *vam = va_arg (*args, vat_main_t *);
7903   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7904   u32 weight, preference;
7905   mpls_label_t out_label;
7906
7907   clib_memset (path, 0, sizeof (*path));
7908   path->weight = 1;
7909   path->sw_if_index = ~0;
7910   path->rpf_id = ~0;
7911   path->n_labels = 0;
7912
7913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7914     {
7915       if (unformat (input, "%U %U",
7916                     unformat_vl_api_ip4_address,
7917                     &path->nh.address.ip4,
7918                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7919         {
7920           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7921         }
7922       else if (unformat (input, "%U %U",
7923                          unformat_vl_api_ip6_address,
7924                          &path->nh.address.ip6,
7925                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7926         {
7927           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7928         }
7929       else if (unformat (input, "weight %u", &weight))
7930         {
7931           path->weight = weight;
7932         }
7933       else if (unformat (input, "preference %u", &preference))
7934         {
7935           path->preference = preference;
7936         }
7937       else if (unformat (input, "%U next-hop-table %d",
7938                          unformat_vl_api_ip4_address,
7939                          &path->nh.address.ip4, &path->table_id))
7940         {
7941           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7942         }
7943       else if (unformat (input, "%U next-hop-table %d",
7944                          unformat_vl_api_ip6_address,
7945                          &path->nh.address.ip6, &path->table_id))
7946         {
7947           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7948         }
7949       else if (unformat (input, "%U",
7950                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7951         {
7952           /*
7953            * the recursive next-hops are by default in the default table
7954            */
7955           path->table_id = 0;
7956           path->sw_if_index = ~0;
7957           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7958         }
7959       else if (unformat (input, "%U",
7960                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7961         {
7962           /*
7963            * the recursive next-hops are by default in the default table
7964            */
7965           path->table_id = 0;
7966           path->sw_if_index = ~0;
7967           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7968         }
7969       else if (unformat (input, "resolve-via-host"))
7970         {
7971           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7972         }
7973       else if (unformat (input, "resolve-via-attached"))
7974         {
7975           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7976         }
7977       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7978         {
7979           path->type = FIB_API_PATH_TYPE_LOCAL;
7980           path->sw_if_index = ~0;
7981           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7982         }
7983       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7984         {
7985           path->type = FIB_API_PATH_TYPE_LOCAL;
7986           path->sw_if_index = ~0;
7987           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7988         }
7989       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7990         ;
7991       else if (unformat (input, "via-label %d", &path->nh.via_label))
7992         {
7993           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7994           path->sw_if_index = ~0;
7995         }
7996       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7997         {
7998           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7999           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8000         }
8001       else if (unformat (input, "local"))
8002         {
8003           path->type = FIB_API_PATH_TYPE_LOCAL;
8004         }
8005       else if (unformat (input, "out-labels"))
8006         {
8007           while (unformat (input, "%d", &out_label))
8008             {
8009               path->label_stack[path->n_labels].label = out_label;
8010               path->label_stack[path->n_labels].is_uniform = 0;
8011               path->label_stack[path->n_labels].ttl = 64;
8012               path->n_labels++;
8013             }
8014         }
8015       else if (unformat (input, "via"))
8016         {
8017           /* new path, back up and return */
8018           unformat_put_input (input);
8019           unformat_put_input (input);
8020           unformat_put_input (input);
8021           unformat_put_input (input);
8022           break;
8023         }
8024       else
8025         {
8026           return (0);
8027         }
8028     }
8029
8030   path->proto = ntohl (path->proto);
8031   path->type = ntohl (path->type);
8032   path->flags = ntohl (path->flags);
8033   path->table_id = ntohl (path->table_id);
8034   path->sw_if_index = ntohl (path->sw_if_index);
8035
8036   return (1);
8037 }
8038
8039 static int
8040 api_ip_route_add_del (vat_main_t * vam)
8041 {
8042   unformat_input_t *i = vam->input;
8043   vl_api_ip_route_add_del_t *mp;
8044   u32 vrf_id = 0;
8045   u8 is_add = 1;
8046   u8 is_multipath = 0;
8047   u8 prefix_set = 0;
8048   u8 path_count = 0;
8049   vl_api_prefix_t pfx = { };
8050   vl_api_fib_path_t paths[8];
8051   int count = 1;
8052   int j;
8053   f64 before = 0;
8054   u32 random_add_del = 0;
8055   u32 *random_vector = 0;
8056   u32 random_seed = 0xdeaddabe;
8057
8058   /* Parse args required to build the message */
8059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8060     {
8061       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8062         prefix_set = 1;
8063       else if (unformat (i, "del"))
8064         is_add = 0;
8065       else if (unformat (i, "add"))
8066         is_add = 1;
8067       else if (unformat (i, "vrf %d", &vrf_id))
8068         ;
8069       else if (unformat (i, "count %d", &count))
8070         ;
8071       else if (unformat (i, "random"))
8072         random_add_del = 1;
8073       else if (unformat (i, "multipath"))
8074         is_multipath = 1;
8075       else if (unformat (i, "seed %d", &random_seed))
8076         ;
8077       else
8078         if (unformat
8079             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8080         {
8081           path_count++;
8082           if (8 == path_count)
8083             {
8084               errmsg ("max 8 paths");
8085               return -99;
8086             }
8087         }
8088       else
8089         {
8090           clib_warning ("parse error '%U'", format_unformat_error, i);
8091           return -99;
8092         }
8093     }
8094
8095   if (!path_count)
8096     {
8097       errmsg ("specify a path; via ...");
8098       return -99;
8099     }
8100   if (prefix_set == 0)
8101     {
8102       errmsg ("missing prefix");
8103       return -99;
8104     }
8105
8106   /* Generate a pile of unique, random routes */
8107   if (random_add_del)
8108     {
8109       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8110       u32 this_random_address;
8111       uword *random_hash;
8112
8113       random_hash = hash_create (count, sizeof (uword));
8114
8115       hash_set (random_hash, i->as_u32, 1);
8116       for (j = 0; j <= count; j++)
8117         {
8118           do
8119             {
8120               this_random_address = random_u32 (&random_seed);
8121               this_random_address =
8122                 clib_host_to_net_u32 (this_random_address);
8123             }
8124           while (hash_get (random_hash, this_random_address));
8125           vec_add1 (random_vector, this_random_address);
8126           hash_set (random_hash, this_random_address, 1);
8127         }
8128       hash_free (random_hash);
8129       set_ip4_address (&pfx.address, random_vector[0]);
8130     }
8131
8132   if (count > 1)
8133     {
8134       /* Turn on async mode */
8135       vam->async_mode = 1;
8136       vam->async_errors = 0;
8137       before = vat_time_now (vam);
8138     }
8139
8140   for (j = 0; j < count; j++)
8141     {
8142       /* Construct the API message */
8143       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8144
8145       mp->is_add = is_add;
8146       mp->is_multipath = is_multipath;
8147
8148       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8149       mp->route.table_id = ntohl (vrf_id);
8150       mp->route.n_paths = path_count;
8151
8152       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8153
8154       if (random_add_del)
8155         set_ip4_address (&pfx.address, random_vector[j + 1]);
8156       else
8157         increment_address (&pfx.address);
8158       /* send it... */
8159       S (mp);
8160       /* If we receive SIGTERM, stop now... */
8161       if (vam->do_exit)
8162         break;
8163     }
8164
8165   /* When testing multiple add/del ops, use a control-ping to sync */
8166   if (count > 1)
8167     {
8168       vl_api_control_ping_t *mp_ping;
8169       f64 after;
8170       f64 timeout;
8171
8172       /* Shut off async mode */
8173       vam->async_mode = 0;
8174
8175       MPING (CONTROL_PING, mp_ping);
8176       S (mp_ping);
8177
8178       timeout = vat_time_now (vam) + 1.0;
8179       while (vat_time_now (vam) < timeout)
8180         if (vam->result_ready == 1)
8181           goto out;
8182       vam->retval = -99;
8183
8184     out:
8185       if (vam->retval == -99)
8186         errmsg ("timeout");
8187
8188       if (vam->async_errors > 0)
8189         {
8190           errmsg ("%d asynchronous errors", vam->async_errors);
8191           vam->retval = -98;
8192         }
8193       vam->async_errors = 0;
8194       after = vat_time_now (vam);
8195
8196       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8197       if (j > 0)
8198         count = j;
8199
8200       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8201              count, after - before, count / (after - before));
8202     }
8203   else
8204     {
8205       int ret;
8206
8207       /* Wait for a reply... */
8208       W (ret);
8209       return ret;
8210     }
8211
8212   /* Return the good/bad news */
8213   return (vam->retval);
8214 }
8215
8216 static int
8217 api_ip_mroute_add_del (vat_main_t * vam)
8218 {
8219   unformat_input_t *i = vam->input;
8220   u8 path_set = 0, prefix_set = 0, is_add = 1;
8221   vl_api_ip_mroute_add_del_t *mp;
8222   mfib_entry_flags_t eflags = 0;
8223   vl_api_mfib_path_t path;
8224   vl_api_mprefix_t pfx = { };
8225   u32 vrf_id = 0;
8226   int ret;
8227
8228   /* Parse args required to build the message */
8229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8230     {
8231       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8232         {
8233           prefix_set = 1;
8234           pfx.grp_address_length = htons (pfx.grp_address_length);
8235         }
8236       else if (unformat (i, "del"))
8237         is_add = 0;
8238       else if (unformat (i, "add"))
8239         is_add = 1;
8240       else if (unformat (i, "vrf %d", &vrf_id))
8241         ;
8242       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8243         path.itf_flags = htonl (path.itf_flags);
8244       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8245         ;
8246       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8247         path_set = 1;
8248       else
8249         {
8250           clib_warning ("parse error '%U'", format_unformat_error, i);
8251           return -99;
8252         }
8253     }
8254
8255   if (prefix_set == 0)
8256     {
8257       errmsg ("missing addresses\n");
8258       return -99;
8259     }
8260   if (path_set == 0)
8261     {
8262       errmsg ("missing path\n");
8263       return -99;
8264     }
8265
8266   /* Construct the API message */
8267   M (IP_MROUTE_ADD_DEL, mp);
8268
8269   mp->is_add = is_add;
8270   mp->is_multipath = 1;
8271
8272   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8273   mp->route.table_id = htonl (vrf_id);
8274   mp->route.n_paths = 1;
8275   mp->route.entry_flags = htonl (eflags);
8276
8277   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8278
8279   /* send it... */
8280   S (mp);
8281   /* Wait for a reply... */
8282   W (ret);
8283   return ret;
8284 }
8285
8286 static int
8287 api_mpls_table_add_del (vat_main_t * vam)
8288 {
8289   unformat_input_t *i = vam->input;
8290   vl_api_mpls_table_add_del_t *mp;
8291   u32 table_id = ~0;
8292   u8 is_add = 1;
8293   int ret = 0;
8294
8295   /* Parse args required to build the message */
8296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8297     {
8298       if (unformat (i, "table %d", &table_id))
8299         ;
8300       else if (unformat (i, "del"))
8301         is_add = 0;
8302       else if (unformat (i, "add"))
8303         is_add = 1;
8304       else
8305         {
8306           clib_warning ("parse error '%U'", format_unformat_error, i);
8307           return -99;
8308         }
8309     }
8310
8311   if (~0 == table_id)
8312     {
8313       errmsg ("missing table-ID");
8314       return -99;
8315     }
8316
8317   /* Construct the API message */
8318   M (MPLS_TABLE_ADD_DEL, mp);
8319
8320   mp->mt_table.mt_table_id = ntohl (table_id);
8321   mp->mt_is_add = is_add;
8322
8323   /* send it... */
8324   S (mp);
8325
8326   /* Wait for a reply... */
8327   W (ret);
8328
8329   return ret;
8330 }
8331
8332 static int
8333 api_mpls_route_add_del (vat_main_t * vam)
8334 {
8335   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8336   mpls_label_t local_label = MPLS_LABEL_INVALID;
8337   unformat_input_t *i = vam->input;
8338   vl_api_mpls_route_add_del_t *mp;
8339   vl_api_fib_path_t paths[8];
8340   int count = 1, j;
8341   f64 before = 0;
8342
8343   /* Parse args required to build the message */
8344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8345     {
8346       if (unformat (i, "%d", &local_label))
8347         ;
8348       else if (unformat (i, "eos"))
8349         is_eos = 1;
8350       else if (unformat (i, "non-eos"))
8351         is_eos = 0;
8352       else if (unformat (i, "del"))
8353         is_add = 0;
8354       else if (unformat (i, "add"))
8355         is_add = 1;
8356       else if (unformat (i, "multipath"))
8357         is_multipath = 1;
8358       else if (unformat (i, "count %d", &count))
8359         ;
8360       else
8361         if (unformat
8362             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8363         {
8364           path_count++;
8365           if (8 == path_count)
8366             {
8367               errmsg ("max 8 paths");
8368               return -99;
8369             }
8370         }
8371       else
8372         {
8373           clib_warning ("parse error '%U'", format_unformat_error, i);
8374           return -99;
8375         }
8376     }
8377
8378   if (!path_count)
8379     {
8380       errmsg ("specify a path; via ...");
8381       return -99;
8382     }
8383
8384   if (MPLS_LABEL_INVALID == local_label)
8385     {
8386       errmsg ("missing label");
8387       return -99;
8388     }
8389
8390   if (count > 1)
8391     {
8392       /* Turn on async mode */
8393       vam->async_mode = 1;
8394       vam->async_errors = 0;
8395       before = vat_time_now (vam);
8396     }
8397
8398   for (j = 0; j < count; j++)
8399     {
8400       /* Construct the API message */
8401       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8402
8403       mp->mr_is_add = is_add;
8404       mp->mr_is_multipath = is_multipath;
8405
8406       mp->mr_route.mr_label = local_label;
8407       mp->mr_route.mr_eos = is_eos;
8408       mp->mr_route.mr_table_id = 0;
8409       mp->mr_route.mr_n_paths = path_count;
8410
8411       clib_memcpy (&mp->mr_route.mr_paths, paths,
8412                    sizeof (paths[0]) * path_count);
8413
8414       local_label++;
8415
8416       /* send it... */
8417       S (mp);
8418       /* If we receive SIGTERM, stop now... */
8419       if (vam->do_exit)
8420         break;
8421     }
8422
8423   /* When testing multiple add/del ops, use a control-ping to sync */
8424   if (count > 1)
8425     {
8426       vl_api_control_ping_t *mp_ping;
8427       f64 after;
8428       f64 timeout;
8429
8430       /* Shut off async mode */
8431       vam->async_mode = 0;
8432
8433       MPING (CONTROL_PING, mp_ping);
8434       S (mp_ping);
8435
8436       timeout = vat_time_now (vam) + 1.0;
8437       while (vat_time_now (vam) < timeout)
8438         if (vam->result_ready == 1)
8439           goto out;
8440       vam->retval = -99;
8441
8442     out:
8443       if (vam->retval == -99)
8444         errmsg ("timeout");
8445
8446       if (vam->async_errors > 0)
8447         {
8448           errmsg ("%d asynchronous errors", vam->async_errors);
8449           vam->retval = -98;
8450         }
8451       vam->async_errors = 0;
8452       after = vat_time_now (vam);
8453
8454       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8455       if (j > 0)
8456         count = j;
8457
8458       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8459              count, after - before, count / (after - before));
8460     }
8461   else
8462     {
8463       int ret;
8464
8465       /* Wait for a reply... */
8466       W (ret);
8467       return ret;
8468     }
8469
8470   /* Return the good/bad news */
8471   return (vam->retval);
8472   return (0);
8473 }
8474
8475 static int
8476 api_mpls_ip_bind_unbind (vat_main_t * vam)
8477 {
8478   unformat_input_t *i = vam->input;
8479   vl_api_mpls_ip_bind_unbind_t *mp;
8480   u32 ip_table_id = 0;
8481   u8 is_bind = 1;
8482   vl_api_prefix_t pfx;
8483   u8 prefix_set = 0;
8484   mpls_label_t local_label = MPLS_LABEL_INVALID;
8485   int ret;
8486
8487   /* Parse args required to build the message */
8488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8489     {
8490       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8491         prefix_set = 1;
8492       else if (unformat (i, "%d", &local_label))
8493         ;
8494       else if (unformat (i, "table-id %d", &ip_table_id))
8495         ;
8496       else if (unformat (i, "unbind"))
8497         is_bind = 0;
8498       else if (unformat (i, "bind"))
8499         is_bind = 1;
8500       else
8501         {
8502           clib_warning ("parse error '%U'", format_unformat_error, i);
8503           return -99;
8504         }
8505     }
8506
8507   if (!prefix_set)
8508     {
8509       errmsg ("IP prefix not set");
8510       return -99;
8511     }
8512
8513   if (MPLS_LABEL_INVALID == local_label)
8514     {
8515       errmsg ("missing label");
8516       return -99;
8517     }
8518
8519   /* Construct the API message */
8520   M (MPLS_IP_BIND_UNBIND, mp);
8521
8522   mp->mb_is_bind = is_bind;
8523   mp->mb_ip_table_id = ntohl (ip_table_id);
8524   mp->mb_mpls_table_id = 0;
8525   mp->mb_label = ntohl (local_label);
8526   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8527
8528   /* send it... */
8529   S (mp);
8530
8531   /* Wait for a reply... */
8532   W (ret);
8533   return ret;
8534   return (0);
8535 }
8536
8537 static int
8538 api_sr_mpls_policy_add (vat_main_t * vam)
8539 {
8540   unformat_input_t *i = vam->input;
8541   vl_api_sr_mpls_policy_add_t *mp;
8542   u32 bsid = 0;
8543   u32 weight = 1;
8544   u8 type = 0;
8545   u8 n_segments = 0;
8546   u32 sid;
8547   u32 *segments = NULL;
8548   int ret;
8549
8550   /* Parse args required to build the message */
8551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8552     {
8553       if (unformat (i, "bsid %d", &bsid))
8554         ;
8555       else if (unformat (i, "weight %d", &weight))
8556         ;
8557       else if (unformat (i, "spray"))
8558         type = 1;
8559       else if (unformat (i, "next %d", &sid))
8560         {
8561           n_segments += 1;
8562           vec_add1 (segments, htonl (sid));
8563         }
8564       else
8565         {
8566           clib_warning ("parse error '%U'", format_unformat_error, i);
8567           return -99;
8568         }
8569     }
8570
8571   if (bsid == 0)
8572     {
8573       errmsg ("bsid not set");
8574       return -99;
8575     }
8576
8577   if (n_segments == 0)
8578     {
8579       errmsg ("no sid in segment stack");
8580       return -99;
8581     }
8582
8583   /* Construct the API message */
8584   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8585
8586   mp->bsid = htonl (bsid);
8587   mp->weight = htonl (weight);
8588   mp->is_spray = type;
8589   mp->n_segments = n_segments;
8590   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8591   vec_free (segments);
8592
8593   /* send it... */
8594   S (mp);
8595
8596   /* Wait for a reply... */
8597   W (ret);
8598   return ret;
8599 }
8600
8601 static int
8602 api_sr_mpls_policy_del (vat_main_t * vam)
8603 {
8604   unformat_input_t *i = vam->input;
8605   vl_api_sr_mpls_policy_del_t *mp;
8606   u32 bsid = 0;
8607   int ret;
8608
8609   /* Parse args required to build the message */
8610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8611     {
8612       if (unformat (i, "bsid %d", &bsid))
8613         ;
8614       else
8615         {
8616           clib_warning ("parse error '%U'", format_unformat_error, i);
8617           return -99;
8618         }
8619     }
8620
8621   if (bsid == 0)
8622     {
8623       errmsg ("bsid not set");
8624       return -99;
8625     }
8626
8627   /* Construct the API message */
8628   M (SR_MPLS_POLICY_DEL, mp);
8629
8630   mp->bsid = htonl (bsid);
8631
8632   /* send it... */
8633   S (mp);
8634
8635   /* Wait for a reply... */
8636   W (ret);
8637   return ret;
8638 }
8639
8640 static int
8641 api_bier_table_add_del (vat_main_t * vam)
8642 {
8643   unformat_input_t *i = vam->input;
8644   vl_api_bier_table_add_del_t *mp;
8645   u8 is_add = 1;
8646   u32 set = 0, sub_domain = 0, hdr_len = 3;
8647   mpls_label_t local_label = MPLS_LABEL_INVALID;
8648   int ret;
8649
8650   /* Parse args required to build the message */
8651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8652     {
8653       if (unformat (i, "sub-domain %d", &sub_domain))
8654         ;
8655       else if (unformat (i, "set %d", &set))
8656         ;
8657       else if (unformat (i, "label %d", &local_label))
8658         ;
8659       else if (unformat (i, "hdr-len %d", &hdr_len))
8660         ;
8661       else if (unformat (i, "add"))
8662         is_add = 1;
8663       else if (unformat (i, "del"))
8664         is_add = 0;
8665       else
8666         {
8667           clib_warning ("parse error '%U'", format_unformat_error, i);
8668           return -99;
8669         }
8670     }
8671
8672   if (MPLS_LABEL_INVALID == local_label)
8673     {
8674       errmsg ("missing label\n");
8675       return -99;
8676     }
8677
8678   /* Construct the API message */
8679   M (BIER_TABLE_ADD_DEL, mp);
8680
8681   mp->bt_is_add = is_add;
8682   mp->bt_label = ntohl (local_label);
8683   mp->bt_tbl_id.bt_set = set;
8684   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8685   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8686
8687   /* send it... */
8688   S (mp);
8689
8690   /* Wait for a reply... */
8691   W (ret);
8692
8693   return (ret);
8694 }
8695
8696 static int
8697 api_bier_route_add_del (vat_main_t * vam)
8698 {
8699   unformat_input_t *i = vam->input;
8700   vl_api_bier_route_add_del_t *mp;
8701   u8 is_add = 1;
8702   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8703   ip4_address_t v4_next_hop_address;
8704   ip6_address_t v6_next_hop_address;
8705   u8 next_hop_set = 0;
8706   u8 next_hop_proto_is_ip4 = 1;
8707   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8708   int ret;
8709
8710   /* Parse args required to build the message */
8711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8712     {
8713       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8714         {
8715           next_hop_proto_is_ip4 = 1;
8716           next_hop_set = 1;
8717         }
8718       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8719         {
8720           next_hop_proto_is_ip4 = 0;
8721           next_hop_set = 1;
8722         }
8723       if (unformat (i, "sub-domain %d", &sub_domain))
8724         ;
8725       else if (unformat (i, "set %d", &set))
8726         ;
8727       else if (unformat (i, "hdr-len %d", &hdr_len))
8728         ;
8729       else if (unformat (i, "bp %d", &bp))
8730         ;
8731       else if (unformat (i, "add"))
8732         is_add = 1;
8733       else if (unformat (i, "del"))
8734         is_add = 0;
8735       else if (unformat (i, "out-label %d", &next_hop_out_label))
8736         ;
8737       else
8738         {
8739           clib_warning ("parse error '%U'", format_unformat_error, i);
8740           return -99;
8741         }
8742     }
8743
8744   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8745     {
8746       errmsg ("next hop / label set\n");
8747       return -99;
8748     }
8749   if (0 == bp)
8750     {
8751       errmsg ("bit=position not set\n");
8752       return -99;
8753     }
8754
8755   /* Construct the API message */
8756   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8757
8758   mp->br_is_add = is_add;
8759   mp->br_route.br_tbl_id.bt_set = set;
8760   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8761   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8762   mp->br_route.br_bp = ntohs (bp);
8763   mp->br_route.br_n_paths = 1;
8764   mp->br_route.br_paths[0].n_labels = 1;
8765   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8766   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8767                                     FIB_API_PATH_NH_PROTO_IP4 :
8768                                     FIB_API_PATH_NH_PROTO_IP6);
8769
8770   if (next_hop_proto_is_ip4)
8771     {
8772       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8773                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8774     }
8775   else
8776     {
8777       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8778                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8779     }
8780
8781   /* send it... */
8782   S (mp);
8783
8784   /* Wait for a reply... */
8785   W (ret);
8786
8787   return (ret);
8788 }
8789
8790 static int
8791 api_mpls_tunnel_add_del (vat_main_t * vam)
8792 {
8793   unformat_input_t *i = vam->input;
8794   vl_api_mpls_tunnel_add_del_t *mp;
8795
8796   vl_api_fib_path_t paths[8];
8797   u32 sw_if_index = ~0;
8798   u8 path_count = 0;
8799   u8 l2_only = 0;
8800   u8 is_add = 1;
8801   int ret;
8802
8803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8804     {
8805       if (unformat (i, "add"))
8806         is_add = 1;
8807       else
8808         if (unformat
8809             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8810         is_add = 0;
8811       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8812         is_add = 0;
8813       else if (unformat (i, "l2-only"))
8814         l2_only = 1;
8815       else
8816         if (unformat
8817             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8818         {
8819           path_count++;
8820           if (8 == path_count)
8821             {
8822               errmsg ("max 8 paths");
8823               return -99;
8824             }
8825         }
8826       else
8827         {
8828           clib_warning ("parse error '%U'", format_unformat_error, i);
8829           return -99;
8830         }
8831     }
8832
8833   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8834
8835   mp->mt_is_add = is_add;
8836   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8837   mp->mt_tunnel.mt_l2_only = l2_only;
8838   mp->mt_tunnel.mt_is_multicast = 0;
8839   mp->mt_tunnel.mt_n_paths = path_count;
8840
8841   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8842                sizeof (paths[0]) * path_count);
8843
8844   S (mp);
8845   W (ret);
8846   return ret;
8847 }
8848
8849 static int
8850 api_sw_interface_set_unnumbered (vat_main_t * vam)
8851 {
8852   unformat_input_t *i = vam->input;
8853   vl_api_sw_interface_set_unnumbered_t *mp;
8854   u32 sw_if_index;
8855   u32 unnum_sw_index = ~0;
8856   u8 is_add = 1;
8857   u8 sw_if_index_set = 0;
8858   int ret;
8859
8860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8863         sw_if_index_set = 1;
8864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8865         sw_if_index_set = 1;
8866       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8867         ;
8868       else if (unformat (i, "del"))
8869         is_add = 0;
8870       else
8871         {
8872           clib_warning ("parse error '%U'", format_unformat_error, i);
8873           return -99;
8874         }
8875     }
8876
8877   if (sw_if_index_set == 0)
8878     {
8879       errmsg ("missing interface name or sw_if_index");
8880       return -99;
8881     }
8882
8883   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8884
8885   mp->sw_if_index = ntohl (sw_if_index);
8886   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8887   mp->is_add = is_add;
8888
8889   S (mp);
8890   W (ret);
8891   return ret;
8892 }
8893
8894
8895 static int
8896 api_create_vlan_subif (vat_main_t * vam)
8897 {
8898   unformat_input_t *i = vam->input;
8899   vl_api_create_vlan_subif_t *mp;
8900   u32 sw_if_index;
8901   u8 sw_if_index_set = 0;
8902   u32 vlan_id;
8903   u8 vlan_id_set = 0;
8904   int ret;
8905
8906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8907     {
8908       if (unformat (i, "sw_if_index %d", &sw_if_index))
8909         sw_if_index_set = 1;
8910       else
8911         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8912         sw_if_index_set = 1;
8913       else if (unformat (i, "vlan %d", &vlan_id))
8914         vlan_id_set = 1;
8915       else
8916         {
8917           clib_warning ("parse error '%U'", format_unformat_error, i);
8918           return -99;
8919         }
8920     }
8921
8922   if (sw_if_index_set == 0)
8923     {
8924       errmsg ("missing interface name or sw_if_index");
8925       return -99;
8926     }
8927
8928   if (vlan_id_set == 0)
8929     {
8930       errmsg ("missing vlan_id");
8931       return -99;
8932     }
8933   M (CREATE_VLAN_SUBIF, mp);
8934
8935   mp->sw_if_index = ntohl (sw_if_index);
8936   mp->vlan_id = ntohl (vlan_id);
8937
8938   S (mp);
8939   W (ret);
8940   return ret;
8941 }
8942
8943 #define foreach_create_subif_bit                \
8944 _(no_tags)                                      \
8945 _(one_tag)                                      \
8946 _(two_tags)                                     \
8947 _(dot1ad)                                       \
8948 _(exact_match)                                  \
8949 _(default_sub)                                  \
8950 _(outer_vlan_id_any)                            \
8951 _(inner_vlan_id_any)
8952
8953 #define foreach_create_subif_flag               \
8954 _(0, "no_tags")                                 \
8955 _(1, "one_tag")                                 \
8956 _(2, "two_tags")                                \
8957 _(3, "dot1ad")                                  \
8958 _(4, "exact_match")                             \
8959 _(5, "default_sub")                             \
8960 _(6, "outer_vlan_id_any")                       \
8961 _(7, "inner_vlan_id_any")
8962
8963 static int
8964 api_create_subif (vat_main_t * vam)
8965 {
8966   unformat_input_t *i = vam->input;
8967   vl_api_create_subif_t *mp;
8968   u32 sw_if_index;
8969   u8 sw_if_index_set = 0;
8970   u32 sub_id;
8971   u8 sub_id_set = 0;
8972   u32 __attribute__ ((unused)) no_tags = 0;
8973   u32 __attribute__ ((unused)) one_tag = 0;
8974   u32 __attribute__ ((unused)) two_tags = 0;
8975   u32 __attribute__ ((unused)) dot1ad = 0;
8976   u32 __attribute__ ((unused)) exact_match = 0;
8977   u32 __attribute__ ((unused)) default_sub = 0;
8978   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8979   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8980   u32 tmp;
8981   u16 outer_vlan_id = 0;
8982   u16 inner_vlan_id = 0;
8983   int ret;
8984
8985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8986     {
8987       if (unformat (i, "sw_if_index %d", &sw_if_index))
8988         sw_if_index_set = 1;
8989       else
8990         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8991         sw_if_index_set = 1;
8992       else if (unformat (i, "sub_id %d", &sub_id))
8993         sub_id_set = 1;
8994       else if (unformat (i, "outer_vlan_id %d", &tmp))
8995         outer_vlan_id = tmp;
8996       else if (unformat (i, "inner_vlan_id %d", &tmp))
8997         inner_vlan_id = tmp;
8998
8999 #define _(a) else if (unformat (i, #a)) a = 1 ;
9000       foreach_create_subif_bit
9001 #undef _
9002         else
9003         {
9004           clib_warning ("parse error '%U'", format_unformat_error, i);
9005           return -99;
9006         }
9007     }
9008
9009   if (sw_if_index_set == 0)
9010     {
9011       errmsg ("missing interface name or sw_if_index");
9012       return -99;
9013     }
9014
9015   if (sub_id_set == 0)
9016     {
9017       errmsg ("missing sub_id");
9018       return -99;
9019     }
9020   M (CREATE_SUBIF, mp);
9021
9022   mp->sw_if_index = ntohl (sw_if_index);
9023   mp->sub_id = ntohl (sub_id);
9024
9025 #define _(a,b) mp->sub_if_flags |= (1 << a);
9026   foreach_create_subif_flag;
9027 #undef _
9028
9029   mp->outer_vlan_id = ntohs (outer_vlan_id);
9030   mp->inner_vlan_id = ntohs (inner_vlan_id);
9031
9032   S (mp);
9033   W (ret);
9034   return ret;
9035 }
9036
9037 static int
9038 api_ip_table_replace_begin (vat_main_t * vam)
9039 {
9040   unformat_input_t *i = vam->input;
9041   vl_api_ip_table_replace_begin_t *mp;
9042   u32 table_id = 0;
9043   u8 is_ipv6 = 0;
9044
9045   int ret;
9046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9047     {
9048       if (unformat (i, "table %d", &table_id))
9049         ;
9050       else if (unformat (i, "ipv6"))
9051         is_ipv6 = 1;
9052       else
9053         {
9054           clib_warning ("parse error '%U'", format_unformat_error, i);
9055           return -99;
9056         }
9057     }
9058
9059   M (IP_TABLE_REPLACE_BEGIN, mp);
9060
9061   mp->table.table_id = ntohl (table_id);
9062   mp->table.is_ip6 = is_ipv6;
9063
9064   S (mp);
9065   W (ret);
9066   return ret;
9067 }
9068
9069 static int
9070 api_ip_table_flush (vat_main_t * vam)
9071 {
9072   unformat_input_t *i = vam->input;
9073   vl_api_ip_table_flush_t *mp;
9074   u32 table_id = 0;
9075   u8 is_ipv6 = 0;
9076
9077   int ret;
9078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9079     {
9080       if (unformat (i, "table %d", &table_id))
9081         ;
9082       else if (unformat (i, "ipv6"))
9083         is_ipv6 = 1;
9084       else
9085         {
9086           clib_warning ("parse error '%U'", format_unformat_error, i);
9087           return -99;
9088         }
9089     }
9090
9091   M (IP_TABLE_FLUSH, mp);
9092
9093   mp->table.table_id = ntohl (table_id);
9094   mp->table.is_ip6 = is_ipv6;
9095
9096   S (mp);
9097   W (ret);
9098   return ret;
9099 }
9100
9101 static int
9102 api_ip_table_replace_end (vat_main_t * vam)
9103 {
9104   unformat_input_t *i = vam->input;
9105   vl_api_ip_table_replace_end_t *mp;
9106   u32 table_id = 0;
9107   u8 is_ipv6 = 0;
9108
9109   int ret;
9110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9111     {
9112       if (unformat (i, "table %d", &table_id))
9113         ;
9114       else if (unformat (i, "ipv6"))
9115         is_ipv6 = 1;
9116       else
9117         {
9118           clib_warning ("parse error '%U'", format_unformat_error, i);
9119           return -99;
9120         }
9121     }
9122
9123   M (IP_TABLE_REPLACE_END, mp);
9124
9125   mp->table.table_id = ntohl (table_id);
9126   mp->table.is_ip6 = is_ipv6;
9127
9128   S (mp);
9129   W (ret);
9130   return ret;
9131 }
9132
9133 static int
9134 api_set_ip_flow_hash (vat_main_t * vam)
9135 {
9136   unformat_input_t *i = vam->input;
9137   vl_api_set_ip_flow_hash_t *mp;
9138   u32 vrf_id = 0;
9139   u8 is_ipv6 = 0;
9140   u8 vrf_id_set = 0;
9141   u8 src = 0;
9142   u8 dst = 0;
9143   u8 sport = 0;
9144   u8 dport = 0;
9145   u8 proto = 0;
9146   u8 reverse = 0;
9147   int ret;
9148
9149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9150     {
9151       if (unformat (i, "vrf %d", &vrf_id))
9152         vrf_id_set = 1;
9153       else if (unformat (i, "ipv6"))
9154         is_ipv6 = 1;
9155       else if (unformat (i, "src"))
9156         src = 1;
9157       else if (unformat (i, "dst"))
9158         dst = 1;
9159       else if (unformat (i, "sport"))
9160         sport = 1;
9161       else if (unformat (i, "dport"))
9162         dport = 1;
9163       else if (unformat (i, "proto"))
9164         proto = 1;
9165       else if (unformat (i, "reverse"))
9166         reverse = 1;
9167
9168       else
9169         {
9170           clib_warning ("parse error '%U'", format_unformat_error, i);
9171           return -99;
9172         }
9173     }
9174
9175   if (vrf_id_set == 0)
9176     {
9177       errmsg ("missing vrf id");
9178       return -99;
9179     }
9180
9181   M (SET_IP_FLOW_HASH, mp);
9182   mp->src = src;
9183   mp->dst = dst;
9184   mp->sport = sport;
9185   mp->dport = dport;
9186   mp->proto = proto;
9187   mp->reverse = reverse;
9188   mp->vrf_id = ntohl (vrf_id);
9189   mp->is_ipv6 = is_ipv6;
9190
9191   S (mp);
9192   W (ret);
9193   return ret;
9194 }
9195
9196 static int
9197 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9198 {
9199   unformat_input_t *i = vam->input;
9200   vl_api_sw_interface_ip6_enable_disable_t *mp;
9201   u32 sw_if_index;
9202   u8 sw_if_index_set = 0;
9203   u8 enable = 0;
9204   int ret;
9205
9206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9207     {
9208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9209         sw_if_index_set = 1;
9210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9211         sw_if_index_set = 1;
9212       else if (unformat (i, "enable"))
9213         enable = 1;
9214       else if (unformat (i, "disable"))
9215         enable = 0;
9216       else
9217         {
9218           clib_warning ("parse error '%U'", format_unformat_error, i);
9219           return -99;
9220         }
9221     }
9222
9223   if (sw_if_index_set == 0)
9224     {
9225       errmsg ("missing interface name or sw_if_index");
9226       return -99;
9227     }
9228
9229   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9230
9231   mp->sw_if_index = ntohl (sw_if_index);
9232   mp->enable = enable;
9233
9234   S (mp);
9235   W (ret);
9236   return ret;
9237 }
9238
9239
9240 static int
9241 api_l2_patch_add_del (vat_main_t * vam)
9242 {
9243   unformat_input_t *i = vam->input;
9244   vl_api_l2_patch_add_del_t *mp;
9245   u32 rx_sw_if_index;
9246   u8 rx_sw_if_index_set = 0;
9247   u32 tx_sw_if_index;
9248   u8 tx_sw_if_index_set = 0;
9249   u8 is_add = 1;
9250   int ret;
9251
9252   /* Parse args required to build the message */
9253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9254     {
9255       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9256         rx_sw_if_index_set = 1;
9257       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9258         tx_sw_if_index_set = 1;
9259       else if (unformat (i, "rx"))
9260         {
9261           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9262             {
9263               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9264                             &rx_sw_if_index))
9265                 rx_sw_if_index_set = 1;
9266             }
9267           else
9268             break;
9269         }
9270       else if (unformat (i, "tx"))
9271         {
9272           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9273             {
9274               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9275                             &tx_sw_if_index))
9276                 tx_sw_if_index_set = 1;
9277             }
9278           else
9279             break;
9280         }
9281       else if (unformat (i, "del"))
9282         is_add = 0;
9283       else
9284         break;
9285     }
9286
9287   if (rx_sw_if_index_set == 0)
9288     {
9289       errmsg ("missing rx interface name or rx_sw_if_index");
9290       return -99;
9291     }
9292
9293   if (tx_sw_if_index_set == 0)
9294     {
9295       errmsg ("missing tx interface name or tx_sw_if_index");
9296       return -99;
9297     }
9298
9299   M (L2_PATCH_ADD_DEL, mp);
9300
9301   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9302   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9303   mp->is_add = is_add;
9304
9305   S (mp);
9306   W (ret);
9307   return ret;
9308 }
9309
9310 u8 is_del;
9311 u8 localsid_addr[16];
9312 u8 end_psp;
9313 u8 behavior;
9314 u32 sw_if_index;
9315 u32 vlan_index;
9316 u32 fib_table;
9317 u8 nh_addr[16];
9318
9319 static int
9320 api_sr_localsid_add_del (vat_main_t * vam)
9321 {
9322   unformat_input_t *i = vam->input;
9323   vl_api_sr_localsid_add_del_t *mp;
9324
9325   u8 is_del;
9326   ip6_address_t localsid;
9327   u8 end_psp = 0;
9328   u8 behavior = ~0;
9329   u32 sw_if_index;
9330   u32 fib_table = ~(u32) 0;
9331   ip46_address_t nh_addr;
9332   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9333
9334   bool nexthop_set = 0;
9335
9336   int ret;
9337
9338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9339     {
9340       if (unformat (i, "del"))
9341         is_del = 1;
9342       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9343       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9344         nexthop_set = 1;
9345       else if (unformat (i, "behavior %u", &behavior));
9346       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9347       else if (unformat (i, "fib-table %u", &fib_table));
9348       else if (unformat (i, "end.psp %u", &behavior));
9349       else
9350         break;
9351     }
9352
9353   M (SR_LOCALSID_ADD_DEL, mp);
9354
9355   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9356
9357   if (nexthop_set)
9358     {
9359       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9360     }
9361   mp->behavior = behavior;
9362   mp->sw_if_index = ntohl (sw_if_index);
9363   mp->fib_table = ntohl (fib_table);
9364   mp->end_psp = end_psp;
9365   mp->is_del = is_del;
9366
9367   S (mp);
9368   W (ret);
9369   return ret;
9370 }
9371
9372 static int
9373 api_ioam_enable (vat_main_t * vam)
9374 {
9375   unformat_input_t *input = vam->input;
9376   vl_api_ioam_enable_t *mp;
9377   u32 id = 0;
9378   int has_trace_option = 0;
9379   int has_pot_option = 0;
9380   int has_seqno_option = 0;
9381   int has_analyse_option = 0;
9382   int ret;
9383
9384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9385     {
9386       if (unformat (input, "trace"))
9387         has_trace_option = 1;
9388       else if (unformat (input, "pot"))
9389         has_pot_option = 1;
9390       else if (unformat (input, "seqno"))
9391         has_seqno_option = 1;
9392       else if (unformat (input, "analyse"))
9393         has_analyse_option = 1;
9394       else
9395         break;
9396     }
9397   M (IOAM_ENABLE, mp);
9398   mp->id = htons (id);
9399   mp->seqno = has_seqno_option;
9400   mp->analyse = has_analyse_option;
9401   mp->pot_enable = has_pot_option;
9402   mp->trace_enable = has_trace_option;
9403
9404   S (mp);
9405   W (ret);
9406   return ret;
9407 }
9408
9409
9410 static int
9411 api_ioam_disable (vat_main_t * vam)
9412 {
9413   vl_api_ioam_disable_t *mp;
9414   int ret;
9415
9416   M (IOAM_DISABLE, mp);
9417   S (mp);
9418   W (ret);
9419   return ret;
9420 }
9421
9422 #define foreach_tcp_proto_field                 \
9423 _(src_port)                                     \
9424 _(dst_port)
9425
9426 #define foreach_udp_proto_field                 \
9427 _(src_port)                                     \
9428 _(dst_port)
9429
9430 #define foreach_ip4_proto_field                 \
9431 _(src_address)                                  \
9432 _(dst_address)                                  \
9433 _(tos)                                          \
9434 _(length)                                       \
9435 _(fragment_id)                                  \
9436 _(ttl)                                          \
9437 _(protocol)                                     \
9438 _(checksum)
9439
9440 typedef struct
9441 {
9442   u16 src_port, dst_port;
9443 } tcpudp_header_t;
9444
9445 #if VPP_API_TEST_BUILTIN == 0
9446 uword
9447 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9448 {
9449   u8 **maskp = va_arg (*args, u8 **);
9450   u8 *mask = 0;
9451   u8 found_something = 0;
9452   tcp_header_t *tcp;
9453
9454 #define _(a) u8 a=0;
9455   foreach_tcp_proto_field;
9456 #undef _
9457
9458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9459     {
9460       if (0);
9461 #define _(a) else if (unformat (input, #a)) a=1;
9462       foreach_tcp_proto_field
9463 #undef _
9464         else
9465         break;
9466     }
9467
9468 #define _(a) found_something += a;
9469   foreach_tcp_proto_field;
9470 #undef _
9471
9472   if (found_something == 0)
9473     return 0;
9474
9475   vec_validate (mask, sizeof (*tcp) - 1);
9476
9477   tcp = (tcp_header_t *) mask;
9478
9479 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9480   foreach_tcp_proto_field;
9481 #undef _
9482
9483   *maskp = mask;
9484   return 1;
9485 }
9486
9487 uword
9488 unformat_udp_mask (unformat_input_t * input, va_list * args)
9489 {
9490   u8 **maskp = va_arg (*args, u8 **);
9491   u8 *mask = 0;
9492   u8 found_something = 0;
9493   udp_header_t *udp;
9494
9495 #define _(a) u8 a=0;
9496   foreach_udp_proto_field;
9497 #undef _
9498
9499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9500     {
9501       if (0);
9502 #define _(a) else if (unformat (input, #a)) a=1;
9503       foreach_udp_proto_field
9504 #undef _
9505         else
9506         break;
9507     }
9508
9509 #define _(a) found_something += a;
9510   foreach_udp_proto_field;
9511 #undef _
9512
9513   if (found_something == 0)
9514     return 0;
9515
9516   vec_validate (mask, sizeof (*udp) - 1);
9517
9518   udp = (udp_header_t *) mask;
9519
9520 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9521   foreach_udp_proto_field;
9522 #undef _
9523
9524   *maskp = mask;
9525   return 1;
9526 }
9527
9528 uword
9529 unformat_l4_mask (unformat_input_t * input, va_list * args)
9530 {
9531   u8 **maskp = va_arg (*args, u8 **);
9532   u16 src_port = 0, dst_port = 0;
9533   tcpudp_header_t *tcpudp;
9534
9535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9536     {
9537       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9538         return 1;
9539       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9540         return 1;
9541       else if (unformat (input, "src_port"))
9542         src_port = 0xFFFF;
9543       else if (unformat (input, "dst_port"))
9544         dst_port = 0xFFFF;
9545       else
9546         return 0;
9547     }
9548
9549   if (!src_port && !dst_port)
9550     return 0;
9551
9552   u8 *mask = 0;
9553   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9554
9555   tcpudp = (tcpudp_header_t *) mask;
9556   tcpudp->src_port = src_port;
9557   tcpudp->dst_port = dst_port;
9558
9559   *maskp = mask;
9560
9561   return 1;
9562 }
9563
9564 uword
9565 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9566 {
9567   u8 **maskp = va_arg (*args, u8 **);
9568   u8 *mask = 0;
9569   u8 found_something = 0;
9570   ip4_header_t *ip;
9571
9572 #define _(a) u8 a=0;
9573   foreach_ip4_proto_field;
9574 #undef _
9575   u8 version = 0;
9576   u8 hdr_length = 0;
9577
9578
9579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9580     {
9581       if (unformat (input, "version"))
9582         version = 1;
9583       else if (unformat (input, "hdr_length"))
9584         hdr_length = 1;
9585       else if (unformat (input, "src"))
9586         src_address = 1;
9587       else if (unformat (input, "dst"))
9588         dst_address = 1;
9589       else if (unformat (input, "proto"))
9590         protocol = 1;
9591
9592 #define _(a) else if (unformat (input, #a)) a=1;
9593       foreach_ip4_proto_field
9594 #undef _
9595         else
9596         break;
9597     }
9598
9599 #define _(a) found_something += a;
9600   foreach_ip4_proto_field;
9601 #undef _
9602
9603   if (found_something == 0)
9604     return 0;
9605
9606   vec_validate (mask, sizeof (*ip) - 1);
9607
9608   ip = (ip4_header_t *) mask;
9609
9610 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9611   foreach_ip4_proto_field;
9612 #undef _
9613
9614   ip->ip_version_and_header_length = 0;
9615
9616   if (version)
9617     ip->ip_version_and_header_length |= 0xF0;
9618
9619   if (hdr_length)
9620     ip->ip_version_and_header_length |= 0x0F;
9621
9622   *maskp = mask;
9623   return 1;
9624 }
9625
9626 #define foreach_ip6_proto_field                 \
9627 _(src_address)                                  \
9628 _(dst_address)                                  \
9629 _(payload_length)                               \
9630 _(hop_limit)                                    \
9631 _(protocol)
9632
9633 uword
9634 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9635 {
9636   u8 **maskp = va_arg (*args, u8 **);
9637   u8 *mask = 0;
9638   u8 found_something = 0;
9639   ip6_header_t *ip;
9640   u32 ip_version_traffic_class_and_flow_label;
9641
9642 #define _(a) u8 a=0;
9643   foreach_ip6_proto_field;
9644 #undef _
9645   u8 version = 0;
9646   u8 traffic_class = 0;
9647   u8 flow_label = 0;
9648
9649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9650     {
9651       if (unformat (input, "version"))
9652         version = 1;
9653       else if (unformat (input, "traffic-class"))
9654         traffic_class = 1;
9655       else if (unformat (input, "flow-label"))
9656         flow_label = 1;
9657       else if (unformat (input, "src"))
9658         src_address = 1;
9659       else if (unformat (input, "dst"))
9660         dst_address = 1;
9661       else if (unformat (input, "proto"))
9662         protocol = 1;
9663
9664 #define _(a) else if (unformat (input, #a)) a=1;
9665       foreach_ip6_proto_field
9666 #undef _
9667         else
9668         break;
9669     }
9670
9671 #define _(a) found_something += a;
9672   foreach_ip6_proto_field;
9673 #undef _
9674
9675   if (found_something == 0)
9676     return 0;
9677
9678   vec_validate (mask, sizeof (*ip) - 1);
9679
9680   ip = (ip6_header_t *) mask;
9681
9682 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9683   foreach_ip6_proto_field;
9684 #undef _
9685
9686   ip_version_traffic_class_and_flow_label = 0;
9687
9688   if (version)
9689     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9690
9691   if (traffic_class)
9692     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9693
9694   if (flow_label)
9695     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9696
9697   ip->ip_version_traffic_class_and_flow_label =
9698     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9699
9700   *maskp = mask;
9701   return 1;
9702 }
9703
9704 uword
9705 unformat_l3_mask (unformat_input_t * input, va_list * args)
9706 {
9707   u8 **maskp = va_arg (*args, u8 **);
9708
9709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9710     {
9711       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9712         return 1;
9713       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9714         return 1;
9715       else
9716         break;
9717     }
9718   return 0;
9719 }
9720
9721 uword
9722 unformat_l2_mask (unformat_input_t * input, va_list * args)
9723 {
9724   u8 **maskp = va_arg (*args, u8 **);
9725   u8 *mask = 0;
9726   u8 src = 0;
9727   u8 dst = 0;
9728   u8 proto = 0;
9729   u8 tag1 = 0;
9730   u8 tag2 = 0;
9731   u8 ignore_tag1 = 0;
9732   u8 ignore_tag2 = 0;
9733   u8 cos1 = 0;
9734   u8 cos2 = 0;
9735   u8 dot1q = 0;
9736   u8 dot1ad = 0;
9737   int len = 14;
9738
9739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9740     {
9741       if (unformat (input, "src"))
9742         src = 1;
9743       else if (unformat (input, "dst"))
9744         dst = 1;
9745       else if (unformat (input, "proto"))
9746         proto = 1;
9747       else if (unformat (input, "tag1"))
9748         tag1 = 1;
9749       else if (unformat (input, "tag2"))
9750         tag2 = 1;
9751       else if (unformat (input, "ignore-tag1"))
9752         ignore_tag1 = 1;
9753       else if (unformat (input, "ignore-tag2"))
9754         ignore_tag2 = 1;
9755       else if (unformat (input, "cos1"))
9756         cos1 = 1;
9757       else if (unformat (input, "cos2"))
9758         cos2 = 1;
9759       else if (unformat (input, "dot1q"))
9760         dot1q = 1;
9761       else if (unformat (input, "dot1ad"))
9762         dot1ad = 1;
9763       else
9764         break;
9765     }
9766   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9767        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9768     return 0;
9769
9770   if (tag1 || ignore_tag1 || cos1 || dot1q)
9771     len = 18;
9772   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9773     len = 22;
9774
9775   vec_validate (mask, len - 1);
9776
9777   if (dst)
9778     clib_memset (mask, 0xff, 6);
9779
9780   if (src)
9781     clib_memset (mask + 6, 0xff, 6);
9782
9783   if (tag2 || dot1ad)
9784     {
9785       /* inner vlan tag */
9786       if (tag2)
9787         {
9788           mask[19] = 0xff;
9789           mask[18] = 0x0f;
9790         }
9791       if (cos2)
9792         mask[18] |= 0xe0;
9793       if (proto)
9794         mask[21] = mask[20] = 0xff;
9795       if (tag1)
9796         {
9797           mask[15] = 0xff;
9798           mask[14] = 0x0f;
9799         }
9800       if (cos1)
9801         mask[14] |= 0xe0;
9802       *maskp = mask;
9803       return 1;
9804     }
9805   if (tag1 | dot1q)
9806     {
9807       if (tag1)
9808         {
9809           mask[15] = 0xff;
9810           mask[14] = 0x0f;
9811         }
9812       if (cos1)
9813         mask[14] |= 0xe0;
9814       if (proto)
9815         mask[16] = mask[17] = 0xff;
9816
9817       *maskp = mask;
9818       return 1;
9819     }
9820   if (cos2)
9821     mask[18] |= 0xe0;
9822   if (cos1)
9823     mask[14] |= 0xe0;
9824   if (proto)
9825     mask[12] = mask[13] = 0xff;
9826
9827   *maskp = mask;
9828   return 1;
9829 }
9830
9831 uword
9832 unformat_classify_mask (unformat_input_t * input, va_list * args)
9833 {
9834   u8 **maskp = va_arg (*args, u8 **);
9835   u32 *skipp = va_arg (*args, u32 *);
9836   u32 *matchp = va_arg (*args, u32 *);
9837   u32 match;
9838   u8 *mask = 0;
9839   u8 *l2 = 0;
9840   u8 *l3 = 0;
9841   u8 *l4 = 0;
9842   int i;
9843
9844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9845     {
9846       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9847         ;
9848       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9849         ;
9850       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9851         ;
9852       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9853         ;
9854       else
9855         break;
9856     }
9857
9858   if (l4 && !l3)
9859     {
9860       vec_free (mask);
9861       vec_free (l2);
9862       vec_free (l4);
9863       return 0;
9864     }
9865
9866   if (mask || l2 || l3 || l4)
9867     {
9868       if (l2 || l3 || l4)
9869         {
9870           /* "With a free Ethernet header in every package" */
9871           if (l2 == 0)
9872             vec_validate (l2, 13);
9873           mask = l2;
9874           if (vec_len (l3))
9875             {
9876               vec_append (mask, l3);
9877               vec_free (l3);
9878             }
9879           if (vec_len (l4))
9880             {
9881               vec_append (mask, l4);
9882               vec_free (l4);
9883             }
9884         }
9885
9886       /* Scan forward looking for the first significant mask octet */
9887       for (i = 0; i < vec_len (mask); i++)
9888         if (mask[i])
9889           break;
9890
9891       /* compute (skip, match) params */
9892       *skipp = i / sizeof (u32x4);
9893       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9894
9895       /* Pad mask to an even multiple of the vector size */
9896       while (vec_len (mask) % sizeof (u32x4))
9897         vec_add1 (mask, 0);
9898
9899       match = vec_len (mask) / sizeof (u32x4);
9900
9901       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9902         {
9903           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9904           if (*tmp || *(tmp + 1))
9905             break;
9906           match--;
9907         }
9908       if (match == 0)
9909         clib_warning ("BUG: match 0");
9910
9911       _vec_len (mask) = match * sizeof (u32x4);
9912
9913       *matchp = match;
9914       *maskp = mask;
9915
9916       return 1;
9917     }
9918
9919   return 0;
9920 }
9921 #endif /* VPP_API_TEST_BUILTIN */
9922
9923 #define foreach_l2_next                         \
9924 _(drop, DROP)                                   \
9925 _(ethernet, ETHERNET_INPUT)                     \
9926 _(ip4, IP4_INPUT)                               \
9927 _(ip6, IP6_INPUT)
9928
9929 uword
9930 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9931 {
9932   u32 *miss_next_indexp = va_arg (*args, u32 *);
9933   u32 next_index = 0;
9934   u32 tmp;
9935
9936 #define _(n,N) \
9937   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9938   foreach_l2_next;
9939 #undef _
9940
9941   if (unformat (input, "%d", &tmp))
9942     {
9943       next_index = tmp;
9944       goto out;
9945     }
9946
9947   return 0;
9948
9949 out:
9950   *miss_next_indexp = next_index;
9951   return 1;
9952 }
9953
9954 #define foreach_ip_next                         \
9955 _(drop, DROP)                                   \
9956 _(local, LOCAL)                                 \
9957 _(rewrite, REWRITE)
9958
9959 uword
9960 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9961 {
9962   u32 *miss_next_indexp = va_arg (*args, u32 *);
9963   u32 next_index = 0;
9964   u32 tmp;
9965
9966 #define _(n,N) \
9967   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9968   foreach_ip_next;
9969 #undef _
9970
9971   if (unformat (input, "%d", &tmp))
9972     {
9973       next_index = tmp;
9974       goto out;
9975     }
9976
9977   return 0;
9978
9979 out:
9980   *miss_next_indexp = next_index;
9981   return 1;
9982 }
9983
9984 #define foreach_acl_next                        \
9985 _(deny, DENY)
9986
9987 uword
9988 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9989 {
9990   u32 *miss_next_indexp = va_arg (*args, u32 *);
9991   u32 next_index = 0;
9992   u32 tmp;
9993
9994 #define _(n,N) \
9995   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9996   foreach_acl_next;
9997 #undef _
9998
9999   if (unformat (input, "permit"))
10000     {
10001       next_index = ~0;
10002       goto out;
10003     }
10004   else if (unformat (input, "%d", &tmp))
10005     {
10006       next_index = tmp;
10007       goto out;
10008     }
10009
10010   return 0;
10011
10012 out:
10013   *miss_next_indexp = next_index;
10014   return 1;
10015 }
10016
10017 uword
10018 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10019 {
10020   u32 *r = va_arg (*args, u32 *);
10021
10022   if (unformat (input, "conform-color"))
10023     *r = POLICE_CONFORM;
10024   else if (unformat (input, "exceed-color"))
10025     *r = POLICE_EXCEED;
10026   else
10027     return 0;
10028
10029   return 1;
10030 }
10031
10032 static int
10033 api_classify_add_del_table (vat_main_t * vam)
10034 {
10035   unformat_input_t *i = vam->input;
10036   vl_api_classify_add_del_table_t *mp;
10037
10038   u32 nbuckets = 2;
10039   u32 skip = ~0;
10040   u32 match = ~0;
10041   int is_add = 1;
10042   int del_chain = 0;
10043   u32 table_index = ~0;
10044   u32 next_table_index = ~0;
10045   u32 miss_next_index = ~0;
10046   u32 memory_size = 32 << 20;
10047   u8 *mask = 0;
10048   u32 current_data_flag = 0;
10049   int current_data_offset = 0;
10050   int ret;
10051
10052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10053     {
10054       if (unformat (i, "del"))
10055         is_add = 0;
10056       else if (unformat (i, "del-chain"))
10057         {
10058           is_add = 0;
10059           del_chain = 1;
10060         }
10061       else if (unformat (i, "buckets %d", &nbuckets))
10062         ;
10063       else if (unformat (i, "memory_size %d", &memory_size))
10064         ;
10065       else if (unformat (i, "skip %d", &skip))
10066         ;
10067       else if (unformat (i, "match %d", &match))
10068         ;
10069       else if (unformat (i, "table %d", &table_index))
10070         ;
10071       else if (unformat (i, "mask %U", unformat_classify_mask,
10072                          &mask, &skip, &match))
10073         ;
10074       else if (unformat (i, "next-table %d", &next_table_index))
10075         ;
10076       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10077                          &miss_next_index))
10078         ;
10079       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10080                          &miss_next_index))
10081         ;
10082       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10083                          &miss_next_index))
10084         ;
10085       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10086         ;
10087       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10088         ;
10089       else
10090         break;
10091     }
10092
10093   if (is_add && mask == 0)
10094     {
10095       errmsg ("Mask required");
10096       return -99;
10097     }
10098
10099   if (is_add && skip == ~0)
10100     {
10101       errmsg ("skip count required");
10102       return -99;
10103     }
10104
10105   if (is_add && match == ~0)
10106     {
10107       errmsg ("match count required");
10108       return -99;
10109     }
10110
10111   if (!is_add && table_index == ~0)
10112     {
10113       errmsg ("table index required for delete");
10114       return -99;
10115     }
10116
10117   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10118
10119   mp->is_add = is_add;
10120   mp->del_chain = del_chain;
10121   mp->table_index = ntohl (table_index);
10122   mp->nbuckets = ntohl (nbuckets);
10123   mp->memory_size = ntohl (memory_size);
10124   mp->skip_n_vectors = ntohl (skip);
10125   mp->match_n_vectors = ntohl (match);
10126   mp->next_table_index = ntohl (next_table_index);
10127   mp->miss_next_index = ntohl (miss_next_index);
10128   mp->current_data_flag = ntohl (current_data_flag);
10129   mp->current_data_offset = ntohl (current_data_offset);
10130   mp->mask_len = ntohl (vec_len (mask));
10131   clib_memcpy (mp->mask, mask, vec_len (mask));
10132
10133   vec_free (mask);
10134
10135   S (mp);
10136   W (ret);
10137   return ret;
10138 }
10139
10140 #if VPP_API_TEST_BUILTIN == 0
10141 uword
10142 unformat_l4_match (unformat_input_t * input, va_list * args)
10143 {
10144   u8 **matchp = va_arg (*args, u8 **);
10145
10146   u8 *proto_header = 0;
10147   int src_port = 0;
10148   int dst_port = 0;
10149
10150   tcpudp_header_t h;
10151
10152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10153     {
10154       if (unformat (input, "src_port %d", &src_port))
10155         ;
10156       else if (unformat (input, "dst_port %d", &dst_port))
10157         ;
10158       else
10159         return 0;
10160     }
10161
10162   h.src_port = clib_host_to_net_u16 (src_port);
10163   h.dst_port = clib_host_to_net_u16 (dst_port);
10164   vec_validate (proto_header, sizeof (h) - 1);
10165   memcpy (proto_header, &h, sizeof (h));
10166
10167   *matchp = proto_header;
10168
10169   return 1;
10170 }
10171
10172 uword
10173 unformat_ip4_match (unformat_input_t * input, va_list * args)
10174 {
10175   u8 **matchp = va_arg (*args, u8 **);
10176   u8 *match = 0;
10177   ip4_header_t *ip;
10178   int version = 0;
10179   u32 version_val;
10180   int hdr_length = 0;
10181   u32 hdr_length_val;
10182   int src = 0, dst = 0;
10183   ip4_address_t src_val, dst_val;
10184   int proto = 0;
10185   u32 proto_val;
10186   int tos = 0;
10187   u32 tos_val;
10188   int length = 0;
10189   u32 length_val;
10190   int fragment_id = 0;
10191   u32 fragment_id_val;
10192   int ttl = 0;
10193   int ttl_val;
10194   int checksum = 0;
10195   u32 checksum_val;
10196
10197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10198     {
10199       if (unformat (input, "version %d", &version_val))
10200         version = 1;
10201       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10202         hdr_length = 1;
10203       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10204         src = 1;
10205       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10206         dst = 1;
10207       else if (unformat (input, "proto %d", &proto_val))
10208         proto = 1;
10209       else if (unformat (input, "tos %d", &tos_val))
10210         tos = 1;
10211       else if (unformat (input, "length %d", &length_val))
10212         length = 1;
10213       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10214         fragment_id = 1;
10215       else if (unformat (input, "ttl %d", &ttl_val))
10216         ttl = 1;
10217       else if (unformat (input, "checksum %d", &checksum_val))
10218         checksum = 1;
10219       else
10220         break;
10221     }
10222
10223   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10224       + ttl + checksum == 0)
10225     return 0;
10226
10227   /*
10228    * Aligned because we use the real comparison functions
10229    */
10230   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10231
10232   ip = (ip4_header_t *) match;
10233
10234   /* These are realistically matched in practice */
10235   if (src)
10236     ip->src_address.as_u32 = src_val.as_u32;
10237
10238   if (dst)
10239     ip->dst_address.as_u32 = dst_val.as_u32;
10240
10241   if (proto)
10242     ip->protocol = proto_val;
10243
10244
10245   /* These are not, but they're included for completeness */
10246   if (version)
10247     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10248
10249   if (hdr_length)
10250     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10251
10252   if (tos)
10253     ip->tos = tos_val;
10254
10255   if (length)
10256     ip->length = clib_host_to_net_u16 (length_val);
10257
10258   if (ttl)
10259     ip->ttl = ttl_val;
10260
10261   if (checksum)
10262     ip->checksum = clib_host_to_net_u16 (checksum_val);
10263
10264   *matchp = match;
10265   return 1;
10266 }
10267
10268 uword
10269 unformat_ip6_match (unformat_input_t * input, va_list * args)
10270 {
10271   u8 **matchp = va_arg (*args, u8 **);
10272   u8 *match = 0;
10273   ip6_header_t *ip;
10274   int version = 0;
10275   u32 version_val;
10276   u8 traffic_class = 0;
10277   u32 traffic_class_val = 0;
10278   u8 flow_label = 0;
10279   u8 flow_label_val;
10280   int src = 0, dst = 0;
10281   ip6_address_t src_val, dst_val;
10282   int proto = 0;
10283   u32 proto_val;
10284   int payload_length = 0;
10285   u32 payload_length_val;
10286   int hop_limit = 0;
10287   int hop_limit_val;
10288   u32 ip_version_traffic_class_and_flow_label;
10289
10290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10291     {
10292       if (unformat (input, "version %d", &version_val))
10293         version = 1;
10294       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10295         traffic_class = 1;
10296       else if (unformat (input, "flow_label %d", &flow_label_val))
10297         flow_label = 1;
10298       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10299         src = 1;
10300       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10301         dst = 1;
10302       else if (unformat (input, "proto %d", &proto_val))
10303         proto = 1;
10304       else if (unformat (input, "payload_length %d", &payload_length_val))
10305         payload_length = 1;
10306       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10307         hop_limit = 1;
10308       else
10309         break;
10310     }
10311
10312   if (version + traffic_class + flow_label + src + dst + proto +
10313       payload_length + hop_limit == 0)
10314     return 0;
10315
10316   /*
10317    * Aligned because we use the real comparison functions
10318    */
10319   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10320
10321   ip = (ip6_header_t *) match;
10322
10323   if (src)
10324     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10325
10326   if (dst)
10327     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10328
10329   if (proto)
10330     ip->protocol = proto_val;
10331
10332   ip_version_traffic_class_and_flow_label = 0;
10333
10334   if (version)
10335     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10336
10337   if (traffic_class)
10338     ip_version_traffic_class_and_flow_label |=
10339       (traffic_class_val & 0xFF) << 20;
10340
10341   if (flow_label)
10342     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10343
10344   ip->ip_version_traffic_class_and_flow_label =
10345     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10346
10347   if (payload_length)
10348     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10349
10350   if (hop_limit)
10351     ip->hop_limit = hop_limit_val;
10352
10353   *matchp = match;
10354   return 1;
10355 }
10356
10357 uword
10358 unformat_l3_match (unformat_input_t * input, va_list * args)
10359 {
10360   u8 **matchp = va_arg (*args, u8 **);
10361
10362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10363     {
10364       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10365         return 1;
10366       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10367         return 1;
10368       else
10369         break;
10370     }
10371   return 0;
10372 }
10373
10374 uword
10375 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10376 {
10377   u8 *tagp = va_arg (*args, u8 *);
10378   u32 tag;
10379
10380   if (unformat (input, "%d", &tag))
10381     {
10382       tagp[0] = (tag >> 8) & 0x0F;
10383       tagp[1] = tag & 0xFF;
10384       return 1;
10385     }
10386
10387   return 0;
10388 }
10389
10390 uword
10391 unformat_l2_match (unformat_input_t * input, va_list * args)
10392 {
10393   u8 **matchp = va_arg (*args, u8 **);
10394   u8 *match = 0;
10395   u8 src = 0;
10396   u8 src_val[6];
10397   u8 dst = 0;
10398   u8 dst_val[6];
10399   u8 proto = 0;
10400   u16 proto_val;
10401   u8 tag1 = 0;
10402   u8 tag1_val[2];
10403   u8 tag2 = 0;
10404   u8 tag2_val[2];
10405   int len = 14;
10406   u8 ignore_tag1 = 0;
10407   u8 ignore_tag2 = 0;
10408   u8 cos1 = 0;
10409   u8 cos2 = 0;
10410   u32 cos1_val = 0;
10411   u32 cos2_val = 0;
10412
10413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10414     {
10415       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10416         src = 1;
10417       else
10418         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10419         dst = 1;
10420       else if (unformat (input, "proto %U",
10421                          unformat_ethernet_type_host_byte_order, &proto_val))
10422         proto = 1;
10423       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10424         tag1 = 1;
10425       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10426         tag2 = 1;
10427       else if (unformat (input, "ignore-tag1"))
10428         ignore_tag1 = 1;
10429       else if (unformat (input, "ignore-tag2"))
10430         ignore_tag2 = 1;
10431       else if (unformat (input, "cos1 %d", &cos1_val))
10432         cos1 = 1;
10433       else if (unformat (input, "cos2 %d", &cos2_val))
10434         cos2 = 1;
10435       else
10436         break;
10437     }
10438   if ((src + dst + proto + tag1 + tag2 +
10439        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10440     return 0;
10441
10442   if (tag1 || ignore_tag1 || cos1)
10443     len = 18;
10444   if (tag2 || ignore_tag2 || cos2)
10445     len = 22;
10446
10447   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10448
10449   if (dst)
10450     clib_memcpy (match, dst_val, 6);
10451
10452   if (src)
10453     clib_memcpy (match + 6, src_val, 6);
10454
10455   if (tag2)
10456     {
10457       /* inner vlan tag */
10458       match[19] = tag2_val[1];
10459       match[18] = tag2_val[0];
10460       if (cos2)
10461         match[18] |= (cos2_val & 0x7) << 5;
10462       if (proto)
10463         {
10464           match[21] = proto_val & 0xff;
10465           match[20] = proto_val >> 8;
10466         }
10467       if (tag1)
10468         {
10469           match[15] = tag1_val[1];
10470           match[14] = tag1_val[0];
10471         }
10472       if (cos1)
10473         match[14] |= (cos1_val & 0x7) << 5;
10474       *matchp = match;
10475       return 1;
10476     }
10477   if (tag1)
10478     {
10479       match[15] = tag1_val[1];
10480       match[14] = tag1_val[0];
10481       if (proto)
10482         {
10483           match[17] = proto_val & 0xff;
10484           match[16] = proto_val >> 8;
10485         }
10486       if (cos1)
10487         match[14] |= (cos1_val & 0x7) << 5;
10488
10489       *matchp = match;
10490       return 1;
10491     }
10492   if (cos2)
10493     match[18] |= (cos2_val & 0x7) << 5;
10494   if (cos1)
10495     match[14] |= (cos1_val & 0x7) << 5;
10496   if (proto)
10497     {
10498       match[13] = proto_val & 0xff;
10499       match[12] = proto_val >> 8;
10500     }
10501
10502   *matchp = match;
10503   return 1;
10504 }
10505
10506 uword
10507 unformat_qos_source (unformat_input_t * input, va_list * args)
10508 {
10509   int *qs = va_arg (*args, int *);
10510
10511   if (unformat (input, "ip"))
10512     *qs = QOS_SOURCE_IP;
10513   else if (unformat (input, "mpls"))
10514     *qs = QOS_SOURCE_MPLS;
10515   else if (unformat (input, "ext"))
10516     *qs = QOS_SOURCE_EXT;
10517   else if (unformat (input, "vlan"))
10518     *qs = QOS_SOURCE_VLAN;
10519   else
10520     return 0;
10521
10522   return 1;
10523 }
10524 #endif
10525
10526 uword
10527 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10528 {
10529   u8 **matchp = va_arg (*args, u8 **);
10530   u32 skip_n_vectors = va_arg (*args, u32);
10531   u32 match_n_vectors = va_arg (*args, u32);
10532
10533   u8 *match = 0;
10534   u8 *l2 = 0;
10535   u8 *l3 = 0;
10536   u8 *l4 = 0;
10537
10538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10539     {
10540       if (unformat (input, "hex %U", unformat_hex_string, &match))
10541         ;
10542       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10543         ;
10544       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10545         ;
10546       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10547         ;
10548       else
10549         break;
10550     }
10551
10552   if (l4 && !l3)
10553     {
10554       vec_free (match);
10555       vec_free (l2);
10556       vec_free (l4);
10557       return 0;
10558     }
10559
10560   if (match || l2 || l3 || l4)
10561     {
10562       if (l2 || l3 || l4)
10563         {
10564           /* "Win a free Ethernet header in every packet" */
10565           if (l2 == 0)
10566             vec_validate_aligned (l2, 13, sizeof (u32x4));
10567           match = l2;
10568           if (vec_len (l3))
10569             {
10570               vec_append_aligned (match, l3, sizeof (u32x4));
10571               vec_free (l3);
10572             }
10573           if (vec_len (l4))
10574             {
10575               vec_append_aligned (match, l4, sizeof (u32x4));
10576               vec_free (l4);
10577             }
10578         }
10579
10580       /* Make sure the vector is big enough even if key is all 0's */
10581       vec_validate_aligned
10582         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10583          sizeof (u32x4));
10584
10585       /* Set size, include skipped vectors */
10586       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10587
10588       *matchp = match;
10589
10590       return 1;
10591     }
10592
10593   return 0;
10594 }
10595
10596 static int
10597 api_classify_add_del_session (vat_main_t * vam)
10598 {
10599   unformat_input_t *i = vam->input;
10600   vl_api_classify_add_del_session_t *mp;
10601   int is_add = 1;
10602   u32 table_index = ~0;
10603   u32 hit_next_index = ~0;
10604   u32 opaque_index = ~0;
10605   u8 *match = 0;
10606   i32 advance = 0;
10607   u32 skip_n_vectors = 0;
10608   u32 match_n_vectors = 0;
10609   u32 action = 0;
10610   u32 metadata = 0;
10611   int ret;
10612
10613   /*
10614    * Warning: you have to supply skip_n and match_n
10615    * because the API client cant simply look at the classify
10616    * table object.
10617    */
10618
10619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10620     {
10621       if (unformat (i, "del"))
10622         is_add = 0;
10623       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10624                          &hit_next_index))
10625         ;
10626       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10627                          &hit_next_index))
10628         ;
10629       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10630                          &hit_next_index))
10631         ;
10632       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10633         ;
10634       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10635         ;
10636       else if (unformat (i, "opaque-index %d", &opaque_index))
10637         ;
10638       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10639         ;
10640       else if (unformat (i, "match_n %d", &match_n_vectors))
10641         ;
10642       else if (unformat (i, "match %U", api_unformat_classify_match,
10643                          &match, skip_n_vectors, match_n_vectors))
10644         ;
10645       else if (unformat (i, "advance %d", &advance))
10646         ;
10647       else if (unformat (i, "table-index %d", &table_index))
10648         ;
10649       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10650         action = 1;
10651       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10652         action = 2;
10653       else if (unformat (i, "action %d", &action))
10654         ;
10655       else if (unformat (i, "metadata %d", &metadata))
10656         ;
10657       else
10658         break;
10659     }
10660
10661   if (table_index == ~0)
10662     {
10663       errmsg ("Table index required");
10664       return -99;
10665     }
10666
10667   if (is_add && match == 0)
10668     {
10669       errmsg ("Match value required");
10670       return -99;
10671     }
10672
10673   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10674
10675   mp->is_add = is_add;
10676   mp->table_index = ntohl (table_index);
10677   mp->hit_next_index = ntohl (hit_next_index);
10678   mp->opaque_index = ntohl (opaque_index);
10679   mp->advance = ntohl (advance);
10680   mp->action = action;
10681   mp->metadata = ntohl (metadata);
10682   mp->match_len = ntohl (vec_len (match));
10683   clib_memcpy (mp->match, match, vec_len (match));
10684   vec_free (match);
10685
10686   S (mp);
10687   W (ret);
10688   return ret;
10689 }
10690
10691 static int
10692 api_classify_set_interface_ip_table (vat_main_t * vam)
10693 {
10694   unformat_input_t *i = vam->input;
10695   vl_api_classify_set_interface_ip_table_t *mp;
10696   u32 sw_if_index;
10697   int sw_if_index_set;
10698   u32 table_index = ~0;
10699   u8 is_ipv6 = 0;
10700   int ret;
10701
10702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10705         sw_if_index_set = 1;
10706       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10707         sw_if_index_set = 1;
10708       else if (unformat (i, "table %d", &table_index))
10709         ;
10710       else
10711         {
10712           clib_warning ("parse error '%U'", format_unformat_error, i);
10713           return -99;
10714         }
10715     }
10716
10717   if (sw_if_index_set == 0)
10718     {
10719       errmsg ("missing interface name or sw_if_index");
10720       return -99;
10721     }
10722
10723
10724   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10725
10726   mp->sw_if_index = ntohl (sw_if_index);
10727   mp->table_index = ntohl (table_index);
10728   mp->is_ipv6 = is_ipv6;
10729
10730   S (mp);
10731   W (ret);
10732   return ret;
10733 }
10734
10735 static int
10736 api_classify_set_interface_l2_tables (vat_main_t * vam)
10737 {
10738   unformat_input_t *i = vam->input;
10739   vl_api_classify_set_interface_l2_tables_t *mp;
10740   u32 sw_if_index;
10741   int sw_if_index_set;
10742   u32 ip4_table_index = ~0;
10743   u32 ip6_table_index = ~0;
10744   u32 other_table_index = ~0;
10745   u32 is_input = 1;
10746   int ret;
10747
10748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10749     {
10750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10751         sw_if_index_set = 1;
10752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10753         sw_if_index_set = 1;
10754       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10755         ;
10756       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10757         ;
10758       else if (unformat (i, "other-table %d", &other_table_index))
10759         ;
10760       else if (unformat (i, "is-input %d", &is_input))
10761         ;
10762       else
10763         {
10764           clib_warning ("parse error '%U'", format_unformat_error, i);
10765           return -99;
10766         }
10767     }
10768
10769   if (sw_if_index_set == 0)
10770     {
10771       errmsg ("missing interface name or sw_if_index");
10772       return -99;
10773     }
10774
10775
10776   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10777
10778   mp->sw_if_index = ntohl (sw_if_index);
10779   mp->ip4_table_index = ntohl (ip4_table_index);
10780   mp->ip6_table_index = ntohl (ip6_table_index);
10781   mp->other_table_index = ntohl (other_table_index);
10782   mp->is_input = (u8) is_input;
10783
10784   S (mp);
10785   W (ret);
10786   return ret;
10787 }
10788
10789 static int
10790 api_set_ipfix_exporter (vat_main_t * vam)
10791 {
10792   unformat_input_t *i = vam->input;
10793   vl_api_set_ipfix_exporter_t *mp;
10794   ip4_address_t collector_address;
10795   u8 collector_address_set = 0;
10796   u32 collector_port = ~0;
10797   ip4_address_t src_address;
10798   u8 src_address_set = 0;
10799   u32 vrf_id = ~0;
10800   u32 path_mtu = ~0;
10801   u32 template_interval = ~0;
10802   u8 udp_checksum = 0;
10803   int ret;
10804
10805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10806     {
10807       if (unformat (i, "collector_address %U", unformat_ip4_address,
10808                     &collector_address))
10809         collector_address_set = 1;
10810       else if (unformat (i, "collector_port %d", &collector_port))
10811         ;
10812       else if (unformat (i, "src_address %U", unformat_ip4_address,
10813                          &src_address))
10814         src_address_set = 1;
10815       else if (unformat (i, "vrf_id %d", &vrf_id))
10816         ;
10817       else if (unformat (i, "path_mtu %d", &path_mtu))
10818         ;
10819       else if (unformat (i, "template_interval %d", &template_interval))
10820         ;
10821       else if (unformat (i, "udp_checksum"))
10822         udp_checksum = 1;
10823       else
10824         break;
10825     }
10826
10827   if (collector_address_set == 0)
10828     {
10829       errmsg ("collector_address required");
10830       return -99;
10831     }
10832
10833   if (src_address_set == 0)
10834     {
10835       errmsg ("src_address required");
10836       return -99;
10837     }
10838
10839   M (SET_IPFIX_EXPORTER, mp);
10840
10841   memcpy (mp->collector_address.un.ip4, collector_address.data,
10842           sizeof (collector_address.data));
10843   mp->collector_port = htons ((u16) collector_port);
10844   memcpy (mp->src_address.un.ip4, src_address.data,
10845           sizeof (src_address.data));
10846   mp->vrf_id = htonl (vrf_id);
10847   mp->path_mtu = htonl (path_mtu);
10848   mp->template_interval = htonl (template_interval);
10849   mp->udp_checksum = udp_checksum;
10850
10851   S (mp);
10852   W (ret);
10853   return ret;
10854 }
10855
10856 static int
10857 api_set_ipfix_classify_stream (vat_main_t * vam)
10858 {
10859   unformat_input_t *i = vam->input;
10860   vl_api_set_ipfix_classify_stream_t *mp;
10861   u32 domain_id = 0;
10862   u32 src_port = UDP_DST_PORT_ipfix;
10863   int ret;
10864
10865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10866     {
10867       if (unformat (i, "domain %d", &domain_id))
10868         ;
10869       else if (unformat (i, "src_port %d", &src_port))
10870         ;
10871       else
10872         {
10873           errmsg ("unknown input `%U'", format_unformat_error, i);
10874           return -99;
10875         }
10876     }
10877
10878   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10879
10880   mp->domain_id = htonl (domain_id);
10881   mp->src_port = htons ((u16) src_port);
10882
10883   S (mp);
10884   W (ret);
10885   return ret;
10886 }
10887
10888 static int
10889 api_ipfix_classify_table_add_del (vat_main_t * vam)
10890 {
10891   unformat_input_t *i = vam->input;
10892   vl_api_ipfix_classify_table_add_del_t *mp;
10893   int is_add = -1;
10894   u32 classify_table_index = ~0;
10895   u8 ip_version = 0;
10896   u8 transport_protocol = 255;
10897   int ret;
10898
10899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10900     {
10901       if (unformat (i, "add"))
10902         is_add = 1;
10903       else if (unformat (i, "del"))
10904         is_add = 0;
10905       else if (unformat (i, "table %d", &classify_table_index))
10906         ;
10907       else if (unformat (i, "ip4"))
10908         ip_version = 4;
10909       else if (unformat (i, "ip6"))
10910         ip_version = 6;
10911       else if (unformat (i, "tcp"))
10912         transport_protocol = 6;
10913       else if (unformat (i, "udp"))
10914         transport_protocol = 17;
10915       else
10916         {
10917           errmsg ("unknown input `%U'", format_unformat_error, i);
10918           return -99;
10919         }
10920     }
10921
10922   if (is_add == -1)
10923     {
10924       errmsg ("expecting: add|del");
10925       return -99;
10926     }
10927   if (classify_table_index == ~0)
10928     {
10929       errmsg ("classifier table not specified");
10930       return -99;
10931     }
10932   if (ip_version == 0)
10933     {
10934       errmsg ("IP version not specified");
10935       return -99;
10936     }
10937
10938   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10939
10940   mp->is_add = is_add;
10941   mp->table_id = htonl (classify_table_index);
10942   mp->ip_version = ip_version;
10943   mp->transport_protocol = transport_protocol;
10944
10945   S (mp);
10946   W (ret);
10947   return ret;
10948 }
10949
10950 static int
10951 api_get_node_index (vat_main_t * vam)
10952 {
10953   unformat_input_t *i = vam->input;
10954   vl_api_get_node_index_t *mp;
10955   u8 *name = 0;
10956   int ret;
10957
10958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (i, "node %s", &name))
10961         ;
10962       else
10963         break;
10964     }
10965   if (name == 0)
10966     {
10967       errmsg ("node name required");
10968       return -99;
10969     }
10970   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10971     {
10972       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10973       return -99;
10974     }
10975
10976   M (GET_NODE_INDEX, mp);
10977   clib_memcpy (mp->node_name, name, vec_len (name));
10978   vec_free (name);
10979
10980   S (mp);
10981   W (ret);
10982   return ret;
10983 }
10984
10985 static int
10986 api_get_next_index (vat_main_t * vam)
10987 {
10988   unformat_input_t *i = vam->input;
10989   vl_api_get_next_index_t *mp;
10990   u8 *node_name = 0, *next_node_name = 0;
10991   int ret;
10992
10993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10994     {
10995       if (unformat (i, "node-name %s", &node_name))
10996         ;
10997       else if (unformat (i, "next-node-name %s", &next_node_name))
10998         break;
10999     }
11000
11001   if (node_name == 0)
11002     {
11003       errmsg ("node name required");
11004       return -99;
11005     }
11006   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11007     {
11008       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11009       return -99;
11010     }
11011
11012   if (next_node_name == 0)
11013     {
11014       errmsg ("next node name required");
11015       return -99;
11016     }
11017   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11018     {
11019       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11020       return -99;
11021     }
11022
11023   M (GET_NEXT_INDEX, mp);
11024   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11025   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11026   vec_free (node_name);
11027   vec_free (next_node_name);
11028
11029   S (mp);
11030   W (ret);
11031   return ret;
11032 }
11033
11034 static int
11035 api_add_node_next (vat_main_t * vam)
11036 {
11037   unformat_input_t *i = vam->input;
11038   vl_api_add_node_next_t *mp;
11039   u8 *name = 0;
11040   u8 *next = 0;
11041   int ret;
11042
11043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11044     {
11045       if (unformat (i, "node %s", &name))
11046         ;
11047       else if (unformat (i, "next %s", &next))
11048         ;
11049       else
11050         break;
11051     }
11052   if (name == 0)
11053     {
11054       errmsg ("node name required");
11055       return -99;
11056     }
11057   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11058     {
11059       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11060       return -99;
11061     }
11062   if (next == 0)
11063     {
11064       errmsg ("next node required");
11065       return -99;
11066     }
11067   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11068     {
11069       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11070       return -99;
11071     }
11072
11073   M (ADD_NODE_NEXT, mp);
11074   clib_memcpy (mp->node_name, name, vec_len (name));
11075   clib_memcpy (mp->next_name, next, vec_len (next));
11076   vec_free (name);
11077   vec_free (next);
11078
11079   S (mp);
11080   W (ret);
11081   return ret;
11082 }
11083
11084 static int
11085 api_l2tpv3_create_tunnel (vat_main_t * vam)
11086 {
11087   unformat_input_t *i = vam->input;
11088   ip6_address_t client_address, our_address;
11089   int client_address_set = 0;
11090   int our_address_set = 0;
11091   u32 local_session_id = 0;
11092   u32 remote_session_id = 0;
11093   u64 local_cookie = 0;
11094   u64 remote_cookie = 0;
11095   u8 l2_sublayer_present = 0;
11096   vl_api_l2tpv3_create_tunnel_t *mp;
11097   int ret;
11098
11099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11100     {
11101       if (unformat (i, "client_address %U", unformat_ip6_address,
11102                     &client_address))
11103         client_address_set = 1;
11104       else if (unformat (i, "our_address %U", unformat_ip6_address,
11105                          &our_address))
11106         our_address_set = 1;
11107       else if (unformat (i, "local_session_id %d", &local_session_id))
11108         ;
11109       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11110         ;
11111       else if (unformat (i, "local_cookie %lld", &local_cookie))
11112         ;
11113       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11114         ;
11115       else if (unformat (i, "l2-sublayer-present"))
11116         l2_sublayer_present = 1;
11117       else
11118         break;
11119     }
11120
11121   if (client_address_set == 0)
11122     {
11123       errmsg ("client_address required");
11124       return -99;
11125     }
11126
11127   if (our_address_set == 0)
11128     {
11129       errmsg ("our_address required");
11130       return -99;
11131     }
11132
11133   M (L2TPV3_CREATE_TUNNEL, mp);
11134
11135   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11136                sizeof (ip6_address_t));
11137
11138   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11139                sizeof (ip6_address_t));
11140
11141   mp->local_session_id = ntohl (local_session_id);
11142   mp->remote_session_id = ntohl (remote_session_id);
11143   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11144   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11145   mp->l2_sublayer_present = l2_sublayer_present;
11146
11147   S (mp);
11148   W (ret);
11149   return ret;
11150 }
11151
11152 static int
11153 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11154 {
11155   unformat_input_t *i = vam->input;
11156   u32 sw_if_index;
11157   u8 sw_if_index_set = 0;
11158   u64 new_local_cookie = 0;
11159   u64 new_remote_cookie = 0;
11160   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11161   int ret;
11162
11163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11164     {
11165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11166         sw_if_index_set = 1;
11167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11168         sw_if_index_set = 1;
11169       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11170         ;
11171       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11172         ;
11173       else
11174         break;
11175     }
11176
11177   if (sw_if_index_set == 0)
11178     {
11179       errmsg ("missing interface name or sw_if_index");
11180       return -99;
11181     }
11182
11183   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11184
11185   mp->sw_if_index = ntohl (sw_if_index);
11186   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11187   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11188
11189   S (mp);
11190   W (ret);
11191   return ret;
11192 }
11193
11194 static int
11195 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11196 {
11197   unformat_input_t *i = vam->input;
11198   vl_api_l2tpv3_interface_enable_disable_t *mp;
11199   u32 sw_if_index;
11200   u8 sw_if_index_set = 0;
11201   u8 enable_disable = 1;
11202   int ret;
11203
11204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11205     {
11206       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11207         sw_if_index_set = 1;
11208       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11209         sw_if_index_set = 1;
11210       else if (unformat (i, "enable"))
11211         enable_disable = 1;
11212       else if (unformat (i, "disable"))
11213         enable_disable = 0;
11214       else
11215         break;
11216     }
11217
11218   if (sw_if_index_set == 0)
11219     {
11220       errmsg ("missing interface name or sw_if_index");
11221       return -99;
11222     }
11223
11224   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11225
11226   mp->sw_if_index = ntohl (sw_if_index);
11227   mp->enable_disable = enable_disable;
11228
11229   S (mp);
11230   W (ret);
11231   return ret;
11232 }
11233
11234 static int
11235 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11236 {
11237   unformat_input_t *i = vam->input;
11238   vl_api_l2tpv3_set_lookup_key_t *mp;
11239   u8 key = ~0;
11240   int ret;
11241
11242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11243     {
11244       if (unformat (i, "lookup_v6_src"))
11245         key = L2T_LOOKUP_SRC_ADDRESS;
11246       else if (unformat (i, "lookup_v6_dst"))
11247         key = L2T_LOOKUP_DST_ADDRESS;
11248       else if (unformat (i, "lookup_session_id"))
11249         key = L2T_LOOKUP_SESSION_ID;
11250       else
11251         break;
11252     }
11253
11254   if (key == (u8) ~ 0)
11255     {
11256       errmsg ("l2tp session lookup key unset");
11257       return -99;
11258     }
11259
11260   M (L2TPV3_SET_LOOKUP_KEY, mp);
11261
11262   mp->key = key;
11263
11264   S (mp);
11265   W (ret);
11266   return ret;
11267 }
11268
11269 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11270   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11271 {
11272   vat_main_t *vam = &vat_main;
11273
11274   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11275          format_ip6_address, mp->our_address,
11276          format_ip6_address, mp->client_address,
11277          clib_net_to_host_u32 (mp->sw_if_index));
11278
11279   print (vam->ofp,
11280          "   local cookies %016llx %016llx remote cookie %016llx",
11281          clib_net_to_host_u64 (mp->local_cookie[0]),
11282          clib_net_to_host_u64 (mp->local_cookie[1]),
11283          clib_net_to_host_u64 (mp->remote_cookie));
11284
11285   print (vam->ofp, "   local session-id %d remote session-id %d",
11286          clib_net_to_host_u32 (mp->local_session_id),
11287          clib_net_to_host_u32 (mp->remote_session_id));
11288
11289   print (vam->ofp, "   l2 specific sublayer %s\n",
11290          mp->l2_sublayer_present ? "preset" : "absent");
11291
11292 }
11293
11294 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11295   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11296 {
11297   vat_main_t *vam = &vat_main;
11298   vat_json_node_t *node = NULL;
11299   struct in6_addr addr;
11300
11301   if (VAT_JSON_ARRAY != vam->json_tree.type)
11302     {
11303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11304       vat_json_init_array (&vam->json_tree);
11305     }
11306   node = vat_json_array_add (&vam->json_tree);
11307
11308   vat_json_init_object (node);
11309
11310   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11311   vat_json_object_add_ip6 (node, "our_address", addr);
11312   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11313   vat_json_object_add_ip6 (node, "client_address", addr);
11314
11315   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11316   vat_json_init_array (lc);
11317   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11318   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11319   vat_json_object_add_uint (node, "remote_cookie",
11320                             clib_net_to_host_u64 (mp->remote_cookie));
11321
11322   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11323   vat_json_object_add_uint (node, "local_session_id",
11324                             clib_net_to_host_u32 (mp->local_session_id));
11325   vat_json_object_add_uint (node, "remote_session_id",
11326                             clib_net_to_host_u32 (mp->remote_session_id));
11327   vat_json_object_add_string_copy (node, "l2_sublayer",
11328                                    mp->l2_sublayer_present ? (u8 *) "present"
11329                                    : (u8 *) "absent");
11330 }
11331
11332 static int
11333 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11334 {
11335   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11336   vl_api_control_ping_t *mp_ping;
11337   int ret;
11338
11339   /* Get list of l2tpv3-tunnel interfaces */
11340   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11341   S (mp);
11342
11343   /* Use a control ping for synchronization */
11344   MPING (CONTROL_PING, mp_ping);
11345   S (mp_ping);
11346
11347   W (ret);
11348   return ret;
11349 }
11350
11351
11352 static void vl_api_sw_interface_tap_v2_details_t_handler
11353   (vl_api_sw_interface_tap_v2_details_t * mp)
11354 {
11355   vat_main_t *vam = &vat_main;
11356
11357   u8 *ip4 =
11358     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11359             mp->host_ip4_prefix.len);
11360   u8 *ip6 =
11361     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11362             mp->host_ip6_prefix.len);
11363
11364   print (vam->ofp,
11365          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11366          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11367          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11368          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11369          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11370
11371   vec_free (ip4);
11372   vec_free (ip6);
11373 }
11374
11375 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11376   (vl_api_sw_interface_tap_v2_details_t * mp)
11377 {
11378   vat_main_t *vam = &vat_main;
11379   vat_json_node_t *node = NULL;
11380
11381   if (VAT_JSON_ARRAY != vam->json_tree.type)
11382     {
11383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11384       vat_json_init_array (&vam->json_tree);
11385     }
11386   node = vat_json_array_add (&vam->json_tree);
11387
11388   vat_json_init_object (node);
11389   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11390   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11391   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11392   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11393   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11394   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11395   vat_json_object_add_string_copy (node, "host_mac_addr",
11396                                    format (0, "%U", format_ethernet_address,
11397                                            &mp->host_mac_addr));
11398   vat_json_object_add_string_copy (node, "host_namespace",
11399                                    mp->host_namespace);
11400   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11401   vat_json_object_add_string_copy (node, "host_ip4_addr",
11402                                    format (0, "%U/%d", format_ip4_address,
11403                                            mp->host_ip4_prefix.address,
11404                                            mp->host_ip4_prefix.len));
11405   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11406                                    format (0, "%U/%d", format_ip6_address,
11407                                            mp->host_ip6_prefix.address,
11408                                            mp->host_ip6_prefix.len));
11409
11410 }
11411
11412 static int
11413 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11414 {
11415   vl_api_sw_interface_tap_v2_dump_t *mp;
11416   vl_api_control_ping_t *mp_ping;
11417   int ret;
11418
11419   print (vam->ofp,
11420          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11421          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11422          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11423          "host_ip6_addr");
11424
11425   /* Get list of tap interfaces */
11426   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11427   S (mp);
11428
11429   /* Use a control ping for synchronization */
11430   MPING (CONTROL_PING, mp_ping);
11431   S (mp_ping);
11432
11433   W (ret);
11434   return ret;
11435 }
11436
11437 static void vl_api_sw_interface_virtio_pci_details_t_handler
11438   (vl_api_sw_interface_virtio_pci_details_t * mp)
11439 {
11440   vat_main_t *vam = &vat_main;
11441
11442   typedef union
11443   {
11444     struct
11445     {
11446       u16 domain;
11447       u8 bus;
11448       u8 slot:5;
11449       u8 function:3;
11450     };
11451     u32 as_u32;
11452   } pci_addr_t;
11453   pci_addr_t addr;
11454
11455   addr.domain = ntohs (mp->pci_addr.domain);
11456   addr.bus = mp->pci_addr.bus;
11457   addr.slot = mp->pci_addr.slot;
11458   addr.function = mp->pci_addr.function;
11459
11460   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11461                          addr.slot, addr.function);
11462
11463   print (vam->ofp,
11464          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11465          pci_addr, ntohl (mp->sw_if_index),
11466          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11467          format_ethernet_address, mp->mac_addr,
11468          clib_net_to_host_u64 (mp->features));
11469   vec_free (pci_addr);
11470 }
11471
11472 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11473   (vl_api_sw_interface_virtio_pci_details_t * mp)
11474 {
11475   vat_main_t *vam = &vat_main;
11476   vat_json_node_t *node = NULL;
11477   vlib_pci_addr_t pci_addr;
11478
11479   if (VAT_JSON_ARRAY != vam->json_tree.type)
11480     {
11481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11482       vat_json_init_array (&vam->json_tree);
11483     }
11484   node = vat_json_array_add (&vam->json_tree);
11485
11486   pci_addr.domain = ntohs (mp->pci_addr.domain);
11487   pci_addr.bus = mp->pci_addr.bus;
11488   pci_addr.slot = mp->pci_addr.slot;
11489   pci_addr.function = mp->pci_addr.function;
11490
11491   vat_json_init_object (node);
11492   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11493   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11494   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11495   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11496   vat_json_object_add_uint (node, "features",
11497                             clib_net_to_host_u64 (mp->features));
11498   vat_json_object_add_string_copy (node, "mac_addr",
11499                                    format (0, "%U", format_ethernet_address,
11500                                            &mp->mac_addr));
11501 }
11502
11503 static int
11504 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11505 {
11506   vl_api_sw_interface_virtio_pci_dump_t *mp;
11507   vl_api_control_ping_t *mp_ping;
11508   int ret;
11509
11510   print (vam->ofp,
11511          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11512          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11513          "mac_addr", "features");
11514
11515   /* Get list of tap interfaces */
11516   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11517   S (mp);
11518
11519   /* Use a control ping for synchronization */
11520   MPING (CONTROL_PING, mp_ping);
11521   S (mp_ping);
11522
11523   W (ret);
11524   return ret;
11525 }
11526
11527 static int
11528 api_vxlan_offload_rx (vat_main_t * vam)
11529 {
11530   unformat_input_t *line_input = vam->input;
11531   vl_api_vxlan_offload_rx_t *mp;
11532   u32 hw_if_index = ~0, rx_if_index = ~0;
11533   u8 is_add = 1;
11534   int ret;
11535
11536   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11537     {
11538       if (unformat (line_input, "del"))
11539         is_add = 0;
11540       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11541                          &hw_if_index))
11542         ;
11543       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11544         ;
11545       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11546                          &rx_if_index))
11547         ;
11548       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11549         ;
11550       else
11551         {
11552           errmsg ("parse error '%U'", format_unformat_error, line_input);
11553           return -99;
11554         }
11555     }
11556
11557   if (hw_if_index == ~0)
11558     {
11559       errmsg ("no hw interface");
11560       return -99;
11561     }
11562
11563   if (rx_if_index == ~0)
11564     {
11565       errmsg ("no rx tunnel");
11566       return -99;
11567     }
11568
11569   M (VXLAN_OFFLOAD_RX, mp);
11570
11571   mp->hw_if_index = ntohl (hw_if_index);
11572   mp->sw_if_index = ntohl (rx_if_index);
11573   mp->enable = is_add;
11574
11575   S (mp);
11576   W (ret);
11577   return ret;
11578 }
11579
11580 static uword unformat_vxlan_decap_next
11581   (unformat_input_t * input, va_list * args)
11582 {
11583   u32 *result = va_arg (*args, u32 *);
11584   u32 tmp;
11585
11586   if (unformat (input, "l2"))
11587     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11588   else if (unformat (input, "%d", &tmp))
11589     *result = tmp;
11590   else
11591     return 0;
11592   return 1;
11593 }
11594
11595 static int
11596 api_vxlan_add_del_tunnel (vat_main_t * vam)
11597 {
11598   unformat_input_t *line_input = vam->input;
11599   vl_api_vxlan_add_del_tunnel_t *mp;
11600   ip46_address_t src, dst;
11601   u8 is_add = 1;
11602   u8 ipv4_set = 0, ipv6_set = 0;
11603   u8 src_set = 0;
11604   u8 dst_set = 0;
11605   u8 grp_set = 0;
11606   u32 instance = ~0;
11607   u32 mcast_sw_if_index = ~0;
11608   u32 encap_vrf_id = 0;
11609   u32 decap_next_index = ~0;
11610   u32 vni = 0;
11611   int ret;
11612
11613   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11614   clib_memset (&src, 0, sizeof src);
11615   clib_memset (&dst, 0, sizeof dst);
11616
11617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11618     {
11619       if (unformat (line_input, "del"))
11620         is_add = 0;
11621       else if (unformat (line_input, "instance %d", &instance))
11622         ;
11623       else
11624         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11625         {
11626           ipv4_set = 1;
11627           src_set = 1;
11628         }
11629       else
11630         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11631         {
11632           ipv4_set = 1;
11633           dst_set = 1;
11634         }
11635       else
11636         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11637         {
11638           ipv6_set = 1;
11639           src_set = 1;
11640         }
11641       else
11642         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11643         {
11644           ipv6_set = 1;
11645           dst_set = 1;
11646         }
11647       else if (unformat (line_input, "group %U %U",
11648                          unformat_ip4_address, &dst.ip4,
11649                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11650         {
11651           grp_set = dst_set = 1;
11652           ipv4_set = 1;
11653         }
11654       else if (unformat (line_input, "group %U",
11655                          unformat_ip4_address, &dst.ip4))
11656         {
11657           grp_set = dst_set = 1;
11658           ipv4_set = 1;
11659         }
11660       else if (unformat (line_input, "group %U %U",
11661                          unformat_ip6_address, &dst.ip6,
11662                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11663         {
11664           grp_set = dst_set = 1;
11665           ipv6_set = 1;
11666         }
11667       else if (unformat (line_input, "group %U",
11668                          unformat_ip6_address, &dst.ip6))
11669         {
11670           grp_set = dst_set = 1;
11671           ipv6_set = 1;
11672         }
11673       else
11674         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11675         ;
11676       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11677         ;
11678       else if (unformat (line_input, "decap-next %U",
11679                          unformat_vxlan_decap_next, &decap_next_index))
11680         ;
11681       else if (unformat (line_input, "vni %d", &vni))
11682         ;
11683       else
11684         {
11685           errmsg ("parse error '%U'", format_unformat_error, line_input);
11686           return -99;
11687         }
11688     }
11689
11690   if (src_set == 0)
11691     {
11692       errmsg ("tunnel src address not specified");
11693       return -99;
11694     }
11695   if (dst_set == 0)
11696     {
11697       errmsg ("tunnel dst address not specified");
11698       return -99;
11699     }
11700
11701   if (grp_set && !ip46_address_is_multicast (&dst))
11702     {
11703       errmsg ("tunnel group address not multicast");
11704       return -99;
11705     }
11706   if (grp_set && mcast_sw_if_index == ~0)
11707     {
11708       errmsg ("tunnel nonexistent multicast device");
11709       return -99;
11710     }
11711   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11712     {
11713       errmsg ("tunnel dst address must be unicast");
11714       return -99;
11715     }
11716
11717
11718   if (ipv4_set && ipv6_set)
11719     {
11720       errmsg ("both IPv4 and IPv6 addresses specified");
11721       return -99;
11722     }
11723
11724   if ((vni == 0) || (vni >> 24))
11725     {
11726       errmsg ("vni not specified or out of range");
11727       return -99;
11728     }
11729
11730   M (VXLAN_ADD_DEL_TUNNEL, mp);
11731
11732   if (ipv6_set)
11733     {
11734       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11735       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11736     }
11737   else
11738     {
11739       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11740       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11741     }
11742   mp->src_address.af = ipv6_set;
11743   mp->dst_address.af = ipv6_set;
11744
11745   mp->instance = htonl (instance);
11746   mp->encap_vrf_id = ntohl (encap_vrf_id);
11747   mp->decap_next_index = ntohl (decap_next_index);
11748   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11749   mp->vni = ntohl (vni);
11750   mp->is_add = is_add;
11751
11752   S (mp);
11753   W (ret);
11754   return ret;
11755 }
11756
11757 static void vl_api_vxlan_tunnel_details_t_handler
11758   (vl_api_vxlan_tunnel_details_t * mp)
11759 {
11760   vat_main_t *vam = &vat_main;
11761   ip46_address_t src =
11762     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11763   ip46_address_t dst =
11764     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11765
11766   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11767          ntohl (mp->sw_if_index),
11768          ntohl (mp->instance),
11769          format_ip46_address, &src, IP46_TYPE_ANY,
11770          format_ip46_address, &dst, IP46_TYPE_ANY,
11771          ntohl (mp->encap_vrf_id),
11772          ntohl (mp->decap_next_index), ntohl (mp->vni),
11773          ntohl (mp->mcast_sw_if_index));
11774 }
11775
11776 static void vl_api_vxlan_tunnel_details_t_handler_json
11777   (vl_api_vxlan_tunnel_details_t * mp)
11778 {
11779   vat_main_t *vam = &vat_main;
11780   vat_json_node_t *node = NULL;
11781
11782   if (VAT_JSON_ARRAY != vam->json_tree.type)
11783     {
11784       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11785       vat_json_init_array (&vam->json_tree);
11786     }
11787   node = vat_json_array_add (&vam->json_tree);
11788
11789   vat_json_init_object (node);
11790   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11791
11792   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11793
11794   if (mp->src_address.af)
11795     {
11796       struct in6_addr ip6;
11797
11798       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11799       vat_json_object_add_ip6 (node, "src_address", ip6);
11800       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11801       vat_json_object_add_ip6 (node, "dst_address", ip6);
11802     }
11803   else
11804     {
11805       struct in_addr ip4;
11806
11807       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11808       vat_json_object_add_ip4 (node, "src_address", ip4);
11809       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11810       vat_json_object_add_ip4 (node, "dst_address", ip4);
11811     }
11812   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11813   vat_json_object_add_uint (node, "decap_next_index",
11814                             ntohl (mp->decap_next_index));
11815   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11816   vat_json_object_add_uint (node, "mcast_sw_if_index",
11817                             ntohl (mp->mcast_sw_if_index));
11818 }
11819
11820 static int
11821 api_vxlan_tunnel_dump (vat_main_t * vam)
11822 {
11823   unformat_input_t *i = vam->input;
11824   vl_api_vxlan_tunnel_dump_t *mp;
11825   vl_api_control_ping_t *mp_ping;
11826   u32 sw_if_index;
11827   u8 sw_if_index_set = 0;
11828   int ret;
11829
11830   /* Parse args required to build the message */
11831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11832     {
11833       if (unformat (i, "sw_if_index %d", &sw_if_index))
11834         sw_if_index_set = 1;
11835       else
11836         break;
11837     }
11838
11839   if (sw_if_index_set == 0)
11840     {
11841       sw_if_index = ~0;
11842     }
11843
11844   if (!vam->json_output)
11845     {
11846       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11847              "sw_if_index", "instance", "src_address", "dst_address",
11848              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11849     }
11850
11851   /* Get list of vxlan-tunnel interfaces */
11852   M (VXLAN_TUNNEL_DUMP, mp);
11853
11854   mp->sw_if_index = htonl (sw_if_index);
11855
11856   S (mp);
11857
11858   /* Use a control ping for synchronization */
11859   MPING (CONTROL_PING, mp_ping);
11860   S (mp_ping);
11861
11862   W (ret);
11863   return ret;
11864 }
11865
11866 static uword unformat_geneve_decap_next
11867   (unformat_input_t * input, va_list * args)
11868 {
11869   u32 *result = va_arg (*args, u32 *);
11870   u32 tmp;
11871
11872   if (unformat (input, "l2"))
11873     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11874   else if (unformat (input, "%d", &tmp))
11875     *result = tmp;
11876   else
11877     return 0;
11878   return 1;
11879 }
11880
11881 static int
11882 api_geneve_add_del_tunnel (vat_main_t * vam)
11883 {
11884   unformat_input_t *line_input = vam->input;
11885   vl_api_geneve_add_del_tunnel_t *mp;
11886   ip46_address_t src, dst;
11887   u8 is_add = 1;
11888   u8 ipv4_set = 0, ipv6_set = 0;
11889   u8 src_set = 0;
11890   u8 dst_set = 0;
11891   u8 grp_set = 0;
11892   u32 mcast_sw_if_index = ~0;
11893   u32 encap_vrf_id = 0;
11894   u32 decap_next_index = ~0;
11895   u32 vni = 0;
11896   int ret;
11897
11898   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11899   clib_memset (&src, 0, sizeof src);
11900   clib_memset (&dst, 0, sizeof dst);
11901
11902   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11903     {
11904       if (unformat (line_input, "del"))
11905         is_add = 0;
11906       else
11907         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11908         {
11909           ipv4_set = 1;
11910           src_set = 1;
11911         }
11912       else
11913         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11914         {
11915           ipv4_set = 1;
11916           dst_set = 1;
11917         }
11918       else
11919         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11920         {
11921           ipv6_set = 1;
11922           src_set = 1;
11923         }
11924       else
11925         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11926         {
11927           ipv6_set = 1;
11928           dst_set = 1;
11929         }
11930       else if (unformat (line_input, "group %U %U",
11931                          unformat_ip4_address, &dst.ip4,
11932                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11933         {
11934           grp_set = dst_set = 1;
11935           ipv4_set = 1;
11936         }
11937       else if (unformat (line_input, "group %U",
11938                          unformat_ip4_address, &dst.ip4))
11939         {
11940           grp_set = dst_set = 1;
11941           ipv4_set = 1;
11942         }
11943       else if (unformat (line_input, "group %U %U",
11944                          unformat_ip6_address, &dst.ip6,
11945                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11946         {
11947           grp_set = dst_set = 1;
11948           ipv6_set = 1;
11949         }
11950       else if (unformat (line_input, "group %U",
11951                          unformat_ip6_address, &dst.ip6))
11952         {
11953           grp_set = dst_set = 1;
11954           ipv6_set = 1;
11955         }
11956       else
11957         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11958         ;
11959       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11960         ;
11961       else if (unformat (line_input, "decap-next %U",
11962                          unformat_geneve_decap_next, &decap_next_index))
11963         ;
11964       else if (unformat (line_input, "vni %d", &vni))
11965         ;
11966       else
11967         {
11968           errmsg ("parse error '%U'", format_unformat_error, line_input);
11969           return -99;
11970         }
11971     }
11972
11973   if (src_set == 0)
11974     {
11975       errmsg ("tunnel src address not specified");
11976       return -99;
11977     }
11978   if (dst_set == 0)
11979     {
11980       errmsg ("tunnel dst address not specified");
11981       return -99;
11982     }
11983
11984   if (grp_set && !ip46_address_is_multicast (&dst))
11985     {
11986       errmsg ("tunnel group address not multicast");
11987       return -99;
11988     }
11989   if (grp_set && mcast_sw_if_index == ~0)
11990     {
11991       errmsg ("tunnel nonexistent multicast device");
11992       return -99;
11993     }
11994   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11995     {
11996       errmsg ("tunnel dst address must be unicast");
11997       return -99;
11998     }
11999
12000
12001   if (ipv4_set && ipv6_set)
12002     {
12003       errmsg ("both IPv4 and IPv6 addresses specified");
12004       return -99;
12005     }
12006
12007   if ((vni == 0) || (vni >> 24))
12008     {
12009       errmsg ("vni not specified or out of range");
12010       return -99;
12011     }
12012
12013   M (GENEVE_ADD_DEL_TUNNEL, mp);
12014
12015   if (ipv6_set)
12016     {
12017       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12018       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12019     }
12020   else
12021     {
12022       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12023       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12024     }
12025   mp->encap_vrf_id = ntohl (encap_vrf_id);
12026   mp->decap_next_index = ntohl (decap_next_index);
12027   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12028   mp->vni = ntohl (vni);
12029   mp->is_add = is_add;
12030
12031   S (mp);
12032   W (ret);
12033   return ret;
12034 }
12035
12036 static void vl_api_geneve_tunnel_details_t_handler
12037   (vl_api_geneve_tunnel_details_t * mp)
12038 {
12039   vat_main_t *vam = &vat_main;
12040   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12041   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12042
12043   if (mp->src_address.af == ADDRESS_IP6)
12044     {
12045       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12046       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12047     }
12048   else
12049     {
12050       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12051       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12052     }
12053
12054   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12055          ntohl (mp->sw_if_index),
12056          format_ip46_address, &src, IP46_TYPE_ANY,
12057          format_ip46_address, &dst, IP46_TYPE_ANY,
12058          ntohl (mp->encap_vrf_id),
12059          ntohl (mp->decap_next_index), ntohl (mp->vni),
12060          ntohl (mp->mcast_sw_if_index));
12061 }
12062
12063 static void vl_api_geneve_tunnel_details_t_handler_json
12064   (vl_api_geneve_tunnel_details_t * mp)
12065 {
12066   vat_main_t *vam = &vat_main;
12067   vat_json_node_t *node = NULL;
12068   bool is_ipv6;
12069
12070   if (VAT_JSON_ARRAY != vam->json_tree.type)
12071     {
12072       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12073       vat_json_init_array (&vam->json_tree);
12074     }
12075   node = vat_json_array_add (&vam->json_tree);
12076
12077   vat_json_init_object (node);
12078   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12079   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12080   if (is_ipv6)
12081     {
12082       struct in6_addr ip6;
12083
12084       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12085       vat_json_object_add_ip6 (node, "src_address", ip6);
12086       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12087       vat_json_object_add_ip6 (node, "dst_address", ip6);
12088     }
12089   else
12090     {
12091       struct in_addr ip4;
12092
12093       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12094       vat_json_object_add_ip4 (node, "src_address", ip4);
12095       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12096       vat_json_object_add_ip4 (node, "dst_address", ip4);
12097     }
12098   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12099   vat_json_object_add_uint (node, "decap_next_index",
12100                             ntohl (mp->decap_next_index));
12101   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12102   vat_json_object_add_uint (node, "mcast_sw_if_index",
12103                             ntohl (mp->mcast_sw_if_index));
12104 }
12105
12106 static int
12107 api_geneve_tunnel_dump (vat_main_t * vam)
12108 {
12109   unformat_input_t *i = vam->input;
12110   vl_api_geneve_tunnel_dump_t *mp;
12111   vl_api_control_ping_t *mp_ping;
12112   u32 sw_if_index;
12113   u8 sw_if_index_set = 0;
12114   int ret;
12115
12116   /* Parse args required to build the message */
12117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12118     {
12119       if (unformat (i, "sw_if_index %d", &sw_if_index))
12120         sw_if_index_set = 1;
12121       else
12122         break;
12123     }
12124
12125   if (sw_if_index_set == 0)
12126     {
12127       sw_if_index = ~0;
12128     }
12129
12130   if (!vam->json_output)
12131     {
12132       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12133              "sw_if_index", "local_address", "remote_address",
12134              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12135     }
12136
12137   /* Get list of geneve-tunnel interfaces */
12138   M (GENEVE_TUNNEL_DUMP, mp);
12139
12140   mp->sw_if_index = htonl (sw_if_index);
12141
12142   S (mp);
12143
12144   /* Use a control ping for synchronization */
12145   M (CONTROL_PING, mp_ping);
12146   S (mp_ping);
12147
12148   W (ret);
12149   return ret;
12150 }
12151
12152 static int
12153 api_gre_tunnel_add_del (vat_main_t * vam)
12154 {
12155   unformat_input_t *line_input = vam->input;
12156   vl_api_address_t src = { }, dst =
12157   {
12158   };
12159   vl_api_gre_tunnel_add_del_t *mp;
12160   vl_api_gre_tunnel_type_t t_type;
12161   u8 is_add = 1;
12162   u8 src_set = 0;
12163   u8 dst_set = 0;
12164   u32 outer_table_id = 0;
12165   u32 session_id = 0;
12166   u32 instance = ~0;
12167   int ret;
12168
12169   t_type = GRE_API_TUNNEL_TYPE_L3;
12170
12171   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (line_input, "del"))
12174         is_add = 0;
12175       else if (unformat (line_input, "instance %d", &instance))
12176         ;
12177       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12178         {
12179           src_set = 1;
12180         }
12181       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12182         {
12183           dst_set = 1;
12184         }
12185       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12186         ;
12187       else if (unformat (line_input, "teb"))
12188         t_type = GRE_API_TUNNEL_TYPE_TEB;
12189       else if (unformat (line_input, "erspan %d", &session_id))
12190         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12191       else
12192         {
12193           errmsg ("parse error '%U'", format_unformat_error, line_input);
12194           return -99;
12195         }
12196     }
12197
12198   if (src_set == 0)
12199     {
12200       errmsg ("tunnel src address not specified");
12201       return -99;
12202     }
12203   if (dst_set == 0)
12204     {
12205       errmsg ("tunnel dst address not specified");
12206       return -99;
12207     }
12208
12209   M (GRE_TUNNEL_ADD_DEL, mp);
12210
12211   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12212   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12213
12214   mp->tunnel.instance = htonl (instance);
12215   mp->tunnel.outer_table_id = htonl (outer_table_id);
12216   mp->is_add = is_add;
12217   mp->tunnel.session_id = htons ((u16) session_id);
12218   mp->tunnel.type = htonl (t_type);
12219
12220   S (mp);
12221   W (ret);
12222   return ret;
12223 }
12224
12225 static void vl_api_gre_tunnel_details_t_handler
12226   (vl_api_gre_tunnel_details_t * mp)
12227 {
12228   vat_main_t *vam = &vat_main;
12229
12230   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12231          ntohl (mp->tunnel.sw_if_index),
12232          ntohl (mp->tunnel.instance),
12233          format_vl_api_address, &mp->tunnel.src,
12234          format_vl_api_address, &mp->tunnel.dst,
12235          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12236          ntohl (mp->tunnel.session_id));
12237 }
12238
12239 static void vl_api_gre_tunnel_details_t_handler_json
12240   (vl_api_gre_tunnel_details_t * mp)
12241 {
12242   vat_main_t *vam = &vat_main;
12243   vat_json_node_t *node = NULL;
12244
12245   if (VAT_JSON_ARRAY != vam->json_tree.type)
12246     {
12247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12248       vat_json_init_array (&vam->json_tree);
12249     }
12250   node = vat_json_array_add (&vam->json_tree);
12251
12252   vat_json_init_object (node);
12253   vat_json_object_add_uint (node, "sw_if_index",
12254                             ntohl (mp->tunnel.sw_if_index));
12255   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12256
12257   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12258   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12259   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12260   vat_json_object_add_uint (node, "outer_table_id",
12261                             ntohl (mp->tunnel.outer_table_id));
12262   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12263 }
12264
12265 static int
12266 api_gre_tunnel_dump (vat_main_t * vam)
12267 {
12268   unformat_input_t *i = vam->input;
12269   vl_api_gre_tunnel_dump_t *mp;
12270   vl_api_control_ping_t *mp_ping;
12271   u32 sw_if_index;
12272   u8 sw_if_index_set = 0;
12273   int ret;
12274
12275   /* Parse args required to build the message */
12276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12277     {
12278       if (unformat (i, "sw_if_index %d", &sw_if_index))
12279         sw_if_index_set = 1;
12280       else
12281         break;
12282     }
12283
12284   if (sw_if_index_set == 0)
12285     {
12286       sw_if_index = ~0;
12287     }
12288
12289   if (!vam->json_output)
12290     {
12291       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12292              "sw_if_index", "instance", "src_address", "dst_address",
12293              "tunnel_type", "outer_fib_id", "session_id");
12294     }
12295
12296   /* Get list of gre-tunnel interfaces */
12297   M (GRE_TUNNEL_DUMP, mp);
12298
12299   mp->sw_if_index = htonl (sw_if_index);
12300
12301   S (mp);
12302
12303   /* Use a control ping for synchronization */
12304   MPING (CONTROL_PING, mp_ping);
12305   S (mp_ping);
12306
12307   W (ret);
12308   return ret;
12309 }
12310
12311 static int
12312 api_l2_fib_clear_table (vat_main_t * vam)
12313 {
12314 //  unformat_input_t * i = vam->input;
12315   vl_api_l2_fib_clear_table_t *mp;
12316   int ret;
12317
12318   M (L2_FIB_CLEAR_TABLE, mp);
12319
12320   S (mp);
12321   W (ret);
12322   return ret;
12323 }
12324
12325 static int
12326 api_l2_interface_efp_filter (vat_main_t * vam)
12327 {
12328   unformat_input_t *i = vam->input;
12329   vl_api_l2_interface_efp_filter_t *mp;
12330   u32 sw_if_index;
12331   u8 enable = 1;
12332   u8 sw_if_index_set = 0;
12333   int ret;
12334
12335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12336     {
12337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12338         sw_if_index_set = 1;
12339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12340         sw_if_index_set = 1;
12341       else if (unformat (i, "enable"))
12342         enable = 1;
12343       else if (unformat (i, "disable"))
12344         enable = 0;
12345       else
12346         {
12347           clib_warning ("parse error '%U'", format_unformat_error, i);
12348           return -99;
12349         }
12350     }
12351
12352   if (sw_if_index_set == 0)
12353     {
12354       errmsg ("missing sw_if_index");
12355       return -99;
12356     }
12357
12358   M (L2_INTERFACE_EFP_FILTER, mp);
12359
12360   mp->sw_if_index = ntohl (sw_if_index);
12361   mp->enable_disable = enable;
12362
12363   S (mp);
12364   W (ret);
12365   return ret;
12366 }
12367
12368 #define foreach_vtr_op                          \
12369 _("disable",  L2_VTR_DISABLED)                  \
12370 _("push-1",  L2_VTR_PUSH_1)                     \
12371 _("push-2",  L2_VTR_PUSH_2)                     \
12372 _("pop-1",  L2_VTR_POP_1)                       \
12373 _("pop-2",  L2_VTR_POP_2)                       \
12374 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12375 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12376 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12377 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12378
12379 static int
12380 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12381 {
12382   unformat_input_t *i = vam->input;
12383   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12384   u32 sw_if_index;
12385   u8 sw_if_index_set = 0;
12386   u8 vtr_op_set = 0;
12387   u32 vtr_op = 0;
12388   u32 push_dot1q = 1;
12389   u32 tag1 = ~0;
12390   u32 tag2 = ~0;
12391   int ret;
12392
12393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12394     {
12395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12396         sw_if_index_set = 1;
12397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12398         sw_if_index_set = 1;
12399       else if (unformat (i, "vtr_op %d", &vtr_op))
12400         vtr_op_set = 1;
12401 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12402       foreach_vtr_op
12403 #undef _
12404         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12405         ;
12406       else if (unformat (i, "tag1 %d", &tag1))
12407         ;
12408       else if (unformat (i, "tag2 %d", &tag2))
12409         ;
12410       else
12411         {
12412           clib_warning ("parse error '%U'", format_unformat_error, i);
12413           return -99;
12414         }
12415     }
12416
12417   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12418     {
12419       errmsg ("missing vtr operation or sw_if_index");
12420       return -99;
12421     }
12422
12423   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12424   mp->sw_if_index = ntohl (sw_if_index);
12425   mp->vtr_op = ntohl (vtr_op);
12426   mp->push_dot1q = ntohl (push_dot1q);
12427   mp->tag1 = ntohl (tag1);
12428   mp->tag2 = ntohl (tag2);
12429
12430   S (mp);
12431   W (ret);
12432   return ret;
12433 }
12434
12435 static int
12436 api_create_vhost_user_if (vat_main_t * vam)
12437 {
12438   unformat_input_t *i = vam->input;
12439   vl_api_create_vhost_user_if_t *mp;
12440   u8 *file_name;
12441   u8 is_server = 0;
12442   u8 file_name_set = 0;
12443   u32 custom_dev_instance = ~0;
12444   u8 hwaddr[6];
12445   u8 use_custom_mac = 0;
12446   u8 disable_mrg_rxbuf = 0;
12447   u8 disable_indirect_desc = 0;
12448   u8 *tag = 0;
12449   u8 enable_gso = 0;
12450   u8 enable_packed = 0;
12451   int ret;
12452
12453   /* Shut up coverity */
12454   clib_memset (hwaddr, 0, sizeof (hwaddr));
12455
12456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12457     {
12458       if (unformat (i, "socket %s", &file_name))
12459         {
12460           file_name_set = 1;
12461         }
12462       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12463         ;
12464       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12465         use_custom_mac = 1;
12466       else if (unformat (i, "server"))
12467         is_server = 1;
12468       else if (unformat (i, "disable_mrg_rxbuf"))
12469         disable_mrg_rxbuf = 1;
12470       else if (unformat (i, "disable_indirect_desc"))
12471         disable_indirect_desc = 1;
12472       else if (unformat (i, "gso"))
12473         enable_gso = 1;
12474       else if (unformat (i, "packed"))
12475         enable_packed = 1;
12476       else if (unformat (i, "tag %s", &tag))
12477         ;
12478       else
12479         break;
12480     }
12481
12482   if (file_name_set == 0)
12483     {
12484       errmsg ("missing socket file name");
12485       return -99;
12486     }
12487
12488   if (vec_len (file_name) > 255)
12489     {
12490       errmsg ("socket file name too long");
12491       return -99;
12492     }
12493   vec_add1 (file_name, 0);
12494
12495   M (CREATE_VHOST_USER_IF, mp);
12496
12497   mp->is_server = is_server;
12498   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12499   mp->disable_indirect_desc = disable_indirect_desc;
12500   mp->enable_gso = enable_gso;
12501   mp->enable_packed = enable_packed;
12502   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12503   vec_free (file_name);
12504   if (custom_dev_instance != ~0)
12505     {
12506       mp->renumber = 1;
12507       mp->custom_dev_instance = ntohl (custom_dev_instance);
12508     }
12509
12510   mp->use_custom_mac = use_custom_mac;
12511   clib_memcpy (mp->mac_address, hwaddr, 6);
12512   if (tag)
12513     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12514   vec_free (tag);
12515
12516   S (mp);
12517   W (ret);
12518   return ret;
12519 }
12520
12521 static int
12522 api_modify_vhost_user_if (vat_main_t * vam)
12523 {
12524   unformat_input_t *i = vam->input;
12525   vl_api_modify_vhost_user_if_t *mp;
12526   u8 *file_name;
12527   u8 is_server = 0;
12528   u8 file_name_set = 0;
12529   u32 custom_dev_instance = ~0;
12530   u8 sw_if_index_set = 0;
12531   u32 sw_if_index = (u32) ~ 0;
12532   u8 enable_gso = 0;
12533   u8 enable_packed = 0;
12534   int ret;
12535
12536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12537     {
12538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12539         sw_if_index_set = 1;
12540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12541         sw_if_index_set = 1;
12542       else if (unformat (i, "socket %s", &file_name))
12543         {
12544           file_name_set = 1;
12545         }
12546       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12547         ;
12548       else if (unformat (i, "server"))
12549         is_server = 1;
12550       else if (unformat (i, "gso"))
12551         enable_gso = 1;
12552       else if (unformat (i, "packed"))
12553         enable_packed = 1;
12554       else
12555         break;
12556     }
12557
12558   if (sw_if_index_set == 0)
12559     {
12560       errmsg ("missing sw_if_index or interface name");
12561       return -99;
12562     }
12563
12564   if (file_name_set == 0)
12565     {
12566       errmsg ("missing socket file name");
12567       return -99;
12568     }
12569
12570   if (vec_len (file_name) > 255)
12571     {
12572       errmsg ("socket file name too long");
12573       return -99;
12574     }
12575   vec_add1 (file_name, 0);
12576
12577   M (MODIFY_VHOST_USER_IF, mp);
12578
12579   mp->sw_if_index = ntohl (sw_if_index);
12580   mp->is_server = is_server;
12581   mp->enable_gso = enable_gso;
12582   mp->enable_packed = enable_packed;
12583   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12584   vec_free (file_name);
12585   if (custom_dev_instance != ~0)
12586     {
12587       mp->renumber = 1;
12588       mp->custom_dev_instance = ntohl (custom_dev_instance);
12589     }
12590
12591   S (mp);
12592   W (ret);
12593   return ret;
12594 }
12595
12596 static int
12597 api_delete_vhost_user_if (vat_main_t * vam)
12598 {
12599   unformat_input_t *i = vam->input;
12600   vl_api_delete_vhost_user_if_t *mp;
12601   u32 sw_if_index = ~0;
12602   u8 sw_if_index_set = 0;
12603   int ret;
12604
12605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12606     {
12607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12608         sw_if_index_set = 1;
12609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12610         sw_if_index_set = 1;
12611       else
12612         break;
12613     }
12614
12615   if (sw_if_index_set == 0)
12616     {
12617       errmsg ("missing sw_if_index or interface name");
12618       return -99;
12619     }
12620
12621
12622   M (DELETE_VHOST_USER_IF, mp);
12623
12624   mp->sw_if_index = ntohl (sw_if_index);
12625
12626   S (mp);
12627   W (ret);
12628   return ret;
12629 }
12630
12631 static void vl_api_sw_interface_vhost_user_details_t_handler
12632   (vl_api_sw_interface_vhost_user_details_t * mp)
12633 {
12634   vat_main_t *vam = &vat_main;
12635   u64 features;
12636
12637   features =
12638     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12639                                                     clib_net_to_host_u32
12640                                                     (mp->features_last_32) <<
12641                                                     32);
12642
12643   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12644          (char *) mp->interface_name,
12645          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12646          features, mp->is_server,
12647          ntohl (mp->num_regions), (char *) mp->sock_filename);
12648   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12649 }
12650
12651 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12652   (vl_api_sw_interface_vhost_user_details_t * mp)
12653 {
12654   vat_main_t *vam = &vat_main;
12655   vat_json_node_t *node = NULL;
12656
12657   if (VAT_JSON_ARRAY != vam->json_tree.type)
12658     {
12659       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12660       vat_json_init_array (&vam->json_tree);
12661     }
12662   node = vat_json_array_add (&vam->json_tree);
12663
12664   vat_json_init_object (node);
12665   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12666   vat_json_object_add_string_copy (node, "interface_name",
12667                                    mp->interface_name);
12668   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12669                             ntohl (mp->virtio_net_hdr_sz));
12670   vat_json_object_add_uint (node, "features_first_32",
12671                             clib_net_to_host_u32 (mp->features_first_32));
12672   vat_json_object_add_uint (node, "features_last_32",
12673                             clib_net_to_host_u32 (mp->features_last_32));
12674   vat_json_object_add_uint (node, "is_server", mp->is_server);
12675   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12676   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12677   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12678 }
12679
12680 static int
12681 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12682 {
12683   vl_api_sw_interface_vhost_user_dump_t *mp;
12684   vl_api_control_ping_t *mp_ping;
12685   int ret;
12686   print (vam->ofp,
12687          "Interface name            idx hdr_sz features server regions filename");
12688
12689   /* Get list of vhost-user interfaces */
12690   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12691   mp->sw_if_index = ntohl (~0);
12692   S (mp);
12693
12694   /* Use a control ping for synchronization */
12695   MPING (CONTROL_PING, mp_ping);
12696   S (mp_ping);
12697
12698   W (ret);
12699   return ret;
12700 }
12701
12702 static int
12703 api_show_version (vat_main_t * vam)
12704 {
12705   vl_api_show_version_t *mp;
12706   int ret;
12707
12708   M (SHOW_VERSION, mp);
12709
12710   S (mp);
12711   W (ret);
12712   return ret;
12713 }
12714
12715
12716 static int
12717 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12718 {
12719   unformat_input_t *line_input = vam->input;
12720   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12721   ip46_address_t local, remote;
12722   u8 is_add = 1;
12723   u8 local_set = 0;
12724   u8 remote_set = 0;
12725   u8 grp_set = 0;
12726   u32 mcast_sw_if_index = ~0;
12727   u32 encap_vrf_id = 0;
12728   u32 decap_vrf_id = 0;
12729   u8 protocol = ~0;
12730   u32 vni;
12731   u8 vni_set = 0;
12732   int ret;
12733
12734   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12735     {
12736       if (unformat (line_input, "del"))
12737         is_add = 0;
12738       else if (unformat (line_input, "local %U",
12739                          unformat_ip46_address, &local))
12740         {
12741           local_set = 1;
12742         }
12743       else if (unformat (line_input, "remote %U",
12744                          unformat_ip46_address, &remote))
12745         {
12746           remote_set = 1;
12747         }
12748       else if (unformat (line_input, "group %U %U",
12749                          unformat_ip46_address, &remote,
12750                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12751         {
12752           grp_set = remote_set = 1;
12753         }
12754       else if (unformat (line_input, "group %U",
12755                          unformat_ip46_address, &remote))
12756         {
12757           grp_set = remote_set = 1;
12758         }
12759       else
12760         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12761         ;
12762       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12763         ;
12764       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12765         ;
12766       else if (unformat (line_input, "vni %d", &vni))
12767         vni_set = 1;
12768       else if (unformat (line_input, "next-ip4"))
12769         protocol = 1;
12770       else if (unformat (line_input, "next-ip6"))
12771         protocol = 2;
12772       else if (unformat (line_input, "next-ethernet"))
12773         protocol = 3;
12774       else if (unformat (line_input, "next-nsh"))
12775         protocol = 4;
12776       else
12777         {
12778           errmsg ("parse error '%U'", format_unformat_error, line_input);
12779           return -99;
12780         }
12781     }
12782
12783   if (local_set == 0)
12784     {
12785       errmsg ("tunnel local address not specified");
12786       return -99;
12787     }
12788   if (remote_set == 0)
12789     {
12790       errmsg ("tunnel remote address not specified");
12791       return -99;
12792     }
12793   if (grp_set && mcast_sw_if_index == ~0)
12794     {
12795       errmsg ("tunnel nonexistent multicast device");
12796       return -99;
12797     }
12798   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12799     {
12800       errmsg ("both IPv4 and IPv6 addresses specified");
12801       return -99;
12802     }
12803
12804   if (vni_set == 0)
12805     {
12806       errmsg ("vni not specified");
12807       return -99;
12808     }
12809
12810   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12811
12812   ip_address_encode (&local,
12813                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12814                      IP46_TYPE_IP6, &mp->local);
12815   ip_address_encode (&remote,
12816                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12817                      IP46_TYPE_IP6, &mp->remote);
12818
12819   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12820   mp->encap_vrf_id = ntohl (encap_vrf_id);
12821   mp->decap_vrf_id = ntohl (decap_vrf_id);
12822   mp->protocol = protocol;
12823   mp->vni = ntohl (vni);
12824   mp->is_add = is_add;
12825
12826   S (mp);
12827   W (ret);
12828   return ret;
12829 }
12830
12831 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12832   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12833 {
12834   vat_main_t *vam = &vat_main;
12835   ip46_address_t local, remote;
12836
12837   ip_address_decode (&mp->local, &local);
12838   ip_address_decode (&mp->remote, &remote);
12839
12840   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12841          ntohl (mp->sw_if_index),
12842          format_ip46_address, &local, IP46_TYPE_ANY,
12843          format_ip46_address, &remote, IP46_TYPE_ANY,
12844          ntohl (mp->vni), mp->protocol,
12845          ntohl (mp->mcast_sw_if_index),
12846          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12847 }
12848
12849
12850 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12851   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12852 {
12853   vat_main_t *vam = &vat_main;
12854   vat_json_node_t *node = NULL;
12855   struct in_addr ip4;
12856   struct in6_addr ip6;
12857   ip46_address_t local, remote;
12858
12859   ip_address_decode (&mp->local, &local);
12860   ip_address_decode (&mp->remote, &remote);
12861
12862   if (VAT_JSON_ARRAY != vam->json_tree.type)
12863     {
12864       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12865       vat_json_init_array (&vam->json_tree);
12866     }
12867   node = vat_json_array_add (&vam->json_tree);
12868
12869   vat_json_init_object (node);
12870   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12871   if (ip46_address_is_ip4 (&local))
12872     {
12873       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12874       vat_json_object_add_ip4 (node, "local", ip4);
12875       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12876       vat_json_object_add_ip4 (node, "remote", ip4);
12877     }
12878   else
12879     {
12880       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12881       vat_json_object_add_ip6 (node, "local", ip6);
12882       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12883       vat_json_object_add_ip6 (node, "remote", ip6);
12884     }
12885   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12886   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12887   vat_json_object_add_uint (node, "mcast_sw_if_index",
12888                             ntohl (mp->mcast_sw_if_index));
12889   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12890   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12891   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12892 }
12893
12894 static int
12895 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12896 {
12897   unformat_input_t *i = vam->input;
12898   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12899   vl_api_control_ping_t *mp_ping;
12900   u32 sw_if_index;
12901   u8 sw_if_index_set = 0;
12902   int ret;
12903
12904   /* Parse args required to build the message */
12905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12906     {
12907       if (unformat (i, "sw_if_index %d", &sw_if_index))
12908         sw_if_index_set = 1;
12909       else
12910         break;
12911     }
12912
12913   if (sw_if_index_set == 0)
12914     {
12915       sw_if_index = ~0;
12916     }
12917
12918   if (!vam->json_output)
12919     {
12920       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12921              "sw_if_index", "local", "remote", "vni",
12922              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12923     }
12924
12925   /* Get list of vxlan-tunnel interfaces */
12926   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12927
12928   mp->sw_if_index = htonl (sw_if_index);
12929
12930   S (mp);
12931
12932   /* Use a control ping for synchronization */
12933   MPING (CONTROL_PING, mp_ping);
12934   S (mp_ping);
12935
12936   W (ret);
12937   return ret;
12938 }
12939
12940 static void vl_api_l2_fib_table_details_t_handler
12941   (vl_api_l2_fib_table_details_t * mp)
12942 {
12943   vat_main_t *vam = &vat_main;
12944
12945   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12946          "       %d       %d     %d",
12947          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12948          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12949          mp->bvi_mac);
12950 }
12951
12952 static void vl_api_l2_fib_table_details_t_handler_json
12953   (vl_api_l2_fib_table_details_t * mp)
12954 {
12955   vat_main_t *vam = &vat_main;
12956   vat_json_node_t *node = NULL;
12957
12958   if (VAT_JSON_ARRAY != vam->json_tree.type)
12959     {
12960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12961       vat_json_init_array (&vam->json_tree);
12962     }
12963   node = vat_json_array_add (&vam->json_tree);
12964
12965   vat_json_init_object (node);
12966   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12967   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12968   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12969   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12970   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12971   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12972 }
12973
12974 static int
12975 api_l2_fib_table_dump (vat_main_t * vam)
12976 {
12977   unformat_input_t *i = vam->input;
12978   vl_api_l2_fib_table_dump_t *mp;
12979   vl_api_control_ping_t *mp_ping;
12980   u32 bd_id;
12981   u8 bd_id_set = 0;
12982   int ret;
12983
12984   /* Parse args required to build the message */
12985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12986     {
12987       if (unformat (i, "bd_id %d", &bd_id))
12988         bd_id_set = 1;
12989       else
12990         break;
12991     }
12992
12993   if (bd_id_set == 0)
12994     {
12995       errmsg ("missing bridge domain");
12996       return -99;
12997     }
12998
12999   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13000
13001   /* Get list of l2 fib entries */
13002   M (L2_FIB_TABLE_DUMP, mp);
13003
13004   mp->bd_id = ntohl (bd_id);
13005   S (mp);
13006
13007   /* Use a control ping for synchronization */
13008   MPING (CONTROL_PING, mp_ping);
13009   S (mp_ping);
13010
13011   W (ret);
13012   return ret;
13013 }
13014
13015
13016 static int
13017 api_interface_name_renumber (vat_main_t * vam)
13018 {
13019   unformat_input_t *line_input = vam->input;
13020   vl_api_interface_name_renumber_t *mp;
13021   u32 sw_if_index = ~0;
13022   u32 new_show_dev_instance = ~0;
13023   int ret;
13024
13025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13028                     &sw_if_index))
13029         ;
13030       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13031         ;
13032       else if (unformat (line_input, "new_show_dev_instance %d",
13033                          &new_show_dev_instance))
13034         ;
13035       else
13036         break;
13037     }
13038
13039   if (sw_if_index == ~0)
13040     {
13041       errmsg ("missing interface name or sw_if_index");
13042       return -99;
13043     }
13044
13045   if (new_show_dev_instance == ~0)
13046     {
13047       errmsg ("missing new_show_dev_instance");
13048       return -99;
13049     }
13050
13051   M (INTERFACE_NAME_RENUMBER, mp);
13052
13053   mp->sw_if_index = ntohl (sw_if_index);
13054   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13055
13056   S (mp);
13057   W (ret);
13058   return ret;
13059 }
13060
13061 static int
13062 api_want_l2_macs_events (vat_main_t * vam)
13063 {
13064   unformat_input_t *line_input = vam->input;
13065   vl_api_want_l2_macs_events_t *mp;
13066   u8 enable_disable = 1;
13067   u32 scan_delay = 0;
13068   u32 max_macs_in_event = 0;
13069   u32 learn_limit = 0;
13070   int ret;
13071
13072   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13073     {
13074       if (unformat (line_input, "learn-limit %d", &learn_limit))
13075         ;
13076       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13077         ;
13078       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13079         ;
13080       else if (unformat (line_input, "disable"))
13081         enable_disable = 0;
13082       else
13083         break;
13084     }
13085
13086   M (WANT_L2_MACS_EVENTS, mp);
13087   mp->enable_disable = enable_disable;
13088   mp->pid = htonl (getpid ());
13089   mp->learn_limit = htonl (learn_limit);
13090   mp->scan_delay = (u8) scan_delay;
13091   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13092   S (mp);
13093   W (ret);
13094   return ret;
13095 }
13096
13097 static int
13098 api_input_acl_set_interface (vat_main_t * vam)
13099 {
13100   unformat_input_t *i = vam->input;
13101   vl_api_input_acl_set_interface_t *mp;
13102   u32 sw_if_index;
13103   int sw_if_index_set;
13104   u32 ip4_table_index = ~0;
13105   u32 ip6_table_index = ~0;
13106   u32 l2_table_index = ~0;
13107   u8 is_add = 1;
13108   int ret;
13109
13110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13111     {
13112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13113         sw_if_index_set = 1;
13114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13115         sw_if_index_set = 1;
13116       else if (unformat (i, "del"))
13117         is_add = 0;
13118       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13119         ;
13120       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13121         ;
13122       else if (unformat (i, "l2-table %d", &l2_table_index))
13123         ;
13124       else
13125         {
13126           clib_warning ("parse error '%U'", format_unformat_error, i);
13127           return -99;
13128         }
13129     }
13130
13131   if (sw_if_index_set == 0)
13132     {
13133       errmsg ("missing interface name or sw_if_index");
13134       return -99;
13135     }
13136
13137   M (INPUT_ACL_SET_INTERFACE, mp);
13138
13139   mp->sw_if_index = ntohl (sw_if_index);
13140   mp->ip4_table_index = ntohl (ip4_table_index);
13141   mp->ip6_table_index = ntohl (ip6_table_index);
13142   mp->l2_table_index = ntohl (l2_table_index);
13143   mp->is_add = is_add;
13144
13145   S (mp);
13146   W (ret);
13147   return ret;
13148 }
13149
13150 static int
13151 api_output_acl_set_interface (vat_main_t * vam)
13152 {
13153   unformat_input_t *i = vam->input;
13154   vl_api_output_acl_set_interface_t *mp;
13155   u32 sw_if_index;
13156   int sw_if_index_set;
13157   u32 ip4_table_index = ~0;
13158   u32 ip6_table_index = ~0;
13159   u32 l2_table_index = ~0;
13160   u8 is_add = 1;
13161   int ret;
13162
13163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13164     {
13165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13166         sw_if_index_set = 1;
13167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13168         sw_if_index_set = 1;
13169       else if (unformat (i, "del"))
13170         is_add = 0;
13171       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13172         ;
13173       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13174         ;
13175       else if (unformat (i, "l2-table %d", &l2_table_index))
13176         ;
13177       else
13178         {
13179           clib_warning ("parse error '%U'", format_unformat_error, i);
13180           return -99;
13181         }
13182     }
13183
13184   if (sw_if_index_set == 0)
13185     {
13186       errmsg ("missing interface name or sw_if_index");
13187       return -99;
13188     }
13189
13190   M (OUTPUT_ACL_SET_INTERFACE, mp);
13191
13192   mp->sw_if_index = ntohl (sw_if_index);
13193   mp->ip4_table_index = ntohl (ip4_table_index);
13194   mp->ip6_table_index = ntohl (ip6_table_index);
13195   mp->l2_table_index = ntohl (l2_table_index);
13196   mp->is_add = is_add;
13197
13198   S (mp);
13199   W (ret);
13200   return ret;
13201 }
13202
13203 static int
13204 api_ip_address_dump (vat_main_t * vam)
13205 {
13206   unformat_input_t *i = vam->input;
13207   vl_api_ip_address_dump_t *mp;
13208   vl_api_control_ping_t *mp_ping;
13209   u32 sw_if_index = ~0;
13210   u8 sw_if_index_set = 0;
13211   u8 ipv4_set = 0;
13212   u8 ipv6_set = 0;
13213   int ret;
13214
13215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13216     {
13217       if (unformat (i, "sw_if_index %d", &sw_if_index))
13218         sw_if_index_set = 1;
13219       else
13220         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13221         sw_if_index_set = 1;
13222       else if (unformat (i, "ipv4"))
13223         ipv4_set = 1;
13224       else if (unformat (i, "ipv6"))
13225         ipv6_set = 1;
13226       else
13227         break;
13228     }
13229
13230   if (ipv4_set && ipv6_set)
13231     {
13232       errmsg ("ipv4 and ipv6 flags cannot be both set");
13233       return -99;
13234     }
13235
13236   if ((!ipv4_set) && (!ipv6_set))
13237     {
13238       errmsg ("no ipv4 nor ipv6 flag set");
13239       return -99;
13240     }
13241
13242   if (sw_if_index_set == 0)
13243     {
13244       errmsg ("missing interface name or sw_if_index");
13245       return -99;
13246     }
13247
13248   vam->current_sw_if_index = sw_if_index;
13249   vam->is_ipv6 = ipv6_set;
13250
13251   M (IP_ADDRESS_DUMP, mp);
13252   mp->sw_if_index = ntohl (sw_if_index);
13253   mp->is_ipv6 = ipv6_set;
13254   S (mp);
13255
13256   /* Use a control ping for synchronization */
13257   MPING (CONTROL_PING, mp_ping);
13258   S (mp_ping);
13259
13260   W (ret);
13261   return ret;
13262 }
13263
13264 static int
13265 api_ip_dump (vat_main_t * vam)
13266 {
13267   vl_api_ip_dump_t *mp;
13268   vl_api_control_ping_t *mp_ping;
13269   unformat_input_t *in = vam->input;
13270   int ipv4_set = 0;
13271   int ipv6_set = 0;
13272   int is_ipv6;
13273   int i;
13274   int ret;
13275
13276   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13277     {
13278       if (unformat (in, "ipv4"))
13279         ipv4_set = 1;
13280       else if (unformat (in, "ipv6"))
13281         ipv6_set = 1;
13282       else
13283         break;
13284     }
13285
13286   if (ipv4_set && ipv6_set)
13287     {
13288       errmsg ("ipv4 and ipv6 flags cannot be both set");
13289       return -99;
13290     }
13291
13292   if ((!ipv4_set) && (!ipv6_set))
13293     {
13294       errmsg ("no ipv4 nor ipv6 flag set");
13295       return -99;
13296     }
13297
13298   is_ipv6 = ipv6_set;
13299   vam->is_ipv6 = is_ipv6;
13300
13301   /* free old data */
13302   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13303     {
13304       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13305     }
13306   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13307
13308   M (IP_DUMP, mp);
13309   mp->is_ipv6 = ipv6_set;
13310   S (mp);
13311
13312   /* Use a control ping for synchronization */
13313   MPING (CONTROL_PING, mp_ping);
13314   S (mp_ping);
13315
13316   W (ret);
13317   return ret;
13318 }
13319
13320 static int
13321 api_ipsec_spd_add_del (vat_main_t * vam)
13322 {
13323   unformat_input_t *i = vam->input;
13324   vl_api_ipsec_spd_add_del_t *mp;
13325   u32 spd_id = ~0;
13326   u8 is_add = 1;
13327   int ret;
13328
13329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13330     {
13331       if (unformat (i, "spd_id %d", &spd_id))
13332         ;
13333       else if (unformat (i, "del"))
13334         is_add = 0;
13335       else
13336         {
13337           clib_warning ("parse error '%U'", format_unformat_error, i);
13338           return -99;
13339         }
13340     }
13341   if (spd_id == ~0)
13342     {
13343       errmsg ("spd_id must be set");
13344       return -99;
13345     }
13346
13347   M (IPSEC_SPD_ADD_DEL, mp);
13348
13349   mp->spd_id = ntohl (spd_id);
13350   mp->is_add = is_add;
13351
13352   S (mp);
13353   W (ret);
13354   return ret;
13355 }
13356
13357 static int
13358 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13359 {
13360   unformat_input_t *i = vam->input;
13361   vl_api_ipsec_interface_add_del_spd_t *mp;
13362   u32 sw_if_index;
13363   u8 sw_if_index_set = 0;
13364   u32 spd_id = (u32) ~ 0;
13365   u8 is_add = 1;
13366   int ret;
13367
13368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13369     {
13370       if (unformat (i, "del"))
13371         is_add = 0;
13372       else if (unformat (i, "spd_id %d", &spd_id))
13373         ;
13374       else
13375         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13376         sw_if_index_set = 1;
13377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13378         sw_if_index_set = 1;
13379       else
13380         {
13381           clib_warning ("parse error '%U'", format_unformat_error, i);
13382           return -99;
13383         }
13384
13385     }
13386
13387   if (spd_id == (u32) ~ 0)
13388     {
13389       errmsg ("spd_id must be set");
13390       return -99;
13391     }
13392
13393   if (sw_if_index_set == 0)
13394     {
13395       errmsg ("missing interface name or sw_if_index");
13396       return -99;
13397     }
13398
13399   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13400
13401   mp->spd_id = ntohl (spd_id);
13402   mp->sw_if_index = ntohl (sw_if_index);
13403   mp->is_add = is_add;
13404
13405   S (mp);
13406   W (ret);
13407   return ret;
13408 }
13409
13410 static int
13411 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13412 {
13413   unformat_input_t *i = vam->input;
13414   vl_api_ipsec_spd_entry_add_del_t *mp;
13415   u8 is_add = 1, is_outbound = 0;
13416   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13417   i32 priority = 0;
13418   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13419   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13420   vl_api_address_t laddr_start = { }, laddr_stop =
13421   {
13422   }, raddr_start =
13423   {
13424   }, raddr_stop =
13425   {
13426   };
13427   int ret;
13428
13429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13430     {
13431       if (unformat (i, "del"))
13432         is_add = 0;
13433       if (unformat (i, "outbound"))
13434         is_outbound = 1;
13435       if (unformat (i, "inbound"))
13436         is_outbound = 0;
13437       else if (unformat (i, "spd_id %d", &spd_id))
13438         ;
13439       else if (unformat (i, "sa_id %d", &sa_id))
13440         ;
13441       else if (unformat (i, "priority %d", &priority))
13442         ;
13443       else if (unformat (i, "protocol %d", &protocol))
13444         ;
13445       else if (unformat (i, "lport_start %d", &lport_start))
13446         ;
13447       else if (unformat (i, "lport_stop %d", &lport_stop))
13448         ;
13449       else if (unformat (i, "rport_start %d", &rport_start))
13450         ;
13451       else if (unformat (i, "rport_stop %d", &rport_stop))
13452         ;
13453       else if (unformat (i, "laddr_start %U",
13454                          unformat_vl_api_address, &laddr_start))
13455         ;
13456       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13457                          &laddr_stop))
13458         ;
13459       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13460                          &raddr_start))
13461         ;
13462       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13463                          &raddr_stop))
13464         ;
13465       else
13466         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13467         {
13468           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13469             {
13470               clib_warning ("unsupported action: 'resolve'");
13471               return -99;
13472             }
13473         }
13474       else
13475         {
13476           clib_warning ("parse error '%U'", format_unformat_error, i);
13477           return -99;
13478         }
13479
13480     }
13481
13482   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13483
13484   mp->is_add = is_add;
13485
13486   mp->entry.spd_id = ntohl (spd_id);
13487   mp->entry.priority = ntohl (priority);
13488   mp->entry.is_outbound = is_outbound;
13489
13490   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13491                sizeof (vl_api_address_t));
13492   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13493                sizeof (vl_api_address_t));
13494   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13495                sizeof (vl_api_address_t));
13496   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13497                sizeof (vl_api_address_t));
13498
13499   mp->entry.protocol = (u8) protocol;
13500   mp->entry.local_port_start = ntohs ((u16) lport_start);
13501   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13502   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13503   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13504   mp->entry.policy = (u8) policy;
13505   mp->entry.sa_id = ntohl (sa_id);
13506
13507   S (mp);
13508   W (ret);
13509   return ret;
13510 }
13511
13512 static int
13513 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13514 {
13515   unformat_input_t *i = vam->input;
13516   vl_api_ipsec_sad_entry_add_del_t *mp;
13517   u32 sad_id = 0, spi = 0;
13518   u8 *ck = 0, *ik = 0;
13519   u8 is_add = 1;
13520
13521   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13522   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13523   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13524   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13525   vl_api_address_t tun_src, tun_dst;
13526   int ret;
13527
13528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13529     {
13530       if (unformat (i, "del"))
13531         is_add = 0;
13532       else if (unformat (i, "sad_id %d", &sad_id))
13533         ;
13534       else if (unformat (i, "spi %d", &spi))
13535         ;
13536       else if (unformat (i, "esp"))
13537         protocol = IPSEC_API_PROTO_ESP;
13538       else
13539         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13540         {
13541           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13542           if (ADDRESS_IP6 == tun_src.af)
13543             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13544         }
13545       else
13546         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13547         {
13548           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13549           if (ADDRESS_IP6 == tun_src.af)
13550             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13551         }
13552       else
13553         if (unformat (i, "crypto_alg %U",
13554                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13555         ;
13556       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13557         ;
13558       else if (unformat (i, "integ_alg %U",
13559                          unformat_ipsec_api_integ_alg, &integ_alg))
13560         ;
13561       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13562         ;
13563       else
13564         {
13565           clib_warning ("parse error '%U'", format_unformat_error, i);
13566           return -99;
13567         }
13568
13569     }
13570
13571   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13572
13573   mp->is_add = is_add;
13574   mp->entry.sad_id = ntohl (sad_id);
13575   mp->entry.protocol = protocol;
13576   mp->entry.spi = ntohl (spi);
13577   mp->entry.flags = flags;
13578
13579   mp->entry.crypto_algorithm = crypto_alg;
13580   mp->entry.integrity_algorithm = integ_alg;
13581   mp->entry.crypto_key.length = vec_len (ck);
13582   mp->entry.integrity_key.length = vec_len (ik);
13583
13584   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13585     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13586
13587   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13588     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13589
13590   if (ck)
13591     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13592   if (ik)
13593     clib_memcpy (mp->entry.integrity_key.data, ik,
13594                  mp->entry.integrity_key.length);
13595
13596   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13597     {
13598       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13599                    sizeof (mp->entry.tunnel_src));
13600       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13601                    sizeof (mp->entry.tunnel_dst));
13602     }
13603
13604   S (mp);
13605   W (ret);
13606   return ret;
13607 }
13608
13609 static int
13610 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13611 {
13612   unformat_input_t *i = vam->input;
13613   vl_api_ipsec_tunnel_if_add_del_t *mp;
13614   u32 local_spi = 0, remote_spi = 0;
13615   u32 crypto_alg = 0, integ_alg = 0;
13616   u8 *lck = NULL, *rck = NULL;
13617   u8 *lik = NULL, *rik = NULL;
13618   vl_api_address_t local_ip = { 0 };
13619   vl_api_address_t remote_ip = { 0 };
13620   f64 before = 0;
13621   u8 is_add = 1;
13622   u8 esn = 0;
13623   u8 anti_replay = 0;
13624   u8 renumber = 0;
13625   u32 instance = ~0;
13626   u32 count = 1, jj;
13627   int ret = -1;
13628
13629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13630     {
13631       if (unformat (i, "del"))
13632         is_add = 0;
13633       else if (unformat (i, "esn"))
13634         esn = 1;
13635       else if (unformat (i, "anti-replay"))
13636         anti_replay = 1;
13637       else if (unformat (i, "count %d", &count))
13638         ;
13639       else if (unformat (i, "local_spi %d", &local_spi))
13640         ;
13641       else if (unformat (i, "remote_spi %d", &remote_spi))
13642         ;
13643       else
13644         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13645         ;
13646       else
13647         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13648         ;
13649       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13650         ;
13651       else
13652         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13653         ;
13654       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13655         ;
13656       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13657         ;
13658       else
13659         if (unformat
13660             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13661         {
13662           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13663             {
13664               errmsg ("unsupported crypto-alg: '%U'\n",
13665                       format_ipsec_crypto_alg, crypto_alg);
13666               return -99;
13667             }
13668         }
13669       else
13670         if (unformat
13671             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13672         {
13673           if (integ_alg >= IPSEC_INTEG_N_ALG)
13674             {
13675               errmsg ("unsupported integ-alg: '%U'\n",
13676                       format_ipsec_integ_alg, integ_alg);
13677               return -99;
13678             }
13679         }
13680       else if (unformat (i, "instance %u", &instance))
13681         renumber = 1;
13682       else
13683         {
13684           errmsg ("parse error '%U'\n", format_unformat_error, i);
13685           return -99;
13686         }
13687     }
13688
13689   if (count > 1)
13690     {
13691       /* Turn on async mode */
13692       vam->async_mode = 1;
13693       vam->async_errors = 0;
13694       before = vat_time_now (vam);
13695     }
13696
13697   for (jj = 0; jj < count; jj++)
13698     {
13699       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13700
13701       mp->is_add = is_add;
13702       mp->esn = esn;
13703       mp->anti_replay = anti_replay;
13704
13705       if (jj > 0)
13706         increment_address (&remote_ip);
13707
13708       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13709       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13710
13711       mp->local_spi = htonl (local_spi + jj);
13712       mp->remote_spi = htonl (remote_spi + jj);
13713       mp->crypto_alg = (u8) crypto_alg;
13714
13715       mp->local_crypto_key_len = 0;
13716       if (lck)
13717         {
13718           mp->local_crypto_key_len = vec_len (lck);
13719           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13720             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13721           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13722         }
13723
13724       mp->remote_crypto_key_len = 0;
13725       if (rck)
13726         {
13727           mp->remote_crypto_key_len = vec_len (rck);
13728           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13729             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13730           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13731         }
13732
13733       mp->integ_alg = (u8) integ_alg;
13734
13735       mp->local_integ_key_len = 0;
13736       if (lik)
13737         {
13738           mp->local_integ_key_len = vec_len (lik);
13739           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13740             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13741           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13742         }
13743
13744       mp->remote_integ_key_len = 0;
13745       if (rik)
13746         {
13747           mp->remote_integ_key_len = vec_len (rik);
13748           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13749             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13750           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13751         }
13752
13753       if (renumber)
13754         {
13755           mp->renumber = renumber;
13756           mp->show_instance = ntohl (instance);
13757         }
13758       S (mp);
13759     }
13760
13761   /* When testing multiple add/del ops, use a control-ping to sync */
13762   if (count > 1)
13763     {
13764       vl_api_control_ping_t *mp_ping;
13765       f64 after;
13766       f64 timeout;
13767
13768       /* Shut off async mode */
13769       vam->async_mode = 0;
13770
13771       MPING (CONTROL_PING, mp_ping);
13772       S (mp_ping);
13773
13774       timeout = vat_time_now (vam) + 1.0;
13775       while (vat_time_now (vam) < timeout)
13776         if (vam->result_ready == 1)
13777           goto out;
13778       vam->retval = -99;
13779
13780     out:
13781       if (vam->retval == -99)
13782         errmsg ("timeout");
13783
13784       if (vam->async_errors > 0)
13785         {
13786           errmsg ("%d asynchronous errors", vam->async_errors);
13787           vam->retval = -98;
13788         }
13789       vam->async_errors = 0;
13790       after = vat_time_now (vam);
13791
13792       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13793       if (jj > 0)
13794         count = jj;
13795
13796       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13797              count, after - before, count / (after - before));
13798     }
13799   else
13800     {
13801       /* Wait for a reply... */
13802       W (ret);
13803       return ret;
13804     }
13805
13806   return ret;
13807 }
13808
13809 static void
13810 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13811 {
13812   vat_main_t *vam = &vat_main;
13813
13814   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13815          "crypto_key %U integ_alg %u integ_key %U flags %x "
13816          "tunnel_src_addr %U tunnel_dst_addr %U "
13817          "salt %u seq_outbound %lu last_seq_inbound %lu "
13818          "replay_window %lu stat_index %u\n",
13819          ntohl (mp->entry.sad_id),
13820          ntohl (mp->sw_if_index),
13821          ntohl (mp->entry.spi),
13822          ntohl (mp->entry.protocol),
13823          ntohl (mp->entry.crypto_algorithm),
13824          format_hex_bytes, mp->entry.crypto_key.data,
13825          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13826          format_hex_bytes, mp->entry.integrity_key.data,
13827          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13828          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13829          &mp->entry.tunnel_dst, ntohl (mp->salt),
13830          clib_net_to_host_u64 (mp->seq_outbound),
13831          clib_net_to_host_u64 (mp->last_seq_inbound),
13832          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13833 }
13834
13835 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13836 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13837
13838 static void vl_api_ipsec_sa_details_t_handler_json
13839   (vl_api_ipsec_sa_details_t * mp)
13840 {
13841   vat_main_t *vam = &vat_main;
13842   vat_json_node_t *node = NULL;
13843   vl_api_ipsec_sad_flags_t flags;
13844
13845   if (VAT_JSON_ARRAY != vam->json_tree.type)
13846     {
13847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13848       vat_json_init_array (&vam->json_tree);
13849     }
13850   node = vat_json_array_add (&vam->json_tree);
13851
13852   vat_json_init_object (node);
13853   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13854   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13855   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13856   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13857   vat_json_object_add_uint (node, "crypto_alg",
13858                             ntohl (mp->entry.crypto_algorithm));
13859   vat_json_object_add_uint (node, "integ_alg",
13860                             ntohl (mp->entry.integrity_algorithm));
13861   flags = ntohl (mp->entry.flags);
13862   vat_json_object_add_uint (node, "use_esn",
13863                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13864   vat_json_object_add_uint (node, "use_anti_replay",
13865                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13866   vat_json_object_add_uint (node, "is_tunnel",
13867                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13868   vat_json_object_add_uint (node, "is_tunnel_ip6",
13869                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13870   vat_json_object_add_uint (node, "udp_encap",
13871                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13872   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13873                              mp->entry.crypto_key.length);
13874   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13875                              mp->entry.integrity_key.length);
13876   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13877   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13878   vat_json_object_add_uint (node, "replay_window",
13879                             clib_net_to_host_u64 (mp->replay_window));
13880   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13881 }
13882
13883 static int
13884 api_ipsec_sa_dump (vat_main_t * vam)
13885 {
13886   unformat_input_t *i = vam->input;
13887   vl_api_ipsec_sa_dump_t *mp;
13888   vl_api_control_ping_t *mp_ping;
13889   u32 sa_id = ~0;
13890   int ret;
13891
13892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13893     {
13894       if (unformat (i, "sa_id %d", &sa_id))
13895         ;
13896       else
13897         {
13898           clib_warning ("parse error '%U'", format_unformat_error, i);
13899           return -99;
13900         }
13901     }
13902
13903   M (IPSEC_SA_DUMP, mp);
13904
13905   mp->sa_id = ntohl (sa_id);
13906
13907   S (mp);
13908
13909   /* Use a control ping for synchronization */
13910   M (CONTROL_PING, mp_ping);
13911   S (mp_ping);
13912
13913   W (ret);
13914   return ret;
13915 }
13916
13917 static int
13918 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13919 {
13920   unformat_input_t *i = vam->input;
13921   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13922   u32 sw_if_index = ~0;
13923   u32 sa_id = ~0;
13924   u8 is_outbound = (u8) ~ 0;
13925   int ret;
13926
13927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13928     {
13929       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13930         ;
13931       else if (unformat (i, "sa_id %d", &sa_id))
13932         ;
13933       else if (unformat (i, "outbound"))
13934         is_outbound = 1;
13935       else if (unformat (i, "inbound"))
13936         is_outbound = 0;
13937       else
13938         {
13939           clib_warning ("parse error '%U'", format_unformat_error, i);
13940           return -99;
13941         }
13942     }
13943
13944   if (sw_if_index == ~0)
13945     {
13946       errmsg ("interface must be specified");
13947       return -99;
13948     }
13949
13950   if (sa_id == ~0)
13951     {
13952       errmsg ("SA ID must be specified");
13953       return -99;
13954     }
13955
13956   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13957
13958   mp->sw_if_index = htonl (sw_if_index);
13959   mp->sa_id = htonl (sa_id);
13960   mp->is_outbound = is_outbound;
13961
13962   S (mp);
13963   W (ret);
13964
13965   return ret;
13966 }
13967
13968 static int
13969 api_get_first_msg_id (vat_main_t * vam)
13970 {
13971   vl_api_get_first_msg_id_t *mp;
13972   unformat_input_t *i = vam->input;
13973   u8 *name;
13974   u8 name_set = 0;
13975   int ret;
13976
13977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13978     {
13979       if (unformat (i, "client %s", &name))
13980         name_set = 1;
13981       else
13982         break;
13983     }
13984
13985   if (name_set == 0)
13986     {
13987       errmsg ("missing client name");
13988       return -99;
13989     }
13990   vec_add1 (name, 0);
13991
13992   if (vec_len (name) > 63)
13993     {
13994       errmsg ("client name too long");
13995       return -99;
13996     }
13997
13998   M (GET_FIRST_MSG_ID, mp);
13999   clib_memcpy (mp->name, name, vec_len (name));
14000   S (mp);
14001   W (ret);
14002   return ret;
14003 }
14004
14005 static int
14006 api_cop_interface_enable_disable (vat_main_t * vam)
14007 {
14008   unformat_input_t *line_input = vam->input;
14009   vl_api_cop_interface_enable_disable_t *mp;
14010   u32 sw_if_index = ~0;
14011   u8 enable_disable = 1;
14012   int ret;
14013
14014   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14015     {
14016       if (unformat (line_input, "disable"))
14017         enable_disable = 0;
14018       if (unformat (line_input, "enable"))
14019         enable_disable = 1;
14020       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14021                          vam, &sw_if_index))
14022         ;
14023       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14024         ;
14025       else
14026         break;
14027     }
14028
14029   if (sw_if_index == ~0)
14030     {
14031       errmsg ("missing interface name or sw_if_index");
14032       return -99;
14033     }
14034
14035   /* Construct the API message */
14036   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14037   mp->sw_if_index = ntohl (sw_if_index);
14038   mp->enable_disable = enable_disable;
14039
14040   /* send it... */
14041   S (mp);
14042   /* Wait for the reply */
14043   W (ret);
14044   return ret;
14045 }
14046
14047 static int
14048 api_cop_whitelist_enable_disable (vat_main_t * vam)
14049 {
14050   unformat_input_t *line_input = vam->input;
14051   vl_api_cop_whitelist_enable_disable_t *mp;
14052   u32 sw_if_index = ~0;
14053   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14054   u32 fib_id = 0;
14055   int ret;
14056
14057   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14058     {
14059       if (unformat (line_input, "ip4"))
14060         ip4 = 1;
14061       else if (unformat (line_input, "ip6"))
14062         ip6 = 1;
14063       else if (unformat (line_input, "default"))
14064         default_cop = 1;
14065       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14066                          vam, &sw_if_index))
14067         ;
14068       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14069         ;
14070       else if (unformat (line_input, "fib-id %d", &fib_id))
14071         ;
14072       else
14073         break;
14074     }
14075
14076   if (sw_if_index == ~0)
14077     {
14078       errmsg ("missing interface name or sw_if_index");
14079       return -99;
14080     }
14081
14082   /* Construct the API message */
14083   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14084   mp->sw_if_index = ntohl (sw_if_index);
14085   mp->fib_id = ntohl (fib_id);
14086   mp->ip4 = ip4;
14087   mp->ip6 = ip6;
14088   mp->default_cop = default_cop;
14089
14090   /* send it... */
14091   S (mp);
14092   /* Wait for the reply */
14093   W (ret);
14094   return ret;
14095 }
14096
14097 static int
14098 api_get_node_graph (vat_main_t * vam)
14099 {
14100   vl_api_get_node_graph_t *mp;
14101   int ret;
14102
14103   M (GET_NODE_GRAPH, mp);
14104
14105   /* send it... */
14106   S (mp);
14107   /* Wait for the reply */
14108   W (ret);
14109   return ret;
14110 }
14111
14112 /* *INDENT-OFF* */
14113 /** Used for parsing LISP eids */
14114 typedef CLIB_PACKED(struct{
14115   u8 addr[16];   /**< eid address */
14116   u32 len;       /**< prefix length if IP */
14117   u8 type;      /**< type of eid */
14118 }) lisp_eid_vat_t;
14119 /* *INDENT-ON* */
14120
14121 static uword
14122 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14123 {
14124   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14125
14126   clib_memset (a, 0, sizeof (a[0]));
14127
14128   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14129     {
14130       a->type = 0;              /* ipv4 type */
14131     }
14132   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14133     {
14134       a->type = 1;              /* ipv6 type */
14135     }
14136   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14137     {
14138       a->type = 2;              /* mac type */
14139     }
14140   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14141     {
14142       a->type = 3;              /* NSH type */
14143       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14144       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14145     }
14146   else
14147     {
14148       return 0;
14149     }
14150
14151   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14152     {
14153       return 0;
14154     }
14155
14156   return 1;
14157 }
14158
14159 static int
14160 lisp_eid_size_vat (u8 type)
14161 {
14162   switch (type)
14163     {
14164     case 0:
14165       return 4;
14166     case 1:
14167       return 16;
14168     case 2:
14169       return 6;
14170     case 3:
14171       return 5;
14172     }
14173   return 0;
14174 }
14175
14176 static void
14177 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14178 {
14179   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14180 }
14181
14182 static int
14183 api_one_add_del_locator_set (vat_main_t * vam)
14184 {
14185   unformat_input_t *input = vam->input;
14186   vl_api_one_add_del_locator_set_t *mp;
14187   u8 is_add = 1;
14188   u8 *locator_set_name = NULL;
14189   u8 locator_set_name_set = 0;
14190   vl_api_local_locator_t locator, *locators = 0;
14191   u32 sw_if_index, priority, weight;
14192   u32 data_len = 0;
14193
14194   int ret;
14195   /* Parse args required to build the message */
14196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14197     {
14198       if (unformat (input, "del"))
14199         {
14200           is_add = 0;
14201         }
14202       else if (unformat (input, "locator-set %s", &locator_set_name))
14203         {
14204           locator_set_name_set = 1;
14205         }
14206       else if (unformat (input, "sw_if_index %u p %u w %u",
14207                          &sw_if_index, &priority, &weight))
14208         {
14209           locator.sw_if_index = htonl (sw_if_index);
14210           locator.priority = priority;
14211           locator.weight = weight;
14212           vec_add1 (locators, locator);
14213         }
14214       else
14215         if (unformat
14216             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14217              &sw_if_index, &priority, &weight))
14218         {
14219           locator.sw_if_index = htonl (sw_if_index);
14220           locator.priority = priority;
14221           locator.weight = weight;
14222           vec_add1 (locators, locator);
14223         }
14224       else
14225         break;
14226     }
14227
14228   if (locator_set_name_set == 0)
14229     {
14230       errmsg ("missing locator-set name");
14231       vec_free (locators);
14232       return -99;
14233     }
14234
14235   if (vec_len (locator_set_name) > 64)
14236     {
14237       errmsg ("locator-set name too long");
14238       vec_free (locator_set_name);
14239       vec_free (locators);
14240       return -99;
14241     }
14242   vec_add1 (locator_set_name, 0);
14243
14244   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14245
14246   /* Construct the API message */
14247   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14248
14249   mp->is_add = is_add;
14250   clib_memcpy (mp->locator_set_name, locator_set_name,
14251                vec_len (locator_set_name));
14252   vec_free (locator_set_name);
14253
14254   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14255   if (locators)
14256     clib_memcpy (mp->locators, locators, data_len);
14257   vec_free (locators);
14258
14259   /* send it... */
14260   S (mp);
14261
14262   /* Wait for a reply... */
14263   W (ret);
14264   return ret;
14265 }
14266
14267 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14268
14269 static int
14270 api_one_add_del_locator (vat_main_t * vam)
14271 {
14272   unformat_input_t *input = vam->input;
14273   vl_api_one_add_del_locator_t *mp;
14274   u32 tmp_if_index = ~0;
14275   u32 sw_if_index = ~0;
14276   u8 sw_if_index_set = 0;
14277   u8 sw_if_index_if_name_set = 0;
14278   u32 priority = ~0;
14279   u8 priority_set = 0;
14280   u32 weight = ~0;
14281   u8 weight_set = 0;
14282   u8 is_add = 1;
14283   u8 *locator_set_name = NULL;
14284   u8 locator_set_name_set = 0;
14285   int ret;
14286
14287   /* Parse args required to build the message */
14288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14289     {
14290       if (unformat (input, "del"))
14291         {
14292           is_add = 0;
14293         }
14294       else if (unformat (input, "locator-set %s", &locator_set_name))
14295         {
14296           locator_set_name_set = 1;
14297         }
14298       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14299                          &tmp_if_index))
14300         {
14301           sw_if_index_if_name_set = 1;
14302           sw_if_index = tmp_if_index;
14303         }
14304       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14305         {
14306           sw_if_index_set = 1;
14307           sw_if_index = tmp_if_index;
14308         }
14309       else if (unformat (input, "p %d", &priority))
14310         {
14311           priority_set = 1;
14312         }
14313       else if (unformat (input, "w %d", &weight))
14314         {
14315           weight_set = 1;
14316         }
14317       else
14318         break;
14319     }
14320
14321   if (locator_set_name_set == 0)
14322     {
14323       errmsg ("missing locator-set name");
14324       return -99;
14325     }
14326
14327   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14328     {
14329       errmsg ("missing sw_if_index");
14330       vec_free (locator_set_name);
14331       return -99;
14332     }
14333
14334   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14335     {
14336       errmsg ("cannot use both params interface name and sw_if_index");
14337       vec_free (locator_set_name);
14338       return -99;
14339     }
14340
14341   if (priority_set == 0)
14342     {
14343       errmsg ("missing locator-set priority");
14344       vec_free (locator_set_name);
14345       return -99;
14346     }
14347
14348   if (weight_set == 0)
14349     {
14350       errmsg ("missing locator-set weight");
14351       vec_free (locator_set_name);
14352       return -99;
14353     }
14354
14355   if (vec_len (locator_set_name) > 64)
14356     {
14357       errmsg ("locator-set name too long");
14358       vec_free (locator_set_name);
14359       return -99;
14360     }
14361   vec_add1 (locator_set_name, 0);
14362
14363   /* Construct the API message */
14364   M (ONE_ADD_DEL_LOCATOR, mp);
14365
14366   mp->is_add = is_add;
14367   mp->sw_if_index = ntohl (sw_if_index);
14368   mp->priority = priority;
14369   mp->weight = weight;
14370   clib_memcpy (mp->locator_set_name, locator_set_name,
14371                vec_len (locator_set_name));
14372   vec_free (locator_set_name);
14373
14374   /* send it... */
14375   S (mp);
14376
14377   /* Wait for a reply... */
14378   W (ret);
14379   return ret;
14380 }
14381
14382 #define api_lisp_add_del_locator api_one_add_del_locator
14383
14384 uword
14385 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14386 {
14387   u32 *key_id = va_arg (*args, u32 *);
14388   u8 *s = 0;
14389
14390   if (unformat (input, "%s", &s))
14391     {
14392       if (!strcmp ((char *) s, "sha1"))
14393         key_id[0] = HMAC_SHA_1_96;
14394       else if (!strcmp ((char *) s, "sha256"))
14395         key_id[0] = HMAC_SHA_256_128;
14396       else
14397         {
14398           clib_warning ("invalid key_id: '%s'", s);
14399           key_id[0] = HMAC_NO_KEY;
14400         }
14401     }
14402   else
14403     return 0;
14404
14405   vec_free (s);
14406   return 1;
14407 }
14408
14409 static int
14410 api_one_add_del_local_eid (vat_main_t * vam)
14411 {
14412   unformat_input_t *input = vam->input;
14413   vl_api_one_add_del_local_eid_t *mp;
14414   u8 is_add = 1;
14415   u8 eid_set = 0;
14416   lisp_eid_vat_t _eid, *eid = &_eid;
14417   u8 *locator_set_name = 0;
14418   u8 locator_set_name_set = 0;
14419   u32 vni = 0;
14420   u16 key_id = 0;
14421   u8 *key = 0;
14422   int ret;
14423
14424   /* Parse args required to build the message */
14425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14426     {
14427       if (unformat (input, "del"))
14428         {
14429           is_add = 0;
14430         }
14431       else if (unformat (input, "vni %d", &vni))
14432         {
14433           ;
14434         }
14435       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14436         {
14437           eid_set = 1;
14438         }
14439       else if (unformat (input, "locator-set %s", &locator_set_name))
14440         {
14441           locator_set_name_set = 1;
14442         }
14443       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14444         ;
14445       else if (unformat (input, "secret-key %_%v%_", &key))
14446         ;
14447       else
14448         break;
14449     }
14450
14451   if (locator_set_name_set == 0)
14452     {
14453       errmsg ("missing locator-set name");
14454       return -99;
14455     }
14456
14457   if (0 == eid_set)
14458     {
14459       errmsg ("EID address not set!");
14460       vec_free (locator_set_name);
14461       return -99;
14462     }
14463
14464   if (key && (0 == key_id))
14465     {
14466       errmsg ("invalid key_id!");
14467       return -99;
14468     }
14469
14470   if (vec_len (key) > 64)
14471     {
14472       errmsg ("key too long");
14473       vec_free (key);
14474       return -99;
14475     }
14476
14477   if (vec_len (locator_set_name) > 64)
14478     {
14479       errmsg ("locator-set name too long");
14480       vec_free (locator_set_name);
14481       return -99;
14482     }
14483   vec_add1 (locator_set_name, 0);
14484
14485   /* Construct the API message */
14486   M (ONE_ADD_DEL_LOCAL_EID, mp);
14487
14488   mp->is_add = is_add;
14489   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14490   mp->eid_type = eid->type;
14491   mp->prefix_len = eid->len;
14492   mp->vni = clib_host_to_net_u32 (vni);
14493   mp->key_id = clib_host_to_net_u16 (key_id);
14494   clib_memcpy (mp->locator_set_name, locator_set_name,
14495                vec_len (locator_set_name));
14496   clib_memcpy (mp->key, key, vec_len (key));
14497
14498   vec_free (locator_set_name);
14499   vec_free (key);
14500
14501   /* send it... */
14502   S (mp);
14503
14504   /* Wait for a reply... */
14505   W (ret);
14506   return ret;
14507 }
14508
14509 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14510
14511 static int
14512 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14513 {
14514   u32 dp_table = 0, vni = 0;;
14515   unformat_input_t *input = vam->input;
14516   vl_api_gpe_add_del_fwd_entry_t *mp;
14517   u8 is_add = 1;
14518   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14519   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14520   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14521   u32 action = ~0, w;
14522   ip4_address_t rmt_rloc4, lcl_rloc4;
14523   ip6_address_t rmt_rloc6, lcl_rloc6;
14524   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14525   int ret;
14526
14527   clib_memset (&rloc, 0, sizeof (rloc));
14528
14529   /* Parse args required to build the message */
14530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14531     {
14532       if (unformat (input, "del"))
14533         is_add = 0;
14534       else if (unformat (input, "add"))
14535         is_add = 1;
14536       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14537         {
14538           rmt_eid_set = 1;
14539         }
14540       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14541         {
14542           lcl_eid_set = 1;
14543         }
14544       else if (unformat (input, "vrf %d", &dp_table))
14545         ;
14546       else if (unformat (input, "bd %d", &dp_table))
14547         ;
14548       else if (unformat (input, "vni %d", &vni))
14549         ;
14550       else if (unformat (input, "w %d", &w))
14551         {
14552           if (!curr_rloc)
14553             {
14554               errmsg ("No RLOC configured for setting priority/weight!");
14555               return -99;
14556             }
14557           curr_rloc->weight = w;
14558         }
14559       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14560                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14561         {
14562           rloc.is_ip4 = 1;
14563
14564           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14565           rloc.weight = 0;
14566           vec_add1 (lcl_locs, rloc);
14567
14568           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14569           vec_add1 (rmt_locs, rloc);
14570           /* weight saved in rmt loc */
14571           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14572         }
14573       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14574                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14575         {
14576           rloc.is_ip4 = 0;
14577           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14578           rloc.weight = 0;
14579           vec_add1 (lcl_locs, rloc);
14580
14581           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14582           vec_add1 (rmt_locs, rloc);
14583           /* weight saved in rmt loc */
14584           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14585         }
14586       else if (unformat (input, "action %d", &action))
14587         {
14588           ;
14589         }
14590       else
14591         {
14592           clib_warning ("parse error '%U'", format_unformat_error, input);
14593           return -99;
14594         }
14595     }
14596
14597   if (!rmt_eid_set)
14598     {
14599       errmsg ("remote eid addresses not set");
14600       return -99;
14601     }
14602
14603   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14604     {
14605       errmsg ("eid types don't match");
14606       return -99;
14607     }
14608
14609   if (0 == rmt_locs && (u32) ~ 0 == action)
14610     {
14611       errmsg ("action not set for negative mapping");
14612       return -99;
14613     }
14614
14615   /* Construct the API message */
14616   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14617       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14618
14619   mp->is_add = is_add;
14620   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14621   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14622   mp->eid_type = rmt_eid->type;
14623   mp->dp_table = clib_host_to_net_u32 (dp_table);
14624   mp->vni = clib_host_to_net_u32 (vni);
14625   mp->rmt_len = rmt_eid->len;
14626   mp->lcl_len = lcl_eid->len;
14627   mp->action = action;
14628
14629   if (0 != rmt_locs && 0 != lcl_locs)
14630     {
14631       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14632       clib_memcpy (mp->locs, lcl_locs,
14633                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14634
14635       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14636       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14637                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14638     }
14639   vec_free (lcl_locs);
14640   vec_free (rmt_locs);
14641
14642   /* send it... */
14643   S (mp);
14644
14645   /* Wait for a reply... */
14646   W (ret);
14647   return ret;
14648 }
14649
14650 static int
14651 api_one_add_del_map_server (vat_main_t * vam)
14652 {
14653   unformat_input_t *input = vam->input;
14654   vl_api_one_add_del_map_server_t *mp;
14655   u8 is_add = 1;
14656   u8 ipv4_set = 0;
14657   u8 ipv6_set = 0;
14658   ip4_address_t ipv4;
14659   ip6_address_t ipv6;
14660   int ret;
14661
14662   /* Parse args required to build the message */
14663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14664     {
14665       if (unformat (input, "del"))
14666         {
14667           is_add = 0;
14668         }
14669       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14670         {
14671           ipv4_set = 1;
14672         }
14673       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14674         {
14675           ipv6_set = 1;
14676         }
14677       else
14678         break;
14679     }
14680
14681   if (ipv4_set && ipv6_set)
14682     {
14683       errmsg ("both eid v4 and v6 addresses set");
14684       return -99;
14685     }
14686
14687   if (!ipv4_set && !ipv6_set)
14688     {
14689       errmsg ("eid addresses not set");
14690       return -99;
14691     }
14692
14693   /* Construct the API message */
14694   M (ONE_ADD_DEL_MAP_SERVER, mp);
14695
14696   mp->is_add = is_add;
14697   if (ipv6_set)
14698     {
14699       mp->is_ipv6 = 1;
14700       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14701     }
14702   else
14703     {
14704       mp->is_ipv6 = 0;
14705       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14706     }
14707
14708   /* send it... */
14709   S (mp);
14710
14711   /* Wait for a reply... */
14712   W (ret);
14713   return ret;
14714 }
14715
14716 #define api_lisp_add_del_map_server api_one_add_del_map_server
14717
14718 static int
14719 api_one_add_del_map_resolver (vat_main_t * vam)
14720 {
14721   unformat_input_t *input = vam->input;
14722   vl_api_one_add_del_map_resolver_t *mp;
14723   u8 is_add = 1;
14724   u8 ipv4_set = 0;
14725   u8 ipv6_set = 0;
14726   ip4_address_t ipv4;
14727   ip6_address_t ipv6;
14728   int ret;
14729
14730   /* Parse args required to build the message */
14731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14732     {
14733       if (unformat (input, "del"))
14734         {
14735           is_add = 0;
14736         }
14737       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14738         {
14739           ipv4_set = 1;
14740         }
14741       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14742         {
14743           ipv6_set = 1;
14744         }
14745       else
14746         break;
14747     }
14748
14749   if (ipv4_set && ipv6_set)
14750     {
14751       errmsg ("both eid v4 and v6 addresses set");
14752       return -99;
14753     }
14754
14755   if (!ipv4_set && !ipv6_set)
14756     {
14757       errmsg ("eid addresses not set");
14758       return -99;
14759     }
14760
14761   /* Construct the API message */
14762   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14763
14764   mp->is_add = is_add;
14765   if (ipv6_set)
14766     {
14767       mp->is_ipv6 = 1;
14768       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14769     }
14770   else
14771     {
14772       mp->is_ipv6 = 0;
14773       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14774     }
14775
14776   /* send it... */
14777   S (mp);
14778
14779   /* Wait for a reply... */
14780   W (ret);
14781   return ret;
14782 }
14783
14784 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14785
14786 static int
14787 api_lisp_gpe_enable_disable (vat_main_t * vam)
14788 {
14789   unformat_input_t *input = vam->input;
14790   vl_api_gpe_enable_disable_t *mp;
14791   u8 is_set = 0;
14792   u8 is_en = 1;
14793   int ret;
14794
14795   /* Parse args required to build the message */
14796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14797     {
14798       if (unformat (input, "enable"))
14799         {
14800           is_set = 1;
14801           is_en = 1;
14802         }
14803       else if (unformat (input, "disable"))
14804         {
14805           is_set = 1;
14806           is_en = 0;
14807         }
14808       else
14809         break;
14810     }
14811
14812   if (is_set == 0)
14813     {
14814       errmsg ("Value not set");
14815       return -99;
14816     }
14817
14818   /* Construct the API message */
14819   M (GPE_ENABLE_DISABLE, mp);
14820
14821   mp->is_en = is_en;
14822
14823   /* send it... */
14824   S (mp);
14825
14826   /* Wait for a reply... */
14827   W (ret);
14828   return ret;
14829 }
14830
14831 static int
14832 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14833 {
14834   unformat_input_t *input = vam->input;
14835   vl_api_one_rloc_probe_enable_disable_t *mp;
14836   u8 is_set = 0;
14837   u8 is_en = 0;
14838   int ret;
14839
14840   /* Parse args required to build the message */
14841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (input, "enable"))
14844         {
14845           is_set = 1;
14846           is_en = 1;
14847         }
14848       else if (unformat (input, "disable"))
14849         is_set = 1;
14850       else
14851         break;
14852     }
14853
14854   if (!is_set)
14855     {
14856       errmsg ("Value not set");
14857       return -99;
14858     }
14859
14860   /* Construct the API message */
14861   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14862
14863   mp->is_enabled = is_en;
14864
14865   /* send it... */
14866   S (mp);
14867
14868   /* Wait for a reply... */
14869   W (ret);
14870   return ret;
14871 }
14872
14873 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14874
14875 static int
14876 api_one_map_register_enable_disable (vat_main_t * vam)
14877 {
14878   unformat_input_t *input = vam->input;
14879   vl_api_one_map_register_enable_disable_t *mp;
14880   u8 is_set = 0;
14881   u8 is_en = 0;
14882   int ret;
14883
14884   /* Parse args required to build the message */
14885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14886     {
14887       if (unformat (input, "enable"))
14888         {
14889           is_set = 1;
14890           is_en = 1;
14891         }
14892       else if (unformat (input, "disable"))
14893         is_set = 1;
14894       else
14895         break;
14896     }
14897
14898   if (!is_set)
14899     {
14900       errmsg ("Value not set");
14901       return -99;
14902     }
14903
14904   /* Construct the API message */
14905   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14906
14907   mp->is_enabled = is_en;
14908
14909   /* send it... */
14910   S (mp);
14911
14912   /* Wait for a reply... */
14913   W (ret);
14914   return ret;
14915 }
14916
14917 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14918
14919 static int
14920 api_one_enable_disable (vat_main_t * vam)
14921 {
14922   unformat_input_t *input = vam->input;
14923   vl_api_one_enable_disable_t *mp;
14924   u8 is_set = 0;
14925   u8 is_en = 0;
14926   int ret;
14927
14928   /* Parse args required to build the message */
14929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14930     {
14931       if (unformat (input, "enable"))
14932         {
14933           is_set = 1;
14934           is_en = 1;
14935         }
14936       else if (unformat (input, "disable"))
14937         {
14938           is_set = 1;
14939         }
14940       else
14941         break;
14942     }
14943
14944   if (!is_set)
14945     {
14946       errmsg ("Value not set");
14947       return -99;
14948     }
14949
14950   /* Construct the API message */
14951   M (ONE_ENABLE_DISABLE, mp);
14952
14953   mp->is_en = is_en;
14954
14955   /* send it... */
14956   S (mp);
14957
14958   /* Wait for a reply... */
14959   W (ret);
14960   return ret;
14961 }
14962
14963 #define api_lisp_enable_disable api_one_enable_disable
14964
14965 static int
14966 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14967 {
14968   unformat_input_t *input = vam->input;
14969   vl_api_one_enable_disable_xtr_mode_t *mp;
14970   u8 is_set = 0;
14971   u8 is_en = 0;
14972   int ret;
14973
14974   /* Parse args required to build the message */
14975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14976     {
14977       if (unformat (input, "enable"))
14978         {
14979           is_set = 1;
14980           is_en = 1;
14981         }
14982       else if (unformat (input, "disable"))
14983         {
14984           is_set = 1;
14985         }
14986       else
14987         break;
14988     }
14989
14990   if (!is_set)
14991     {
14992       errmsg ("Value not set");
14993       return -99;
14994     }
14995
14996   /* Construct the API message */
14997   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14998
14999   mp->is_en = is_en;
15000
15001   /* send it... */
15002   S (mp);
15003
15004   /* Wait for a reply... */
15005   W (ret);
15006   return ret;
15007 }
15008
15009 static int
15010 api_one_show_xtr_mode (vat_main_t * vam)
15011 {
15012   vl_api_one_show_xtr_mode_t *mp;
15013   int ret;
15014
15015   /* Construct the API message */
15016   M (ONE_SHOW_XTR_MODE, mp);
15017
15018   /* send it... */
15019   S (mp);
15020
15021   /* Wait for a reply... */
15022   W (ret);
15023   return ret;
15024 }
15025
15026 static int
15027 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15028 {
15029   unformat_input_t *input = vam->input;
15030   vl_api_one_enable_disable_pitr_mode_t *mp;
15031   u8 is_set = 0;
15032   u8 is_en = 0;
15033   int ret;
15034
15035   /* Parse args required to build the message */
15036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15037     {
15038       if (unformat (input, "enable"))
15039         {
15040           is_set = 1;
15041           is_en = 1;
15042         }
15043       else if (unformat (input, "disable"))
15044         {
15045           is_set = 1;
15046         }
15047       else
15048         break;
15049     }
15050
15051   if (!is_set)
15052     {
15053       errmsg ("Value not set");
15054       return -99;
15055     }
15056
15057   /* Construct the API message */
15058   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15059
15060   mp->is_en = is_en;
15061
15062   /* send it... */
15063   S (mp);
15064
15065   /* Wait for a reply... */
15066   W (ret);
15067   return ret;
15068 }
15069
15070 static int
15071 api_one_show_pitr_mode (vat_main_t * vam)
15072 {
15073   vl_api_one_show_pitr_mode_t *mp;
15074   int ret;
15075
15076   /* Construct the API message */
15077   M (ONE_SHOW_PITR_MODE, mp);
15078
15079   /* send it... */
15080   S (mp);
15081
15082   /* Wait for a reply... */
15083   W (ret);
15084   return ret;
15085 }
15086
15087 static int
15088 api_one_enable_disable_petr_mode (vat_main_t * vam)
15089 {
15090   unformat_input_t *input = vam->input;
15091   vl_api_one_enable_disable_petr_mode_t *mp;
15092   u8 is_set = 0;
15093   u8 is_en = 0;
15094   int ret;
15095
15096   /* Parse args required to build the message */
15097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (input, "enable"))
15100         {
15101           is_set = 1;
15102           is_en = 1;
15103         }
15104       else if (unformat (input, "disable"))
15105         {
15106           is_set = 1;
15107         }
15108       else
15109         break;
15110     }
15111
15112   if (!is_set)
15113     {
15114       errmsg ("Value not set");
15115       return -99;
15116     }
15117
15118   /* Construct the API message */
15119   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15120
15121   mp->is_en = is_en;
15122
15123   /* send it... */
15124   S (mp);
15125
15126   /* Wait for a reply... */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 static int
15132 api_one_show_petr_mode (vat_main_t * vam)
15133 {
15134   vl_api_one_show_petr_mode_t *mp;
15135   int ret;
15136
15137   /* Construct the API message */
15138   M (ONE_SHOW_PETR_MODE, mp);
15139
15140   /* send it... */
15141   S (mp);
15142
15143   /* Wait for a reply... */
15144   W (ret);
15145   return ret;
15146 }
15147
15148 static int
15149 api_show_one_map_register_state (vat_main_t * vam)
15150 {
15151   vl_api_show_one_map_register_state_t *mp;
15152   int ret;
15153
15154   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15155
15156   /* send */
15157   S (mp);
15158
15159   /* wait for reply */
15160   W (ret);
15161   return ret;
15162 }
15163
15164 #define api_show_lisp_map_register_state api_show_one_map_register_state
15165
15166 static int
15167 api_show_one_rloc_probe_state (vat_main_t * vam)
15168 {
15169   vl_api_show_one_rloc_probe_state_t *mp;
15170   int ret;
15171
15172   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15173
15174   /* send */
15175   S (mp);
15176
15177   /* wait for reply */
15178   W (ret);
15179   return ret;
15180 }
15181
15182 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15183
15184 static int
15185 api_one_add_del_ndp_entry (vat_main_t * vam)
15186 {
15187   vl_api_one_add_del_ndp_entry_t *mp;
15188   unformat_input_t *input = vam->input;
15189   u8 is_add = 1;
15190   u8 mac_set = 0;
15191   u8 bd_set = 0;
15192   u8 ip_set = 0;
15193   u8 mac[6] = { 0, };
15194   u8 ip6[16] = { 0, };
15195   u32 bd = ~0;
15196   int ret;
15197
15198   /* Parse args required to build the message */
15199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15200     {
15201       if (unformat (input, "del"))
15202         is_add = 0;
15203       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15204         mac_set = 1;
15205       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15206         ip_set = 1;
15207       else if (unformat (input, "bd %d", &bd))
15208         bd_set = 1;
15209       else
15210         {
15211           errmsg ("parse error '%U'", format_unformat_error, input);
15212           return -99;
15213         }
15214     }
15215
15216   if (!bd_set || !ip_set || (!mac_set && is_add))
15217     {
15218       errmsg ("Missing BD, IP or MAC!");
15219       return -99;
15220     }
15221
15222   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15223   mp->is_add = is_add;
15224   clib_memcpy (mp->mac, mac, 6);
15225   mp->bd = clib_host_to_net_u32 (bd);
15226   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15227
15228   /* send */
15229   S (mp);
15230
15231   /* wait for reply */
15232   W (ret);
15233   return ret;
15234 }
15235
15236 static int
15237 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15238 {
15239   vl_api_one_add_del_l2_arp_entry_t *mp;
15240   unformat_input_t *input = vam->input;
15241   u8 is_add = 1;
15242   u8 mac_set = 0;
15243   u8 bd_set = 0;
15244   u8 ip_set = 0;
15245   u8 mac[6] = { 0, };
15246   u32 ip4 = 0, bd = ~0;
15247   int ret;
15248
15249   /* Parse args required to build the message */
15250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15251     {
15252       if (unformat (input, "del"))
15253         is_add = 0;
15254       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15255         mac_set = 1;
15256       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15257         ip_set = 1;
15258       else if (unformat (input, "bd %d", &bd))
15259         bd_set = 1;
15260       else
15261         {
15262           errmsg ("parse error '%U'", format_unformat_error, input);
15263           return -99;
15264         }
15265     }
15266
15267   if (!bd_set || !ip_set || (!mac_set && is_add))
15268     {
15269       errmsg ("Missing BD, IP or MAC!");
15270       return -99;
15271     }
15272
15273   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15274   mp->is_add = is_add;
15275   clib_memcpy (mp->mac, mac, 6);
15276   mp->bd = clib_host_to_net_u32 (bd);
15277   mp->ip4 = ip4;
15278
15279   /* send */
15280   S (mp);
15281
15282   /* wait for reply */
15283   W (ret);
15284   return ret;
15285 }
15286
15287 static int
15288 api_one_ndp_bd_get (vat_main_t * vam)
15289 {
15290   vl_api_one_ndp_bd_get_t *mp;
15291   int ret;
15292
15293   M (ONE_NDP_BD_GET, mp);
15294
15295   /* send */
15296   S (mp);
15297
15298   /* wait for reply */
15299   W (ret);
15300   return ret;
15301 }
15302
15303 static int
15304 api_one_ndp_entries_get (vat_main_t * vam)
15305 {
15306   vl_api_one_ndp_entries_get_t *mp;
15307   unformat_input_t *input = vam->input;
15308   u8 bd_set = 0;
15309   u32 bd = ~0;
15310   int ret;
15311
15312   /* Parse args required to build the message */
15313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15314     {
15315       if (unformat (input, "bd %d", &bd))
15316         bd_set = 1;
15317       else
15318         {
15319           errmsg ("parse error '%U'", format_unformat_error, input);
15320           return -99;
15321         }
15322     }
15323
15324   if (!bd_set)
15325     {
15326       errmsg ("Expected bridge domain!");
15327       return -99;
15328     }
15329
15330   M (ONE_NDP_ENTRIES_GET, mp);
15331   mp->bd = clib_host_to_net_u32 (bd);
15332
15333   /* send */
15334   S (mp);
15335
15336   /* wait for reply */
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static int
15342 api_one_l2_arp_bd_get (vat_main_t * vam)
15343 {
15344   vl_api_one_l2_arp_bd_get_t *mp;
15345   int ret;
15346
15347   M (ONE_L2_ARP_BD_GET, mp);
15348
15349   /* send */
15350   S (mp);
15351
15352   /* wait for reply */
15353   W (ret);
15354   return ret;
15355 }
15356
15357 static int
15358 api_one_l2_arp_entries_get (vat_main_t * vam)
15359 {
15360   vl_api_one_l2_arp_entries_get_t *mp;
15361   unformat_input_t *input = vam->input;
15362   u8 bd_set = 0;
15363   u32 bd = ~0;
15364   int ret;
15365
15366   /* Parse args required to build the message */
15367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (input, "bd %d", &bd))
15370         bd_set = 1;
15371       else
15372         {
15373           errmsg ("parse error '%U'", format_unformat_error, input);
15374           return -99;
15375         }
15376     }
15377
15378   if (!bd_set)
15379     {
15380       errmsg ("Expected bridge domain!");
15381       return -99;
15382     }
15383
15384   M (ONE_L2_ARP_ENTRIES_GET, mp);
15385   mp->bd = clib_host_to_net_u32 (bd);
15386
15387   /* send */
15388   S (mp);
15389
15390   /* wait for reply */
15391   W (ret);
15392   return ret;
15393 }
15394
15395 static int
15396 api_one_stats_enable_disable (vat_main_t * vam)
15397 {
15398   vl_api_one_stats_enable_disable_t *mp;
15399   unformat_input_t *input = vam->input;
15400   u8 is_set = 0;
15401   u8 is_en = 0;
15402   int ret;
15403
15404   /* Parse args required to build the message */
15405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15406     {
15407       if (unformat (input, "enable"))
15408         {
15409           is_set = 1;
15410           is_en = 1;
15411         }
15412       else if (unformat (input, "disable"))
15413         {
15414           is_set = 1;
15415         }
15416       else
15417         break;
15418     }
15419
15420   if (!is_set)
15421     {
15422       errmsg ("Value not set");
15423       return -99;
15424     }
15425
15426   M (ONE_STATS_ENABLE_DISABLE, mp);
15427   mp->is_en = is_en;
15428
15429   /* send */
15430   S (mp);
15431
15432   /* wait for reply */
15433   W (ret);
15434   return ret;
15435 }
15436
15437 static int
15438 api_show_one_stats_enable_disable (vat_main_t * vam)
15439 {
15440   vl_api_show_one_stats_enable_disable_t *mp;
15441   int ret;
15442
15443   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15444
15445   /* send */
15446   S (mp);
15447
15448   /* wait for reply */
15449   W (ret);
15450   return ret;
15451 }
15452
15453 static int
15454 api_show_one_map_request_mode (vat_main_t * vam)
15455 {
15456   vl_api_show_one_map_request_mode_t *mp;
15457   int ret;
15458
15459   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15460
15461   /* send */
15462   S (mp);
15463
15464   /* wait for reply */
15465   W (ret);
15466   return ret;
15467 }
15468
15469 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15470
15471 static int
15472 api_one_map_request_mode (vat_main_t * vam)
15473 {
15474   unformat_input_t *input = vam->input;
15475   vl_api_one_map_request_mode_t *mp;
15476   u8 mode = 0;
15477   int ret;
15478
15479   /* Parse args required to build the message */
15480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15481     {
15482       if (unformat (input, "dst-only"))
15483         mode = 0;
15484       else if (unformat (input, "src-dst"))
15485         mode = 1;
15486       else
15487         {
15488           errmsg ("parse error '%U'", format_unformat_error, input);
15489           return -99;
15490         }
15491     }
15492
15493   M (ONE_MAP_REQUEST_MODE, mp);
15494
15495   mp->mode = mode;
15496
15497   /* send */
15498   S (mp);
15499
15500   /* wait for reply */
15501   W (ret);
15502   return ret;
15503 }
15504
15505 #define api_lisp_map_request_mode api_one_map_request_mode
15506
15507 /**
15508  * Enable/disable ONE proxy ITR.
15509  *
15510  * @param vam vpp API test context
15511  * @return return code
15512  */
15513 static int
15514 api_one_pitr_set_locator_set (vat_main_t * vam)
15515 {
15516   u8 ls_name_set = 0;
15517   unformat_input_t *input = vam->input;
15518   vl_api_one_pitr_set_locator_set_t *mp;
15519   u8 is_add = 1;
15520   u8 *ls_name = 0;
15521   int ret;
15522
15523   /* Parse args required to build the message */
15524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15525     {
15526       if (unformat (input, "del"))
15527         is_add = 0;
15528       else if (unformat (input, "locator-set %s", &ls_name))
15529         ls_name_set = 1;
15530       else
15531         {
15532           errmsg ("parse error '%U'", format_unformat_error, input);
15533           return -99;
15534         }
15535     }
15536
15537   if (!ls_name_set)
15538     {
15539       errmsg ("locator-set name not set!");
15540       return -99;
15541     }
15542
15543   M (ONE_PITR_SET_LOCATOR_SET, mp);
15544
15545   mp->is_add = is_add;
15546   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15547   vec_free (ls_name);
15548
15549   /* send */
15550   S (mp);
15551
15552   /* wait for reply */
15553   W (ret);
15554   return ret;
15555 }
15556
15557 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15558
15559 static int
15560 api_one_nsh_set_locator_set (vat_main_t * vam)
15561 {
15562   u8 ls_name_set = 0;
15563   unformat_input_t *input = vam->input;
15564   vl_api_one_nsh_set_locator_set_t *mp;
15565   u8 is_add = 1;
15566   u8 *ls_name = 0;
15567   int ret;
15568
15569   /* Parse args required to build the message */
15570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15571     {
15572       if (unformat (input, "del"))
15573         is_add = 0;
15574       else if (unformat (input, "ls %s", &ls_name))
15575         ls_name_set = 1;
15576       else
15577         {
15578           errmsg ("parse error '%U'", format_unformat_error, input);
15579           return -99;
15580         }
15581     }
15582
15583   if (!ls_name_set && is_add)
15584     {
15585       errmsg ("locator-set name not set!");
15586       return -99;
15587     }
15588
15589   M (ONE_NSH_SET_LOCATOR_SET, mp);
15590
15591   mp->is_add = is_add;
15592   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15593   vec_free (ls_name);
15594
15595   /* send */
15596   S (mp);
15597
15598   /* wait for reply */
15599   W (ret);
15600   return ret;
15601 }
15602
15603 static int
15604 api_show_one_pitr (vat_main_t * vam)
15605 {
15606   vl_api_show_one_pitr_t *mp;
15607   int ret;
15608
15609   if (!vam->json_output)
15610     {
15611       print (vam->ofp, "%=20s", "lisp status:");
15612     }
15613
15614   M (SHOW_ONE_PITR, mp);
15615   /* send it... */
15616   S (mp);
15617
15618   /* Wait for a reply... */
15619   W (ret);
15620   return ret;
15621 }
15622
15623 #define api_show_lisp_pitr api_show_one_pitr
15624
15625 static int
15626 api_one_use_petr (vat_main_t * vam)
15627 {
15628   unformat_input_t *input = vam->input;
15629   vl_api_one_use_petr_t *mp;
15630   u8 is_add = 0;
15631   ip_address_t ip;
15632   int ret;
15633
15634   clib_memset (&ip, 0, sizeof (ip));
15635
15636   /* Parse args required to build the message */
15637   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15638     {
15639       if (unformat (input, "disable"))
15640         is_add = 0;
15641       else
15642         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15643         {
15644           is_add = 1;
15645           ip_addr_version (&ip) = AF_IP4;
15646         }
15647       else
15648         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15649         {
15650           is_add = 1;
15651           ip_addr_version (&ip) = AF_IP6;
15652         }
15653       else
15654         {
15655           errmsg ("parse error '%U'", format_unformat_error, input);
15656           return -99;
15657         }
15658     }
15659
15660   M (ONE_USE_PETR, mp);
15661
15662   mp->is_add = is_add;
15663   if (is_add)
15664     {
15665       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15666       if (mp->is_ip4)
15667         clib_memcpy (mp->address, &ip, 4);
15668       else
15669         clib_memcpy (mp->address, &ip, 16);
15670     }
15671
15672   /* send */
15673   S (mp);
15674
15675   /* wait for reply */
15676   W (ret);
15677   return ret;
15678 }
15679
15680 #define api_lisp_use_petr api_one_use_petr
15681
15682 static int
15683 api_show_one_nsh_mapping (vat_main_t * vam)
15684 {
15685   vl_api_show_one_use_petr_t *mp;
15686   int ret;
15687
15688   if (!vam->json_output)
15689     {
15690       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15691     }
15692
15693   M (SHOW_ONE_NSH_MAPPING, mp);
15694   /* send it... */
15695   S (mp);
15696
15697   /* Wait for a reply... */
15698   W (ret);
15699   return ret;
15700 }
15701
15702 static int
15703 api_show_one_use_petr (vat_main_t * vam)
15704 {
15705   vl_api_show_one_use_petr_t *mp;
15706   int ret;
15707
15708   if (!vam->json_output)
15709     {
15710       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15711     }
15712
15713   M (SHOW_ONE_USE_PETR, mp);
15714   /* send it... */
15715   S (mp);
15716
15717   /* Wait for a reply... */
15718   W (ret);
15719   return ret;
15720 }
15721
15722 #define api_show_lisp_use_petr api_show_one_use_petr
15723
15724 /**
15725  * Add/delete mapping between vni and vrf
15726  */
15727 static int
15728 api_one_eid_table_add_del_map (vat_main_t * vam)
15729 {
15730   unformat_input_t *input = vam->input;
15731   vl_api_one_eid_table_add_del_map_t *mp;
15732   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15733   u32 vni, vrf, bd_index;
15734   int ret;
15735
15736   /* Parse args required to build the message */
15737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15738     {
15739       if (unformat (input, "del"))
15740         is_add = 0;
15741       else if (unformat (input, "vrf %d", &vrf))
15742         vrf_set = 1;
15743       else if (unformat (input, "bd_index %d", &bd_index))
15744         bd_index_set = 1;
15745       else if (unformat (input, "vni %d", &vni))
15746         vni_set = 1;
15747       else
15748         break;
15749     }
15750
15751   if (!vni_set || (!vrf_set && !bd_index_set))
15752     {
15753       errmsg ("missing arguments!");
15754       return -99;
15755     }
15756
15757   if (vrf_set && bd_index_set)
15758     {
15759       errmsg ("error: both vrf and bd entered!");
15760       return -99;
15761     }
15762
15763   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15764
15765   mp->is_add = is_add;
15766   mp->vni = htonl (vni);
15767   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15768   mp->is_l2 = bd_index_set;
15769
15770   /* send */
15771   S (mp);
15772
15773   /* wait for reply */
15774   W (ret);
15775   return ret;
15776 }
15777
15778 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15779
15780 uword
15781 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15782 {
15783   u32 *action = va_arg (*args, u32 *);
15784   u8 *s = 0;
15785
15786   if (unformat (input, "%s", &s))
15787     {
15788       if (!strcmp ((char *) s, "no-action"))
15789         action[0] = 0;
15790       else if (!strcmp ((char *) s, "natively-forward"))
15791         action[0] = 1;
15792       else if (!strcmp ((char *) s, "send-map-request"))
15793         action[0] = 2;
15794       else if (!strcmp ((char *) s, "drop"))
15795         action[0] = 3;
15796       else
15797         {
15798           clib_warning ("invalid action: '%s'", s);
15799           action[0] = 3;
15800         }
15801     }
15802   else
15803     return 0;
15804
15805   vec_free (s);
15806   return 1;
15807 }
15808
15809 /**
15810  * Add/del remote mapping to/from ONE control plane
15811  *
15812  * @param vam vpp API test context
15813  * @return return code
15814  */
15815 static int
15816 api_one_add_del_remote_mapping (vat_main_t * vam)
15817 {
15818   unformat_input_t *input = vam->input;
15819   vl_api_one_add_del_remote_mapping_t *mp;
15820   u32 vni = 0;
15821   lisp_eid_vat_t _eid, *eid = &_eid;
15822   lisp_eid_vat_t _seid, *seid = &_seid;
15823   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15824   u32 action = ~0, p, w, data_len;
15825   ip4_address_t rloc4;
15826   ip6_address_t rloc6;
15827   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15828   int ret;
15829
15830   clib_memset (&rloc, 0, sizeof (rloc));
15831
15832   /* Parse args required to build the message */
15833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15834     {
15835       if (unformat (input, "del-all"))
15836         {
15837           del_all = 1;
15838         }
15839       else if (unformat (input, "del"))
15840         {
15841           is_add = 0;
15842         }
15843       else if (unformat (input, "add"))
15844         {
15845           is_add = 1;
15846         }
15847       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15848         {
15849           eid_set = 1;
15850         }
15851       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15852         {
15853           seid_set = 1;
15854         }
15855       else if (unformat (input, "vni %d", &vni))
15856         {
15857           ;
15858         }
15859       else if (unformat (input, "p %d w %d", &p, &w))
15860         {
15861           if (!curr_rloc)
15862             {
15863               errmsg ("No RLOC configured for setting priority/weight!");
15864               return -99;
15865             }
15866           curr_rloc->priority = p;
15867           curr_rloc->weight = w;
15868         }
15869       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15870         {
15871           rloc.is_ip4 = 1;
15872           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15873           vec_add1 (rlocs, rloc);
15874           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15875         }
15876       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15877         {
15878           rloc.is_ip4 = 0;
15879           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15880           vec_add1 (rlocs, rloc);
15881           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15882         }
15883       else if (unformat (input, "action %U",
15884                          unformat_negative_mapping_action, &action))
15885         {
15886           ;
15887         }
15888       else
15889         {
15890           clib_warning ("parse error '%U'", format_unformat_error, input);
15891           return -99;
15892         }
15893     }
15894
15895   if (0 == eid_set)
15896     {
15897       errmsg ("missing params!");
15898       return -99;
15899     }
15900
15901   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15902     {
15903       errmsg ("no action set for negative map-reply!");
15904       return -99;
15905     }
15906
15907   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15908
15909   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15910   mp->is_add = is_add;
15911   mp->vni = htonl (vni);
15912   mp->action = (u8) action;
15913   mp->is_src_dst = seid_set;
15914   mp->eid_len = eid->len;
15915   mp->seid_len = seid->len;
15916   mp->del_all = del_all;
15917   mp->eid_type = eid->type;
15918   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15919   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15920
15921   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15922   clib_memcpy (mp->rlocs, rlocs, data_len);
15923   vec_free (rlocs);
15924
15925   /* send it... */
15926   S (mp);
15927
15928   /* Wait for a reply... */
15929   W (ret);
15930   return ret;
15931 }
15932
15933 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15934
15935 /**
15936  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15937  * forwarding entries in data-plane accordingly.
15938  *
15939  * @param vam vpp API test context
15940  * @return return code
15941  */
15942 static int
15943 api_one_add_del_adjacency (vat_main_t * vam)
15944 {
15945   unformat_input_t *input = vam->input;
15946   vl_api_one_add_del_adjacency_t *mp;
15947   u32 vni = 0;
15948   ip4_address_t leid4, reid4;
15949   ip6_address_t leid6, reid6;
15950   u8 reid_mac[6] = { 0 };
15951   u8 leid_mac[6] = { 0 };
15952   u8 reid_type, leid_type;
15953   u32 leid_len = 0, reid_len = 0, len;
15954   u8 is_add = 1;
15955   int ret;
15956
15957   leid_type = reid_type = (u8) ~ 0;
15958
15959   /* Parse args required to build the message */
15960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15961     {
15962       if (unformat (input, "del"))
15963         {
15964           is_add = 0;
15965         }
15966       else if (unformat (input, "add"))
15967         {
15968           is_add = 1;
15969         }
15970       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15971                          &reid4, &len))
15972         {
15973           reid_type = 0;        /* ipv4 */
15974           reid_len = len;
15975         }
15976       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15977                          &reid6, &len))
15978         {
15979           reid_type = 1;        /* ipv6 */
15980           reid_len = len;
15981         }
15982       else if (unformat (input, "reid %U", unformat_ethernet_address,
15983                          reid_mac))
15984         {
15985           reid_type = 2;        /* mac */
15986         }
15987       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15988                          &leid4, &len))
15989         {
15990           leid_type = 0;        /* ipv4 */
15991           leid_len = len;
15992         }
15993       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15994                          &leid6, &len))
15995         {
15996           leid_type = 1;        /* ipv6 */
15997           leid_len = len;
15998         }
15999       else if (unformat (input, "leid %U", unformat_ethernet_address,
16000                          leid_mac))
16001         {
16002           leid_type = 2;        /* mac */
16003         }
16004       else if (unformat (input, "vni %d", &vni))
16005         {
16006           ;
16007         }
16008       else
16009         {
16010           errmsg ("parse error '%U'", format_unformat_error, input);
16011           return -99;
16012         }
16013     }
16014
16015   if ((u8) ~ 0 == reid_type)
16016     {
16017       errmsg ("missing params!");
16018       return -99;
16019     }
16020
16021   if (leid_type != reid_type)
16022     {
16023       errmsg ("remote and local EIDs are of different types!");
16024       return -99;
16025     }
16026
16027   M (ONE_ADD_DEL_ADJACENCY, mp);
16028   mp->is_add = is_add;
16029   mp->vni = htonl (vni);
16030   mp->leid_len = leid_len;
16031   mp->reid_len = reid_len;
16032   mp->eid_type = reid_type;
16033
16034   switch (mp->eid_type)
16035     {
16036     case 0:
16037       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16038       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16039       break;
16040     case 1:
16041       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16042       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16043       break;
16044     case 2:
16045       clib_memcpy (mp->leid, leid_mac, 6);
16046       clib_memcpy (mp->reid, reid_mac, 6);
16047       break;
16048     default:
16049       errmsg ("unknown EID type %d!", mp->eid_type);
16050       return 0;
16051     }
16052
16053   /* send it... */
16054   S (mp);
16055
16056   /* Wait for a reply... */
16057   W (ret);
16058   return ret;
16059 }
16060
16061 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16062
16063 uword
16064 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16065 {
16066   u32 *mode = va_arg (*args, u32 *);
16067
16068   if (unformat (input, "lisp"))
16069     *mode = 0;
16070   else if (unformat (input, "vxlan"))
16071     *mode = 1;
16072   else
16073     return 0;
16074
16075   return 1;
16076 }
16077
16078 static int
16079 api_gpe_get_encap_mode (vat_main_t * vam)
16080 {
16081   vl_api_gpe_get_encap_mode_t *mp;
16082   int ret;
16083
16084   /* Construct the API message */
16085   M (GPE_GET_ENCAP_MODE, mp);
16086
16087   /* send it... */
16088   S (mp);
16089
16090   /* Wait for a reply... */
16091   W (ret);
16092   return ret;
16093 }
16094
16095 static int
16096 api_gpe_set_encap_mode (vat_main_t * vam)
16097 {
16098   unformat_input_t *input = vam->input;
16099   vl_api_gpe_set_encap_mode_t *mp;
16100   int ret;
16101   u32 mode = 0;
16102
16103   /* Parse args required to build the message */
16104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16105     {
16106       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16107         ;
16108       else
16109         break;
16110     }
16111
16112   /* Construct the API message */
16113   M (GPE_SET_ENCAP_MODE, mp);
16114
16115   mp->mode = mode;
16116
16117   /* send it... */
16118   S (mp);
16119
16120   /* Wait for a reply... */
16121   W (ret);
16122   return ret;
16123 }
16124
16125 static int
16126 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16127 {
16128   unformat_input_t *input = vam->input;
16129   vl_api_gpe_add_del_iface_t *mp;
16130   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16131   u32 dp_table = 0, vni = 0;
16132   int ret;
16133
16134   /* Parse args required to build the message */
16135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16136     {
16137       if (unformat (input, "up"))
16138         {
16139           action_set = 1;
16140           is_add = 1;
16141         }
16142       else if (unformat (input, "down"))
16143         {
16144           action_set = 1;
16145           is_add = 0;
16146         }
16147       else if (unformat (input, "table_id %d", &dp_table))
16148         {
16149           dp_table_set = 1;
16150         }
16151       else if (unformat (input, "bd_id %d", &dp_table))
16152         {
16153           dp_table_set = 1;
16154           is_l2 = 1;
16155         }
16156       else if (unformat (input, "vni %d", &vni))
16157         {
16158           vni_set = 1;
16159         }
16160       else
16161         break;
16162     }
16163
16164   if (action_set == 0)
16165     {
16166       errmsg ("Action not set");
16167       return -99;
16168     }
16169   if (dp_table_set == 0 || vni_set == 0)
16170     {
16171       errmsg ("vni and dp_table must be set");
16172       return -99;
16173     }
16174
16175   /* Construct the API message */
16176   M (GPE_ADD_DEL_IFACE, mp);
16177
16178   mp->is_add = is_add;
16179   mp->dp_table = clib_host_to_net_u32 (dp_table);
16180   mp->is_l2 = is_l2;
16181   mp->vni = clib_host_to_net_u32 (vni);
16182
16183   /* send it... */
16184   S (mp);
16185
16186   /* Wait for a reply... */
16187   W (ret);
16188   return ret;
16189 }
16190
16191 static int
16192 api_one_map_register_fallback_threshold (vat_main_t * vam)
16193 {
16194   unformat_input_t *input = vam->input;
16195   vl_api_one_map_register_fallback_threshold_t *mp;
16196   u32 value = 0;
16197   u8 is_set = 0;
16198   int ret;
16199
16200   /* Parse args required to build the message */
16201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16202     {
16203       if (unformat (input, "%u", &value))
16204         is_set = 1;
16205       else
16206         {
16207           clib_warning ("parse error '%U'", format_unformat_error, input);
16208           return -99;
16209         }
16210     }
16211
16212   if (!is_set)
16213     {
16214       errmsg ("fallback threshold value is missing!");
16215       return -99;
16216     }
16217
16218   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16219   mp->value = clib_host_to_net_u32 (value);
16220
16221   /* send it... */
16222   S (mp);
16223
16224   /* Wait for a reply... */
16225   W (ret);
16226   return ret;
16227 }
16228
16229 static int
16230 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16231 {
16232   vl_api_show_one_map_register_fallback_threshold_t *mp;
16233   int ret;
16234
16235   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16236
16237   /* send it... */
16238   S (mp);
16239
16240   /* Wait for a reply... */
16241   W (ret);
16242   return ret;
16243 }
16244
16245 uword
16246 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16247 {
16248   u32 *proto = va_arg (*args, u32 *);
16249
16250   if (unformat (input, "udp"))
16251     *proto = 1;
16252   else if (unformat (input, "api"))
16253     *proto = 2;
16254   else
16255     return 0;
16256
16257   return 1;
16258 }
16259
16260 static int
16261 api_one_set_transport_protocol (vat_main_t * vam)
16262 {
16263   unformat_input_t *input = vam->input;
16264   vl_api_one_set_transport_protocol_t *mp;
16265   u8 is_set = 0;
16266   u32 protocol = 0;
16267   int ret;
16268
16269   /* Parse args required to build the message */
16270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16271     {
16272       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16273         is_set = 1;
16274       else
16275         {
16276           clib_warning ("parse error '%U'", format_unformat_error, input);
16277           return -99;
16278         }
16279     }
16280
16281   if (!is_set)
16282     {
16283       errmsg ("Transport protocol missing!");
16284       return -99;
16285     }
16286
16287   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16288   mp->protocol = (u8) protocol;
16289
16290   /* send it... */
16291   S (mp);
16292
16293   /* Wait for a reply... */
16294   W (ret);
16295   return ret;
16296 }
16297
16298 static int
16299 api_one_get_transport_protocol (vat_main_t * vam)
16300 {
16301   vl_api_one_get_transport_protocol_t *mp;
16302   int ret;
16303
16304   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16305
16306   /* send it... */
16307   S (mp);
16308
16309   /* Wait for a reply... */
16310   W (ret);
16311   return ret;
16312 }
16313
16314 static int
16315 api_one_map_register_set_ttl (vat_main_t * vam)
16316 {
16317   unformat_input_t *input = vam->input;
16318   vl_api_one_map_register_set_ttl_t *mp;
16319   u32 ttl = 0;
16320   u8 is_set = 0;
16321   int ret;
16322
16323   /* Parse args required to build the message */
16324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16325     {
16326       if (unformat (input, "%u", &ttl))
16327         is_set = 1;
16328       else
16329         {
16330           clib_warning ("parse error '%U'", format_unformat_error, input);
16331           return -99;
16332         }
16333     }
16334
16335   if (!is_set)
16336     {
16337       errmsg ("TTL value missing!");
16338       return -99;
16339     }
16340
16341   M (ONE_MAP_REGISTER_SET_TTL, mp);
16342   mp->ttl = clib_host_to_net_u32 (ttl);
16343
16344   /* send it... */
16345   S (mp);
16346
16347   /* Wait for a reply... */
16348   W (ret);
16349   return ret;
16350 }
16351
16352 static int
16353 api_show_one_map_register_ttl (vat_main_t * vam)
16354 {
16355   vl_api_show_one_map_register_ttl_t *mp;
16356   int ret;
16357
16358   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16359
16360   /* send it... */
16361   S (mp);
16362
16363   /* Wait for a reply... */
16364   W (ret);
16365   return ret;
16366 }
16367
16368 /**
16369  * Add/del map request itr rlocs from ONE control plane and updates
16370  *
16371  * @param vam vpp API test context
16372  * @return return code
16373  */
16374 static int
16375 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16376 {
16377   unformat_input_t *input = vam->input;
16378   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16379   u8 *locator_set_name = 0;
16380   u8 locator_set_name_set = 0;
16381   u8 is_add = 1;
16382   int ret;
16383
16384   /* Parse args required to build the message */
16385   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16386     {
16387       if (unformat (input, "del"))
16388         {
16389           is_add = 0;
16390         }
16391       else if (unformat (input, "%_%v%_", &locator_set_name))
16392         {
16393           locator_set_name_set = 1;
16394         }
16395       else
16396         {
16397           clib_warning ("parse error '%U'", format_unformat_error, input);
16398           return -99;
16399         }
16400     }
16401
16402   if (is_add && !locator_set_name_set)
16403     {
16404       errmsg ("itr-rloc is not set!");
16405       return -99;
16406     }
16407
16408   if (is_add && vec_len (locator_set_name) > 64)
16409     {
16410       errmsg ("itr-rloc locator-set name too long");
16411       vec_free (locator_set_name);
16412       return -99;
16413     }
16414
16415   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16416   mp->is_add = is_add;
16417   if (is_add)
16418     {
16419       clib_memcpy (mp->locator_set_name, locator_set_name,
16420                    vec_len (locator_set_name));
16421     }
16422   else
16423     {
16424       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16425     }
16426   vec_free (locator_set_name);
16427
16428   /* send it... */
16429   S (mp);
16430
16431   /* Wait for a reply... */
16432   W (ret);
16433   return ret;
16434 }
16435
16436 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16437
16438 static int
16439 api_one_locator_dump (vat_main_t * vam)
16440 {
16441   unformat_input_t *input = vam->input;
16442   vl_api_one_locator_dump_t *mp;
16443   vl_api_control_ping_t *mp_ping;
16444   u8 is_index_set = 0, is_name_set = 0;
16445   u8 *ls_name = 0;
16446   u32 ls_index = ~0;
16447   int ret;
16448
16449   /* Parse args required to build the message */
16450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16451     {
16452       if (unformat (input, "ls_name %_%v%_", &ls_name))
16453         {
16454           is_name_set = 1;
16455         }
16456       else if (unformat (input, "ls_index %d", &ls_index))
16457         {
16458           is_index_set = 1;
16459         }
16460       else
16461         {
16462           errmsg ("parse error '%U'", format_unformat_error, input);
16463           return -99;
16464         }
16465     }
16466
16467   if (!is_index_set && !is_name_set)
16468     {
16469       errmsg ("error: expected one of index or name!");
16470       return -99;
16471     }
16472
16473   if (is_index_set && is_name_set)
16474     {
16475       errmsg ("error: only one param expected!");
16476       return -99;
16477     }
16478
16479   if (vec_len (ls_name) > 62)
16480     {
16481       errmsg ("error: locator set name too long!");
16482       return -99;
16483     }
16484
16485   if (!vam->json_output)
16486     {
16487       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16488     }
16489
16490   M (ONE_LOCATOR_DUMP, mp);
16491   mp->is_index_set = is_index_set;
16492
16493   if (is_index_set)
16494     mp->ls_index = clib_host_to_net_u32 (ls_index);
16495   else
16496     {
16497       vec_add1 (ls_name, 0);
16498       strncpy ((char *) mp->ls_name, (char *) ls_name,
16499                sizeof (mp->ls_name) - 1);
16500     }
16501
16502   /* send it... */
16503   S (mp);
16504
16505   /* Use a control ping for synchronization */
16506   MPING (CONTROL_PING, mp_ping);
16507   S (mp_ping);
16508
16509   /* Wait for a reply... */
16510   W (ret);
16511   return ret;
16512 }
16513
16514 #define api_lisp_locator_dump api_one_locator_dump
16515
16516 static int
16517 api_one_locator_set_dump (vat_main_t * vam)
16518 {
16519   vl_api_one_locator_set_dump_t *mp;
16520   vl_api_control_ping_t *mp_ping;
16521   unformat_input_t *input = vam->input;
16522   u8 filter = 0;
16523   int ret;
16524
16525   /* Parse args required to build the message */
16526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16527     {
16528       if (unformat (input, "local"))
16529         {
16530           filter = 1;
16531         }
16532       else if (unformat (input, "remote"))
16533         {
16534           filter = 2;
16535         }
16536       else
16537         {
16538           errmsg ("parse error '%U'", format_unformat_error, input);
16539           return -99;
16540         }
16541     }
16542
16543   if (!vam->json_output)
16544     {
16545       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16546     }
16547
16548   M (ONE_LOCATOR_SET_DUMP, mp);
16549
16550   mp->filter = filter;
16551
16552   /* send it... */
16553   S (mp);
16554
16555   /* Use a control ping for synchronization */
16556   MPING (CONTROL_PING, mp_ping);
16557   S (mp_ping);
16558
16559   /* Wait for a reply... */
16560   W (ret);
16561   return ret;
16562 }
16563
16564 #define api_lisp_locator_set_dump api_one_locator_set_dump
16565
16566 static int
16567 api_one_eid_table_map_dump (vat_main_t * vam)
16568 {
16569   u8 is_l2 = 0;
16570   u8 mode_set = 0;
16571   unformat_input_t *input = vam->input;
16572   vl_api_one_eid_table_map_dump_t *mp;
16573   vl_api_control_ping_t *mp_ping;
16574   int ret;
16575
16576   /* Parse args required to build the message */
16577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16578     {
16579       if (unformat (input, "l2"))
16580         {
16581           is_l2 = 1;
16582           mode_set = 1;
16583         }
16584       else if (unformat (input, "l3"))
16585         {
16586           is_l2 = 0;
16587           mode_set = 1;
16588         }
16589       else
16590         {
16591           errmsg ("parse error '%U'", format_unformat_error, input);
16592           return -99;
16593         }
16594     }
16595
16596   if (!mode_set)
16597     {
16598       errmsg ("expected one of 'l2' or 'l3' parameter!");
16599       return -99;
16600     }
16601
16602   if (!vam->json_output)
16603     {
16604       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16605     }
16606
16607   M (ONE_EID_TABLE_MAP_DUMP, mp);
16608   mp->is_l2 = is_l2;
16609
16610   /* send it... */
16611   S (mp);
16612
16613   /* Use a control ping for synchronization */
16614   MPING (CONTROL_PING, mp_ping);
16615   S (mp_ping);
16616
16617   /* Wait for a reply... */
16618   W (ret);
16619   return ret;
16620 }
16621
16622 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16623
16624 static int
16625 api_one_eid_table_vni_dump (vat_main_t * vam)
16626 {
16627   vl_api_one_eid_table_vni_dump_t *mp;
16628   vl_api_control_ping_t *mp_ping;
16629   int ret;
16630
16631   if (!vam->json_output)
16632     {
16633       print (vam->ofp, "VNI");
16634     }
16635
16636   M (ONE_EID_TABLE_VNI_DUMP, mp);
16637
16638   /* send it... */
16639   S (mp);
16640
16641   /* Use a control ping for synchronization */
16642   MPING (CONTROL_PING, mp_ping);
16643   S (mp_ping);
16644
16645   /* Wait for a reply... */
16646   W (ret);
16647   return ret;
16648 }
16649
16650 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16651
16652 static int
16653 api_one_eid_table_dump (vat_main_t * vam)
16654 {
16655   unformat_input_t *i = vam->input;
16656   vl_api_one_eid_table_dump_t *mp;
16657   vl_api_control_ping_t *mp_ping;
16658   struct in_addr ip4;
16659   struct in6_addr ip6;
16660   u8 mac[6];
16661   u8 eid_type = ~0, eid_set = 0;
16662   u32 prefix_length = ~0, t, vni = 0;
16663   u8 filter = 0;
16664   int ret;
16665   lisp_nsh_api_t nsh;
16666
16667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16668     {
16669       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16670         {
16671           eid_set = 1;
16672           eid_type = 0;
16673           prefix_length = t;
16674         }
16675       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16676         {
16677           eid_set = 1;
16678           eid_type = 1;
16679           prefix_length = t;
16680         }
16681       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16682         {
16683           eid_set = 1;
16684           eid_type = 2;
16685         }
16686       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16687         {
16688           eid_set = 1;
16689           eid_type = 3;
16690         }
16691       else if (unformat (i, "vni %d", &t))
16692         {
16693           vni = t;
16694         }
16695       else if (unformat (i, "local"))
16696         {
16697           filter = 1;
16698         }
16699       else if (unformat (i, "remote"))
16700         {
16701           filter = 2;
16702         }
16703       else
16704         {
16705           errmsg ("parse error '%U'", format_unformat_error, i);
16706           return -99;
16707         }
16708     }
16709
16710   if (!vam->json_output)
16711     {
16712       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16713              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16714     }
16715
16716   M (ONE_EID_TABLE_DUMP, mp);
16717
16718   mp->filter = filter;
16719   if (eid_set)
16720     {
16721       mp->eid_set = 1;
16722       mp->vni = htonl (vni);
16723       mp->eid_type = eid_type;
16724       switch (eid_type)
16725         {
16726         case 0:
16727           mp->prefix_length = prefix_length;
16728           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16729           break;
16730         case 1:
16731           mp->prefix_length = prefix_length;
16732           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16733           break;
16734         case 2:
16735           clib_memcpy (mp->eid, mac, sizeof (mac));
16736           break;
16737         case 3:
16738           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16739           break;
16740         default:
16741           errmsg ("unknown EID type %d!", eid_type);
16742           return -99;
16743         }
16744     }
16745
16746   /* send it... */
16747   S (mp);
16748
16749   /* Use a control ping for synchronization */
16750   MPING (CONTROL_PING, mp_ping);
16751   S (mp_ping);
16752
16753   /* Wait for a reply... */
16754   W (ret);
16755   return ret;
16756 }
16757
16758 #define api_lisp_eid_table_dump api_one_eid_table_dump
16759
16760 static int
16761 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16762 {
16763   unformat_input_t *i = vam->input;
16764   vl_api_gpe_fwd_entries_get_t *mp;
16765   u8 vni_set = 0;
16766   u32 vni = ~0;
16767   int ret;
16768
16769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16770     {
16771       if (unformat (i, "vni %d", &vni))
16772         {
16773           vni_set = 1;
16774         }
16775       else
16776         {
16777           errmsg ("parse error '%U'", format_unformat_error, i);
16778           return -99;
16779         }
16780     }
16781
16782   if (!vni_set)
16783     {
16784       errmsg ("vni not set!");
16785       return -99;
16786     }
16787
16788   if (!vam->json_output)
16789     {
16790       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16791              "leid", "reid");
16792     }
16793
16794   M (GPE_FWD_ENTRIES_GET, mp);
16795   mp->vni = clib_host_to_net_u32 (vni);
16796
16797   /* send it... */
16798   S (mp);
16799
16800   /* Wait for a reply... */
16801   W (ret);
16802   return ret;
16803 }
16804
16805 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16806 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16807 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16808 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16809 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16810 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16811 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16812 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16813
16814 static int
16815 api_one_adjacencies_get (vat_main_t * vam)
16816 {
16817   unformat_input_t *i = vam->input;
16818   vl_api_one_adjacencies_get_t *mp;
16819   u8 vni_set = 0;
16820   u32 vni = ~0;
16821   int ret;
16822
16823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16824     {
16825       if (unformat (i, "vni %d", &vni))
16826         {
16827           vni_set = 1;
16828         }
16829       else
16830         {
16831           errmsg ("parse error '%U'", format_unformat_error, i);
16832           return -99;
16833         }
16834     }
16835
16836   if (!vni_set)
16837     {
16838       errmsg ("vni not set!");
16839       return -99;
16840     }
16841
16842   if (!vam->json_output)
16843     {
16844       print (vam->ofp, "%s %40s", "leid", "reid");
16845     }
16846
16847   M (ONE_ADJACENCIES_GET, mp);
16848   mp->vni = clib_host_to_net_u32 (vni);
16849
16850   /* send it... */
16851   S (mp);
16852
16853   /* Wait for a reply... */
16854   W (ret);
16855   return ret;
16856 }
16857
16858 #define api_lisp_adjacencies_get api_one_adjacencies_get
16859
16860 static int
16861 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16862 {
16863   unformat_input_t *i = vam->input;
16864   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16865   int ret;
16866   u8 ip_family_set = 0, is_ip4 = 1;
16867
16868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16869     {
16870       if (unformat (i, "ip4"))
16871         {
16872           ip_family_set = 1;
16873           is_ip4 = 1;
16874         }
16875       else if (unformat (i, "ip6"))
16876         {
16877           ip_family_set = 1;
16878           is_ip4 = 0;
16879         }
16880       else
16881         {
16882           errmsg ("parse error '%U'", format_unformat_error, i);
16883           return -99;
16884         }
16885     }
16886
16887   if (!ip_family_set)
16888     {
16889       errmsg ("ip family not set!");
16890       return -99;
16891     }
16892
16893   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16894   mp->is_ip4 = is_ip4;
16895
16896   /* send it... */
16897   S (mp);
16898
16899   /* Wait for a reply... */
16900   W (ret);
16901   return ret;
16902 }
16903
16904 static int
16905 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16906 {
16907   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16908   int ret;
16909
16910   if (!vam->json_output)
16911     {
16912       print (vam->ofp, "VNIs");
16913     }
16914
16915   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16916
16917   /* send it... */
16918   S (mp);
16919
16920   /* Wait for a reply... */
16921   W (ret);
16922   return ret;
16923 }
16924
16925 static int
16926 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16927 {
16928   unformat_input_t *i = vam->input;
16929   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16930   int ret = 0;
16931   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16932   struct in_addr ip4;
16933   struct in6_addr ip6;
16934   u32 table_id = 0, nh_sw_if_index = ~0;
16935
16936   clib_memset (&ip4, 0, sizeof (ip4));
16937   clib_memset (&ip6, 0, sizeof (ip6));
16938
16939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16940     {
16941       if (unformat (i, "del"))
16942         is_add = 0;
16943       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16944                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16945         {
16946           ip_set = 1;
16947           is_ip4 = 1;
16948         }
16949       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16950                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16951         {
16952           ip_set = 1;
16953           is_ip4 = 0;
16954         }
16955       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16956         {
16957           ip_set = 1;
16958           is_ip4 = 1;
16959           nh_sw_if_index = ~0;
16960         }
16961       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16962         {
16963           ip_set = 1;
16964           is_ip4 = 0;
16965           nh_sw_if_index = ~0;
16966         }
16967       else if (unformat (i, "table %d", &table_id))
16968         ;
16969       else
16970         {
16971           errmsg ("parse error '%U'", format_unformat_error, i);
16972           return -99;
16973         }
16974     }
16975
16976   if (!ip_set)
16977     {
16978       errmsg ("nh addr not set!");
16979       return -99;
16980     }
16981
16982   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16983   mp->is_add = is_add;
16984   mp->table_id = clib_host_to_net_u32 (table_id);
16985   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16986   mp->is_ip4 = is_ip4;
16987   if (is_ip4)
16988     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16989   else
16990     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16991
16992   /* send it... */
16993   S (mp);
16994
16995   /* Wait for a reply... */
16996   W (ret);
16997   return ret;
16998 }
16999
17000 static int
17001 api_one_map_server_dump (vat_main_t * vam)
17002 {
17003   vl_api_one_map_server_dump_t *mp;
17004   vl_api_control_ping_t *mp_ping;
17005   int ret;
17006
17007   if (!vam->json_output)
17008     {
17009       print (vam->ofp, "%=20s", "Map server");
17010     }
17011
17012   M (ONE_MAP_SERVER_DUMP, mp);
17013   /* send it... */
17014   S (mp);
17015
17016   /* Use a control ping for synchronization */
17017   MPING (CONTROL_PING, mp_ping);
17018   S (mp_ping);
17019
17020   /* Wait for a reply... */
17021   W (ret);
17022   return ret;
17023 }
17024
17025 #define api_lisp_map_server_dump api_one_map_server_dump
17026
17027 static int
17028 api_one_map_resolver_dump (vat_main_t * vam)
17029 {
17030   vl_api_one_map_resolver_dump_t *mp;
17031   vl_api_control_ping_t *mp_ping;
17032   int ret;
17033
17034   if (!vam->json_output)
17035     {
17036       print (vam->ofp, "%=20s", "Map resolver");
17037     }
17038
17039   M (ONE_MAP_RESOLVER_DUMP, mp);
17040   /* send it... */
17041   S (mp);
17042
17043   /* Use a control ping for synchronization */
17044   MPING (CONTROL_PING, mp_ping);
17045   S (mp_ping);
17046
17047   /* Wait for a reply... */
17048   W (ret);
17049   return ret;
17050 }
17051
17052 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17053
17054 static int
17055 api_one_stats_flush (vat_main_t * vam)
17056 {
17057   vl_api_one_stats_flush_t *mp;
17058   int ret = 0;
17059
17060   M (ONE_STATS_FLUSH, mp);
17061   S (mp);
17062   W (ret);
17063   return ret;
17064 }
17065
17066 static int
17067 api_one_stats_dump (vat_main_t * vam)
17068 {
17069   vl_api_one_stats_dump_t *mp;
17070   vl_api_control_ping_t *mp_ping;
17071   int ret;
17072
17073   M (ONE_STATS_DUMP, mp);
17074   /* send it... */
17075   S (mp);
17076
17077   /* Use a control ping for synchronization */
17078   MPING (CONTROL_PING, mp_ping);
17079   S (mp_ping);
17080
17081   /* Wait for a reply... */
17082   W (ret);
17083   return ret;
17084 }
17085
17086 static int
17087 api_show_one_status (vat_main_t * vam)
17088 {
17089   vl_api_show_one_status_t *mp;
17090   int ret;
17091
17092   if (!vam->json_output)
17093     {
17094       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17095     }
17096
17097   M (SHOW_ONE_STATUS, mp);
17098   /* send it... */
17099   S (mp);
17100   /* Wait for a reply... */
17101   W (ret);
17102   return ret;
17103 }
17104
17105 #define api_show_lisp_status api_show_one_status
17106
17107 static int
17108 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17109 {
17110   vl_api_gpe_fwd_entry_path_dump_t *mp;
17111   vl_api_control_ping_t *mp_ping;
17112   unformat_input_t *i = vam->input;
17113   u32 fwd_entry_index = ~0;
17114   int ret;
17115
17116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17117     {
17118       if (unformat (i, "index %d", &fwd_entry_index))
17119         ;
17120       else
17121         break;
17122     }
17123
17124   if (~0 == fwd_entry_index)
17125     {
17126       errmsg ("no index specified!");
17127       return -99;
17128     }
17129
17130   if (!vam->json_output)
17131     {
17132       print (vam->ofp, "first line");
17133     }
17134
17135   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17136
17137   /* send it... */
17138   S (mp);
17139   /* Use a control ping for synchronization */
17140   MPING (CONTROL_PING, mp_ping);
17141   S (mp_ping);
17142
17143   /* Wait for a reply... */
17144   W (ret);
17145   return ret;
17146 }
17147
17148 static int
17149 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17150 {
17151   vl_api_one_get_map_request_itr_rlocs_t *mp;
17152   int ret;
17153
17154   if (!vam->json_output)
17155     {
17156       print (vam->ofp, "%=20s", "itr-rlocs:");
17157     }
17158
17159   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17160   /* send it... */
17161   S (mp);
17162   /* Wait for a reply... */
17163   W (ret);
17164   return ret;
17165 }
17166
17167 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17168
17169 static int
17170 api_af_packet_create (vat_main_t * vam)
17171 {
17172   unformat_input_t *i = vam->input;
17173   vl_api_af_packet_create_t *mp;
17174   u8 *host_if_name = 0;
17175   u8 hw_addr[6];
17176   u8 random_hw_addr = 1;
17177   int ret;
17178
17179   clib_memset (hw_addr, 0, sizeof (hw_addr));
17180
17181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17182     {
17183       if (unformat (i, "name %s", &host_if_name))
17184         vec_add1 (host_if_name, 0);
17185       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17186         random_hw_addr = 0;
17187       else
17188         break;
17189     }
17190
17191   if (!vec_len (host_if_name))
17192     {
17193       errmsg ("host-interface name must be specified");
17194       return -99;
17195     }
17196
17197   if (vec_len (host_if_name) > 64)
17198     {
17199       errmsg ("host-interface name too long");
17200       return -99;
17201     }
17202
17203   M (AF_PACKET_CREATE, mp);
17204
17205   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17206   clib_memcpy (mp->hw_addr, hw_addr, 6);
17207   mp->use_random_hw_addr = random_hw_addr;
17208   vec_free (host_if_name);
17209
17210   S (mp);
17211
17212   /* *INDENT-OFF* */
17213   W2 (ret,
17214       ({
17215         if (ret == 0)
17216           fprintf (vam->ofp ? vam->ofp : stderr,
17217                    " new sw_if_index = %d\n", vam->sw_if_index);
17218       }));
17219   /* *INDENT-ON* */
17220   return ret;
17221 }
17222
17223 static int
17224 api_af_packet_delete (vat_main_t * vam)
17225 {
17226   unformat_input_t *i = vam->input;
17227   vl_api_af_packet_delete_t *mp;
17228   u8 *host_if_name = 0;
17229   int ret;
17230
17231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17232     {
17233       if (unformat (i, "name %s", &host_if_name))
17234         vec_add1 (host_if_name, 0);
17235       else
17236         break;
17237     }
17238
17239   if (!vec_len (host_if_name))
17240     {
17241       errmsg ("host-interface name must be specified");
17242       return -99;
17243     }
17244
17245   if (vec_len (host_if_name) > 64)
17246     {
17247       errmsg ("host-interface name too long");
17248       return -99;
17249     }
17250
17251   M (AF_PACKET_DELETE, mp);
17252
17253   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17254   vec_free (host_if_name);
17255
17256   S (mp);
17257   W (ret);
17258   return ret;
17259 }
17260
17261 static void vl_api_af_packet_details_t_handler
17262   (vl_api_af_packet_details_t * mp)
17263 {
17264   vat_main_t *vam = &vat_main;
17265
17266   print (vam->ofp, "%-16s %d",
17267          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17268 }
17269
17270 static void vl_api_af_packet_details_t_handler_json
17271   (vl_api_af_packet_details_t * mp)
17272 {
17273   vat_main_t *vam = &vat_main;
17274   vat_json_node_t *node = NULL;
17275
17276   if (VAT_JSON_ARRAY != vam->json_tree.type)
17277     {
17278       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17279       vat_json_init_array (&vam->json_tree);
17280     }
17281   node = vat_json_array_add (&vam->json_tree);
17282
17283   vat_json_init_object (node);
17284   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17285   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17286 }
17287
17288 static int
17289 api_af_packet_dump (vat_main_t * vam)
17290 {
17291   vl_api_af_packet_dump_t *mp;
17292   vl_api_control_ping_t *mp_ping;
17293   int ret;
17294
17295   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17296   /* Get list of tap interfaces */
17297   M (AF_PACKET_DUMP, mp);
17298   S (mp);
17299
17300   /* Use a control ping for synchronization */
17301   MPING (CONTROL_PING, mp_ping);
17302   S (mp_ping);
17303
17304   W (ret);
17305   return ret;
17306 }
17307
17308 static int
17309 api_policer_add_del (vat_main_t * vam)
17310 {
17311   unformat_input_t *i = vam->input;
17312   vl_api_policer_add_del_t *mp;
17313   u8 is_add = 1;
17314   u8 *name = 0;
17315   u32 cir = 0;
17316   u32 eir = 0;
17317   u64 cb = 0;
17318   u64 eb = 0;
17319   u8 rate_type = 0;
17320   u8 round_type = 0;
17321   u8 type = 0;
17322   u8 color_aware = 0;
17323   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17324   int ret;
17325
17326   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17327   conform_action.dscp = 0;
17328   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17329   exceed_action.dscp = 0;
17330   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17331   violate_action.dscp = 0;
17332
17333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17334     {
17335       if (unformat (i, "del"))
17336         is_add = 0;
17337       else if (unformat (i, "name %s", &name))
17338         vec_add1 (name, 0);
17339       else if (unformat (i, "cir %u", &cir))
17340         ;
17341       else if (unformat (i, "eir %u", &eir))
17342         ;
17343       else if (unformat (i, "cb %u", &cb))
17344         ;
17345       else if (unformat (i, "eb %u", &eb))
17346         ;
17347       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17348                          &rate_type))
17349         ;
17350       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17351                          &round_type))
17352         ;
17353       else if (unformat (i, "type %U", unformat_policer_type, &type))
17354         ;
17355       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17356                          &conform_action))
17357         ;
17358       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17359                          &exceed_action))
17360         ;
17361       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17362                          &violate_action))
17363         ;
17364       else if (unformat (i, "color-aware"))
17365         color_aware = 1;
17366       else
17367         break;
17368     }
17369
17370   if (!vec_len (name))
17371     {
17372       errmsg ("policer name must be specified");
17373       return -99;
17374     }
17375
17376   if (vec_len (name) > 64)
17377     {
17378       errmsg ("policer name too long");
17379       return -99;
17380     }
17381
17382   M (POLICER_ADD_DEL, mp);
17383
17384   clib_memcpy (mp->name, name, vec_len (name));
17385   vec_free (name);
17386   mp->is_add = is_add;
17387   mp->cir = ntohl (cir);
17388   mp->eir = ntohl (eir);
17389   mp->cb = clib_net_to_host_u64 (cb);
17390   mp->eb = clib_net_to_host_u64 (eb);
17391   mp->rate_type = rate_type;
17392   mp->round_type = round_type;
17393   mp->type = type;
17394   mp->conform_action.type = conform_action.action_type;
17395   mp->conform_action.dscp = conform_action.dscp;
17396   mp->exceed_action.type = exceed_action.action_type;
17397   mp->exceed_action.dscp = exceed_action.dscp;
17398   mp->violate_action.type = violate_action.action_type;
17399   mp->violate_action.dscp = violate_action.dscp;
17400   mp->color_aware = color_aware;
17401
17402   S (mp);
17403   W (ret);
17404   return ret;
17405 }
17406
17407 static int
17408 api_policer_dump (vat_main_t * vam)
17409 {
17410   unformat_input_t *i = vam->input;
17411   vl_api_policer_dump_t *mp;
17412   vl_api_control_ping_t *mp_ping;
17413   u8 *match_name = 0;
17414   u8 match_name_valid = 0;
17415   int ret;
17416
17417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17418     {
17419       if (unformat (i, "name %s", &match_name))
17420         {
17421           vec_add1 (match_name, 0);
17422           match_name_valid = 1;
17423         }
17424       else
17425         break;
17426     }
17427
17428   M (POLICER_DUMP, mp);
17429   mp->match_name_valid = match_name_valid;
17430   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17431   vec_free (match_name);
17432   /* send it... */
17433   S (mp);
17434
17435   /* Use a control ping for synchronization */
17436   MPING (CONTROL_PING, mp_ping);
17437   S (mp_ping);
17438
17439   /* Wait for a reply... */
17440   W (ret);
17441   return ret;
17442 }
17443
17444 static int
17445 api_policer_classify_set_interface (vat_main_t * vam)
17446 {
17447   unformat_input_t *i = vam->input;
17448   vl_api_policer_classify_set_interface_t *mp;
17449   u32 sw_if_index;
17450   int sw_if_index_set;
17451   u32 ip4_table_index = ~0;
17452   u32 ip6_table_index = ~0;
17453   u32 l2_table_index = ~0;
17454   u8 is_add = 1;
17455   int ret;
17456
17457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17458     {
17459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17460         sw_if_index_set = 1;
17461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17462         sw_if_index_set = 1;
17463       else if (unformat (i, "del"))
17464         is_add = 0;
17465       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17466         ;
17467       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17468         ;
17469       else if (unformat (i, "l2-table %d", &l2_table_index))
17470         ;
17471       else
17472         {
17473           clib_warning ("parse error '%U'", format_unformat_error, i);
17474           return -99;
17475         }
17476     }
17477
17478   if (sw_if_index_set == 0)
17479     {
17480       errmsg ("missing interface name or sw_if_index");
17481       return -99;
17482     }
17483
17484   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17485
17486   mp->sw_if_index = ntohl (sw_if_index);
17487   mp->ip4_table_index = ntohl (ip4_table_index);
17488   mp->ip6_table_index = ntohl (ip6_table_index);
17489   mp->l2_table_index = ntohl (l2_table_index);
17490   mp->is_add = is_add;
17491
17492   S (mp);
17493   W (ret);
17494   return ret;
17495 }
17496
17497 static int
17498 api_policer_classify_dump (vat_main_t * vam)
17499 {
17500   unformat_input_t *i = vam->input;
17501   vl_api_policer_classify_dump_t *mp;
17502   vl_api_control_ping_t *mp_ping;
17503   u8 type = POLICER_CLASSIFY_N_TABLES;
17504   int ret;
17505
17506   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17507     ;
17508   else
17509     {
17510       errmsg ("classify table type must be specified");
17511       return -99;
17512     }
17513
17514   if (!vam->json_output)
17515     {
17516       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17517     }
17518
17519   M (POLICER_CLASSIFY_DUMP, mp);
17520   mp->type = type;
17521   /* send it... */
17522   S (mp);
17523
17524   /* Use a control ping for synchronization */
17525   MPING (CONTROL_PING, mp_ping);
17526   S (mp_ping);
17527
17528   /* Wait for a reply... */
17529   W (ret);
17530   return ret;
17531 }
17532
17533 static u8 *
17534 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17535 {
17536   vl_api_fib_path_nh_proto_t proto =
17537     va_arg (*args, vl_api_fib_path_nh_proto_t);
17538
17539   switch (proto)
17540     {
17541     case FIB_API_PATH_NH_PROTO_IP4:
17542       s = format (s, "ip4");
17543       break;
17544     case FIB_API_PATH_NH_PROTO_IP6:
17545       s = format (s, "ip6");
17546       break;
17547     case FIB_API_PATH_NH_PROTO_MPLS:
17548       s = format (s, "mpls");
17549       break;
17550     case FIB_API_PATH_NH_PROTO_BIER:
17551       s = format (s, "bier");
17552       break;
17553     case FIB_API_PATH_NH_PROTO_ETHERNET:
17554       s = format (s, "ethernet");
17555       break;
17556     }
17557
17558   return (s);
17559 }
17560
17561 static u8 *
17562 format_vl_api_ip_address_union (u8 * s, va_list * args)
17563 {
17564   vl_api_address_family_t af = va_arg (*args, int);
17565   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17566
17567   switch (af)
17568     {
17569     case ADDRESS_IP4:
17570       s = format (s, "%U", format_ip4_address, u->ip4);
17571       break;
17572     case ADDRESS_IP6:
17573       s = format (s, "%U", format_ip6_address, u->ip6);
17574       break;
17575     }
17576   return (s);
17577 }
17578
17579 static u8 *
17580 format_vl_api_fib_path_type (u8 * s, va_list * args)
17581 {
17582   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17583
17584   switch (t)
17585     {
17586     case FIB_API_PATH_TYPE_NORMAL:
17587       s = format (s, "normal");
17588       break;
17589     case FIB_API_PATH_TYPE_LOCAL:
17590       s = format (s, "local");
17591       break;
17592     case FIB_API_PATH_TYPE_DROP:
17593       s = format (s, "drop");
17594       break;
17595     case FIB_API_PATH_TYPE_UDP_ENCAP:
17596       s = format (s, "udp-encap");
17597       break;
17598     case FIB_API_PATH_TYPE_BIER_IMP:
17599       s = format (s, "bier-imp");
17600       break;
17601     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17602       s = format (s, "unreach");
17603       break;
17604     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17605       s = format (s, "prohibit");
17606       break;
17607     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17608       s = format (s, "src-lookup");
17609       break;
17610     case FIB_API_PATH_TYPE_DVR:
17611       s = format (s, "dvr");
17612       break;
17613     case FIB_API_PATH_TYPE_INTERFACE_RX:
17614       s = format (s, "interface-rx");
17615       break;
17616     case FIB_API_PATH_TYPE_CLASSIFY:
17617       s = format (s, "classify");
17618       break;
17619     }
17620
17621   return (s);
17622 }
17623
17624 static void
17625 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17626 {
17627   print (vam->ofp,
17628          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17629          ntohl (fp->weight), ntohl (fp->sw_if_index),
17630          format_vl_api_fib_path_type, fp->type,
17631          format_fib_api_path_nh_proto, fp->proto,
17632          format_vl_api_ip_address_union, &fp->nh.address);
17633 }
17634
17635 static void
17636 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17637                                  vl_api_fib_path_t * fp)
17638 {
17639   struct in_addr ip4;
17640   struct in6_addr ip6;
17641
17642   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17643   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17644   vat_json_object_add_uint (node, "type", fp->type);
17645   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17646   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17647     {
17648       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17649       vat_json_object_add_ip4 (node, "next_hop", ip4);
17650     }
17651   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17652     {
17653       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17654       vat_json_object_add_ip6 (node, "next_hop", ip6);
17655     }
17656 }
17657
17658 static void
17659 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17660 {
17661   vat_main_t *vam = &vat_main;
17662   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17663   vl_api_fib_path_t *fp;
17664   i32 i;
17665
17666   print (vam->ofp, "sw_if_index %d via:",
17667          ntohl (mp->mt_tunnel.mt_sw_if_index));
17668   fp = mp->mt_tunnel.mt_paths;
17669   for (i = 0; i < count; i++)
17670     {
17671       vl_api_fib_path_print (vam, fp);
17672       fp++;
17673     }
17674
17675   print (vam->ofp, "");
17676 }
17677
17678 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17679 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17680
17681 static void
17682 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17683 {
17684   vat_main_t *vam = &vat_main;
17685   vat_json_node_t *node = NULL;
17686   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17687   vl_api_fib_path_t *fp;
17688   i32 i;
17689
17690   if (VAT_JSON_ARRAY != vam->json_tree.type)
17691     {
17692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17693       vat_json_init_array (&vam->json_tree);
17694     }
17695   node = vat_json_array_add (&vam->json_tree);
17696
17697   vat_json_init_object (node);
17698   vat_json_object_add_uint (node, "sw_if_index",
17699                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17700
17701   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17702
17703   fp = mp->mt_tunnel.mt_paths;
17704   for (i = 0; i < count; i++)
17705     {
17706       vl_api_mpls_fib_path_json_print (node, fp);
17707       fp++;
17708     }
17709 }
17710
17711 static int
17712 api_mpls_tunnel_dump (vat_main_t * vam)
17713 {
17714   vl_api_mpls_tunnel_dump_t *mp;
17715   vl_api_control_ping_t *mp_ping;
17716   int ret;
17717
17718   M (MPLS_TUNNEL_DUMP, mp);
17719
17720   S (mp);
17721
17722   /* Use a control ping for synchronization */
17723   MPING (CONTROL_PING, mp_ping);
17724   S (mp_ping);
17725
17726   W (ret);
17727   return ret;
17728 }
17729
17730 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17731 #define vl_api_mpls_table_details_t_print vl_noop_handler
17732
17733
17734 static void
17735 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17736 {
17737   vat_main_t *vam = &vat_main;
17738
17739   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17740 }
17741
17742 static void vl_api_mpls_table_details_t_handler_json
17743   (vl_api_mpls_table_details_t * mp)
17744 {
17745   vat_main_t *vam = &vat_main;
17746   vat_json_node_t *node = NULL;
17747
17748   if (VAT_JSON_ARRAY != vam->json_tree.type)
17749     {
17750       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17751       vat_json_init_array (&vam->json_tree);
17752     }
17753   node = vat_json_array_add (&vam->json_tree);
17754
17755   vat_json_init_object (node);
17756   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17757 }
17758
17759 static int
17760 api_mpls_table_dump (vat_main_t * vam)
17761 {
17762   vl_api_mpls_table_dump_t *mp;
17763   vl_api_control_ping_t *mp_ping;
17764   int ret;
17765
17766   M (MPLS_TABLE_DUMP, mp);
17767   S (mp);
17768
17769   /* Use a control ping for synchronization */
17770   MPING (CONTROL_PING, mp_ping);
17771   S (mp_ping);
17772
17773   W (ret);
17774   return ret;
17775 }
17776
17777 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17778 #define vl_api_mpls_route_details_t_print vl_noop_handler
17779
17780 static void
17781 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17782 {
17783   vat_main_t *vam = &vat_main;
17784   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17785   vl_api_fib_path_t *fp;
17786   int i;
17787
17788   print (vam->ofp,
17789          "table-id %d, label %u, ess_bit %u",
17790          ntohl (mp->mr_route.mr_table_id),
17791          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17792   fp = mp->mr_route.mr_paths;
17793   for (i = 0; i < count; i++)
17794     {
17795       vl_api_fib_path_print (vam, fp);
17796       fp++;
17797     }
17798 }
17799
17800 static void vl_api_mpls_route_details_t_handler_json
17801   (vl_api_mpls_route_details_t * mp)
17802 {
17803   vat_main_t *vam = &vat_main;
17804   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17805   vat_json_node_t *node = NULL;
17806   vl_api_fib_path_t *fp;
17807   int i;
17808
17809   if (VAT_JSON_ARRAY != vam->json_tree.type)
17810     {
17811       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17812       vat_json_init_array (&vam->json_tree);
17813     }
17814   node = vat_json_array_add (&vam->json_tree);
17815
17816   vat_json_init_object (node);
17817   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17818   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17819   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17820   vat_json_object_add_uint (node, "path_count", count);
17821   fp = mp->mr_route.mr_paths;
17822   for (i = 0; i < count; i++)
17823     {
17824       vl_api_mpls_fib_path_json_print (node, fp);
17825       fp++;
17826     }
17827 }
17828
17829 static int
17830 api_mpls_route_dump (vat_main_t * vam)
17831 {
17832   unformat_input_t *input = vam->input;
17833   vl_api_mpls_route_dump_t *mp;
17834   vl_api_control_ping_t *mp_ping;
17835   u32 table_id;
17836   int ret;
17837
17838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17839     {
17840       if (unformat (input, "table_id %d", &table_id))
17841         ;
17842       else
17843         break;
17844     }
17845   if (table_id == ~0)
17846     {
17847       errmsg ("missing table id");
17848       return -99;
17849     }
17850
17851   M (MPLS_ROUTE_DUMP, mp);
17852
17853   mp->table.mt_table_id = ntohl (table_id);
17854   S (mp);
17855
17856   /* Use a control ping for synchronization */
17857   MPING (CONTROL_PING, mp_ping);
17858   S (mp_ping);
17859
17860   W (ret);
17861   return ret;
17862 }
17863
17864 #define vl_api_ip_table_details_t_endian vl_noop_handler
17865 #define vl_api_ip_table_details_t_print vl_noop_handler
17866
17867 static void
17868 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17869 {
17870   vat_main_t *vam = &vat_main;
17871
17872   print (vam->ofp,
17873          "%s; table-id %d, prefix %U/%d",
17874          mp->table.name, ntohl (mp->table.table_id));
17875 }
17876
17877
17878 static void vl_api_ip_table_details_t_handler_json
17879   (vl_api_ip_table_details_t * mp)
17880 {
17881   vat_main_t *vam = &vat_main;
17882   vat_json_node_t *node = NULL;
17883
17884   if (VAT_JSON_ARRAY != vam->json_tree.type)
17885     {
17886       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17887       vat_json_init_array (&vam->json_tree);
17888     }
17889   node = vat_json_array_add (&vam->json_tree);
17890
17891   vat_json_init_object (node);
17892   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17893 }
17894
17895 static int
17896 api_ip_table_dump (vat_main_t * vam)
17897 {
17898   vl_api_ip_table_dump_t *mp;
17899   vl_api_control_ping_t *mp_ping;
17900   int ret;
17901
17902   M (IP_TABLE_DUMP, mp);
17903   S (mp);
17904
17905   /* Use a control ping for synchronization */
17906   MPING (CONTROL_PING, mp_ping);
17907   S (mp_ping);
17908
17909   W (ret);
17910   return ret;
17911 }
17912
17913 static int
17914 api_ip_mtable_dump (vat_main_t * vam)
17915 {
17916   vl_api_ip_mtable_dump_t *mp;
17917   vl_api_control_ping_t *mp_ping;
17918   int ret;
17919
17920   M (IP_MTABLE_DUMP, mp);
17921   S (mp);
17922
17923   /* Use a control ping for synchronization */
17924   MPING (CONTROL_PING, mp_ping);
17925   S (mp_ping);
17926
17927   W (ret);
17928   return ret;
17929 }
17930
17931 static int
17932 api_ip_mroute_dump (vat_main_t * vam)
17933 {
17934   unformat_input_t *input = vam->input;
17935   vl_api_control_ping_t *mp_ping;
17936   vl_api_ip_mroute_dump_t *mp;
17937   int ret, is_ip6;
17938   u32 table_id;
17939
17940   is_ip6 = 0;
17941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17942     {
17943       if (unformat (input, "table_id %d", &table_id))
17944         ;
17945       else if (unformat (input, "ip6"))
17946         is_ip6 = 1;
17947       else if (unformat (input, "ip4"))
17948         is_ip6 = 0;
17949       else
17950         break;
17951     }
17952   if (table_id == ~0)
17953     {
17954       errmsg ("missing table id");
17955       return -99;
17956     }
17957
17958   M (IP_MROUTE_DUMP, mp);
17959   mp->table.table_id = table_id;
17960   mp->table.is_ip6 = is_ip6;
17961   S (mp);
17962
17963   /* Use a control ping for synchronization */
17964   MPING (CONTROL_PING, mp_ping);
17965   S (mp_ping);
17966
17967   W (ret);
17968   return ret;
17969 }
17970
17971 #define vl_api_ip_route_details_t_endian vl_noop_handler
17972 #define vl_api_ip_route_details_t_print vl_noop_handler
17973
17974 static void
17975 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17976 {
17977   vat_main_t *vam = &vat_main;
17978   u8 count = mp->route.n_paths;
17979   vl_api_fib_path_t *fp;
17980   int i;
17981
17982   print (vam->ofp,
17983          "table-id %d, prefix %U/%d",
17984          ntohl (mp->route.table_id),
17985          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17986   for (i = 0; i < count; i++)
17987     {
17988       fp = &mp->route.paths[i];
17989
17990       vl_api_fib_path_print (vam, fp);
17991       fp++;
17992     }
17993 }
17994
17995 static void vl_api_ip_route_details_t_handler_json
17996   (vl_api_ip_route_details_t * mp)
17997 {
17998   vat_main_t *vam = &vat_main;
17999   u8 count = mp->route.n_paths;
18000   vat_json_node_t *node = NULL;
18001   struct in_addr ip4;
18002   struct in6_addr ip6;
18003   vl_api_fib_path_t *fp;
18004   int i;
18005
18006   if (VAT_JSON_ARRAY != vam->json_tree.type)
18007     {
18008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18009       vat_json_init_array (&vam->json_tree);
18010     }
18011   node = vat_json_array_add (&vam->json_tree);
18012
18013   vat_json_init_object (node);
18014   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18015   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18016     {
18017       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18018       vat_json_object_add_ip6 (node, "prefix", ip6);
18019     }
18020   else
18021     {
18022       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18023       vat_json_object_add_ip4 (node, "prefix", ip4);
18024     }
18025   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18026   vat_json_object_add_uint (node, "path_count", count);
18027   for (i = 0; i < count; i++)
18028     {
18029       fp = &mp->route.paths[i];
18030       vl_api_mpls_fib_path_json_print (node, fp);
18031     }
18032 }
18033
18034 static int
18035 api_ip_route_dump (vat_main_t * vam)
18036 {
18037   unformat_input_t *input = vam->input;
18038   vl_api_ip_route_dump_t *mp;
18039   vl_api_control_ping_t *mp_ping;
18040   u32 table_id;
18041   u8 is_ip6;
18042   int ret;
18043
18044   is_ip6 = 0;
18045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18046     {
18047       if (unformat (input, "table_id %d", &table_id))
18048         ;
18049       else if (unformat (input, "ip6"))
18050         is_ip6 = 1;
18051       else if (unformat (input, "ip4"))
18052         is_ip6 = 0;
18053       else
18054         break;
18055     }
18056   if (table_id == ~0)
18057     {
18058       errmsg ("missing table id");
18059       return -99;
18060     }
18061
18062   M (IP_ROUTE_DUMP, mp);
18063
18064   mp->table.table_id = table_id;
18065   mp->table.is_ip6 = is_ip6;
18066
18067   S (mp);
18068
18069   /* Use a control ping for synchronization */
18070   MPING (CONTROL_PING, mp_ping);
18071   S (mp_ping);
18072
18073   W (ret);
18074   return ret;
18075 }
18076
18077 int
18078 api_classify_table_ids (vat_main_t * vam)
18079 {
18080   vl_api_classify_table_ids_t *mp;
18081   int ret;
18082
18083   /* Construct the API message */
18084   M (CLASSIFY_TABLE_IDS, mp);
18085   mp->context = 0;
18086
18087   S (mp);
18088   W (ret);
18089   return ret;
18090 }
18091
18092 int
18093 api_classify_table_by_interface (vat_main_t * vam)
18094 {
18095   unformat_input_t *input = vam->input;
18096   vl_api_classify_table_by_interface_t *mp;
18097
18098   u32 sw_if_index = ~0;
18099   int ret;
18100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18101     {
18102       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18103         ;
18104       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18105         ;
18106       else
18107         break;
18108     }
18109   if (sw_if_index == ~0)
18110     {
18111       errmsg ("missing interface name or sw_if_index");
18112       return -99;
18113     }
18114
18115   /* Construct the API message */
18116   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18117   mp->context = 0;
18118   mp->sw_if_index = ntohl (sw_if_index);
18119
18120   S (mp);
18121   W (ret);
18122   return ret;
18123 }
18124
18125 int
18126 api_classify_table_info (vat_main_t * vam)
18127 {
18128   unformat_input_t *input = vam->input;
18129   vl_api_classify_table_info_t *mp;
18130
18131   u32 table_id = ~0;
18132   int ret;
18133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18134     {
18135       if (unformat (input, "table_id %d", &table_id))
18136         ;
18137       else
18138         break;
18139     }
18140   if (table_id == ~0)
18141     {
18142       errmsg ("missing table id");
18143       return -99;
18144     }
18145
18146   /* Construct the API message */
18147   M (CLASSIFY_TABLE_INFO, mp);
18148   mp->context = 0;
18149   mp->table_id = ntohl (table_id);
18150
18151   S (mp);
18152   W (ret);
18153   return ret;
18154 }
18155
18156 int
18157 api_classify_session_dump (vat_main_t * vam)
18158 {
18159   unformat_input_t *input = vam->input;
18160   vl_api_classify_session_dump_t *mp;
18161   vl_api_control_ping_t *mp_ping;
18162
18163   u32 table_id = ~0;
18164   int ret;
18165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18166     {
18167       if (unformat (input, "table_id %d", &table_id))
18168         ;
18169       else
18170         break;
18171     }
18172   if (table_id == ~0)
18173     {
18174       errmsg ("missing table id");
18175       return -99;
18176     }
18177
18178   /* Construct the API message */
18179   M (CLASSIFY_SESSION_DUMP, mp);
18180   mp->context = 0;
18181   mp->table_id = ntohl (table_id);
18182   S (mp);
18183
18184   /* Use a control ping for synchronization */
18185   MPING (CONTROL_PING, mp_ping);
18186   S (mp_ping);
18187
18188   W (ret);
18189   return ret;
18190 }
18191
18192 static void
18193 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18194 {
18195   vat_main_t *vam = &vat_main;
18196
18197   print (vam->ofp, "collector_address %U, collector_port %d, "
18198          "src_address %U, vrf_id %d, path_mtu %u, "
18199          "template_interval %u, udp_checksum %d",
18200          format_ip4_address, mp->collector_address,
18201          ntohs (mp->collector_port),
18202          format_ip4_address, mp->src_address,
18203          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18204          ntohl (mp->template_interval), mp->udp_checksum);
18205
18206   vam->retval = 0;
18207   vam->result_ready = 1;
18208 }
18209
18210 static void
18211   vl_api_ipfix_exporter_details_t_handler_json
18212   (vl_api_ipfix_exporter_details_t * mp)
18213 {
18214   vat_main_t *vam = &vat_main;
18215   vat_json_node_t node;
18216   struct in_addr collector_address;
18217   struct in_addr src_address;
18218
18219   vat_json_init_object (&node);
18220   clib_memcpy (&collector_address, &mp->collector_address,
18221                sizeof (collector_address));
18222   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18223   vat_json_object_add_uint (&node, "collector_port",
18224                             ntohs (mp->collector_port));
18225   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18226   vat_json_object_add_ip4 (&node, "src_address", src_address);
18227   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18228   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18229   vat_json_object_add_uint (&node, "template_interval",
18230                             ntohl (mp->template_interval));
18231   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18232
18233   vat_json_print (vam->ofp, &node);
18234   vat_json_free (&node);
18235   vam->retval = 0;
18236   vam->result_ready = 1;
18237 }
18238
18239 int
18240 api_ipfix_exporter_dump (vat_main_t * vam)
18241 {
18242   vl_api_ipfix_exporter_dump_t *mp;
18243   int ret;
18244
18245   /* Construct the API message */
18246   M (IPFIX_EXPORTER_DUMP, mp);
18247   mp->context = 0;
18248
18249   S (mp);
18250   W (ret);
18251   return ret;
18252 }
18253
18254 static int
18255 api_ipfix_classify_stream_dump (vat_main_t * vam)
18256 {
18257   vl_api_ipfix_classify_stream_dump_t *mp;
18258   int ret;
18259
18260   /* Construct the API message */
18261   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18262   mp->context = 0;
18263
18264   S (mp);
18265   W (ret);
18266   return ret;
18267   /* NOTREACHED */
18268   return 0;
18269 }
18270
18271 static void
18272   vl_api_ipfix_classify_stream_details_t_handler
18273   (vl_api_ipfix_classify_stream_details_t * mp)
18274 {
18275   vat_main_t *vam = &vat_main;
18276   print (vam->ofp, "domain_id %d, src_port %d",
18277          ntohl (mp->domain_id), ntohs (mp->src_port));
18278   vam->retval = 0;
18279   vam->result_ready = 1;
18280 }
18281
18282 static void
18283   vl_api_ipfix_classify_stream_details_t_handler_json
18284   (vl_api_ipfix_classify_stream_details_t * mp)
18285 {
18286   vat_main_t *vam = &vat_main;
18287   vat_json_node_t node;
18288
18289   vat_json_init_object (&node);
18290   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18291   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18292
18293   vat_json_print (vam->ofp, &node);
18294   vat_json_free (&node);
18295   vam->retval = 0;
18296   vam->result_ready = 1;
18297 }
18298
18299 static int
18300 api_ipfix_classify_table_dump (vat_main_t * vam)
18301 {
18302   vl_api_ipfix_classify_table_dump_t *mp;
18303   vl_api_control_ping_t *mp_ping;
18304   int ret;
18305
18306   if (!vam->json_output)
18307     {
18308       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18309              "transport_protocol");
18310     }
18311
18312   /* Construct the API message */
18313   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18314
18315   /* send it... */
18316   S (mp);
18317
18318   /* Use a control ping for synchronization */
18319   MPING (CONTROL_PING, mp_ping);
18320   S (mp_ping);
18321
18322   W (ret);
18323   return ret;
18324 }
18325
18326 static void
18327   vl_api_ipfix_classify_table_details_t_handler
18328   (vl_api_ipfix_classify_table_details_t * mp)
18329 {
18330   vat_main_t *vam = &vat_main;
18331   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18332          mp->transport_protocol);
18333 }
18334
18335 static void
18336   vl_api_ipfix_classify_table_details_t_handler_json
18337   (vl_api_ipfix_classify_table_details_t * mp)
18338 {
18339   vat_json_node_t *node = NULL;
18340   vat_main_t *vam = &vat_main;
18341
18342   if (VAT_JSON_ARRAY != vam->json_tree.type)
18343     {
18344       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18345       vat_json_init_array (&vam->json_tree);
18346     }
18347
18348   node = vat_json_array_add (&vam->json_tree);
18349   vat_json_init_object (node);
18350
18351   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18352   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18353   vat_json_object_add_uint (node, "transport_protocol",
18354                             mp->transport_protocol);
18355 }
18356
18357 static int
18358 api_sw_interface_span_enable_disable (vat_main_t * vam)
18359 {
18360   unformat_input_t *i = vam->input;
18361   vl_api_sw_interface_span_enable_disable_t *mp;
18362   u32 src_sw_if_index = ~0;
18363   u32 dst_sw_if_index = ~0;
18364   u8 state = 3;
18365   int ret;
18366   u8 is_l2 = 0;
18367
18368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18369     {
18370       if (unformat
18371           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18372         ;
18373       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18374         ;
18375       else
18376         if (unformat
18377             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18378         ;
18379       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18380         ;
18381       else if (unformat (i, "disable"))
18382         state = 0;
18383       else if (unformat (i, "rx"))
18384         state = 1;
18385       else if (unformat (i, "tx"))
18386         state = 2;
18387       else if (unformat (i, "both"))
18388         state = 3;
18389       else if (unformat (i, "l2"))
18390         is_l2 = 1;
18391       else
18392         break;
18393     }
18394
18395   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18396
18397   mp->sw_if_index_from = htonl (src_sw_if_index);
18398   mp->sw_if_index_to = htonl (dst_sw_if_index);
18399   mp->state = state;
18400   mp->is_l2 = is_l2;
18401
18402   S (mp);
18403   W (ret);
18404   return ret;
18405 }
18406
18407 static void
18408 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18409                                             * mp)
18410 {
18411   vat_main_t *vam = &vat_main;
18412   u8 *sw_if_from_name = 0;
18413   u8 *sw_if_to_name = 0;
18414   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18415   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18416   char *states[] = { "none", "rx", "tx", "both" };
18417   hash_pair_t *p;
18418
18419   /* *INDENT-OFF* */
18420   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18421   ({
18422     if ((u32) p->value[0] == sw_if_index_from)
18423       {
18424         sw_if_from_name = (u8 *)(p->key);
18425         if (sw_if_to_name)
18426           break;
18427       }
18428     if ((u32) p->value[0] == sw_if_index_to)
18429       {
18430         sw_if_to_name = (u8 *)(p->key);
18431         if (sw_if_from_name)
18432           break;
18433       }
18434   }));
18435   /* *INDENT-ON* */
18436   print (vam->ofp, "%20s => %20s (%s) %s",
18437          sw_if_from_name, sw_if_to_name, states[mp->state],
18438          mp->is_l2 ? "l2" : "device");
18439 }
18440
18441 static void
18442   vl_api_sw_interface_span_details_t_handler_json
18443   (vl_api_sw_interface_span_details_t * mp)
18444 {
18445   vat_main_t *vam = &vat_main;
18446   vat_json_node_t *node = NULL;
18447   u8 *sw_if_from_name = 0;
18448   u8 *sw_if_to_name = 0;
18449   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18450   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18451   hash_pair_t *p;
18452
18453   /* *INDENT-OFF* */
18454   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18455   ({
18456     if ((u32) p->value[0] == sw_if_index_from)
18457       {
18458         sw_if_from_name = (u8 *)(p->key);
18459         if (sw_if_to_name)
18460           break;
18461       }
18462     if ((u32) p->value[0] == sw_if_index_to)
18463       {
18464         sw_if_to_name = (u8 *)(p->key);
18465         if (sw_if_from_name)
18466           break;
18467       }
18468   }));
18469   /* *INDENT-ON* */
18470
18471   if (VAT_JSON_ARRAY != vam->json_tree.type)
18472     {
18473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18474       vat_json_init_array (&vam->json_tree);
18475     }
18476   node = vat_json_array_add (&vam->json_tree);
18477
18478   vat_json_init_object (node);
18479   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18480   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18481   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18482   if (0 != sw_if_to_name)
18483     {
18484       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18485     }
18486   vat_json_object_add_uint (node, "state", mp->state);
18487   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18488 }
18489
18490 static int
18491 api_sw_interface_span_dump (vat_main_t * vam)
18492 {
18493   unformat_input_t *input = vam->input;
18494   vl_api_sw_interface_span_dump_t *mp;
18495   vl_api_control_ping_t *mp_ping;
18496   u8 is_l2 = 0;
18497   int ret;
18498
18499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18500     {
18501       if (unformat (input, "l2"))
18502         is_l2 = 1;
18503       else
18504         break;
18505     }
18506
18507   M (SW_INTERFACE_SPAN_DUMP, mp);
18508   mp->is_l2 = is_l2;
18509   S (mp);
18510
18511   /* Use a control ping for synchronization */
18512   MPING (CONTROL_PING, mp_ping);
18513   S (mp_ping);
18514
18515   W (ret);
18516   return ret;
18517 }
18518
18519 int
18520 api_pg_create_interface (vat_main_t * vam)
18521 {
18522   unformat_input_t *input = vam->input;
18523   vl_api_pg_create_interface_t *mp;
18524
18525   u32 if_id = ~0, gso_size = 0;
18526   u8 gso_enabled = 0;
18527   int ret;
18528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18529     {
18530       if (unformat (input, "if_id %d", &if_id))
18531         ;
18532       else if (unformat (input, "gso-enabled"))
18533         {
18534           gso_enabled = 1;
18535           if (unformat (input, "gso-size %u", &gso_size))
18536             ;
18537           else
18538             {
18539               errmsg ("missing gso-size");
18540               return -99;
18541             }
18542         }
18543       else
18544         break;
18545     }
18546   if (if_id == ~0)
18547     {
18548       errmsg ("missing pg interface index");
18549       return -99;
18550     }
18551
18552   /* Construct the API message */
18553   M (PG_CREATE_INTERFACE, mp);
18554   mp->context = 0;
18555   mp->interface_id = ntohl (if_id);
18556   mp->gso_enabled = gso_enabled;
18557
18558   S (mp);
18559   W (ret);
18560   return ret;
18561 }
18562
18563 int
18564 api_pg_capture (vat_main_t * vam)
18565 {
18566   unformat_input_t *input = vam->input;
18567   vl_api_pg_capture_t *mp;
18568
18569   u32 if_id = ~0;
18570   u8 enable = 1;
18571   u32 count = 1;
18572   u8 pcap_file_set = 0;
18573   u8 *pcap_file = 0;
18574   int ret;
18575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18576     {
18577       if (unformat (input, "if_id %d", &if_id))
18578         ;
18579       else if (unformat (input, "pcap %s", &pcap_file))
18580         pcap_file_set = 1;
18581       else if (unformat (input, "count %d", &count))
18582         ;
18583       else if (unformat (input, "disable"))
18584         enable = 0;
18585       else
18586         break;
18587     }
18588   if (if_id == ~0)
18589     {
18590       errmsg ("missing pg interface index");
18591       return -99;
18592     }
18593   if (pcap_file_set > 0)
18594     {
18595       if (vec_len (pcap_file) > 255)
18596         {
18597           errmsg ("pcap file name is too long");
18598           return -99;
18599         }
18600     }
18601
18602   /* Construct the API message */
18603   M (PG_CAPTURE, mp);
18604   mp->context = 0;
18605   mp->interface_id = ntohl (if_id);
18606   mp->is_enabled = enable;
18607   mp->count = ntohl (count);
18608   if (pcap_file_set != 0)
18609     {
18610       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18611     }
18612   vec_free (pcap_file);
18613
18614   S (mp);
18615   W (ret);
18616   return ret;
18617 }
18618
18619 int
18620 api_pg_enable_disable (vat_main_t * vam)
18621 {
18622   unformat_input_t *input = vam->input;
18623   vl_api_pg_enable_disable_t *mp;
18624
18625   u8 enable = 1;
18626   u8 stream_name_set = 0;
18627   u8 *stream_name = 0;
18628   int ret;
18629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18630     {
18631       if (unformat (input, "stream %s", &stream_name))
18632         stream_name_set = 1;
18633       else if (unformat (input, "disable"))
18634         enable = 0;
18635       else
18636         break;
18637     }
18638
18639   if (stream_name_set > 0)
18640     {
18641       if (vec_len (stream_name) > 255)
18642         {
18643           errmsg ("stream name too long");
18644           return -99;
18645         }
18646     }
18647
18648   /* Construct the API message */
18649   M (PG_ENABLE_DISABLE, mp);
18650   mp->context = 0;
18651   mp->is_enabled = enable;
18652   if (stream_name_set != 0)
18653     {
18654       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18655     }
18656   vec_free (stream_name);
18657
18658   S (mp);
18659   W (ret);
18660   return ret;
18661 }
18662
18663 int
18664 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18665 {
18666   unformat_input_t *input = vam->input;
18667   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18668
18669   u16 *low_ports = 0;
18670   u16 *high_ports = 0;
18671   u16 this_low;
18672   u16 this_hi;
18673   vl_api_prefix_t prefix;
18674   u32 tmp, tmp2;
18675   u8 prefix_set = 0;
18676   u32 vrf_id = ~0;
18677   u8 is_add = 1;
18678   int ret;
18679
18680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18681     {
18682       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18683         prefix_set = 1;
18684       else if (unformat (input, "vrf %d", &vrf_id))
18685         ;
18686       else if (unformat (input, "del"))
18687         is_add = 0;
18688       else if (unformat (input, "port %d", &tmp))
18689         {
18690           if (tmp == 0 || tmp > 65535)
18691             {
18692               errmsg ("port %d out of range", tmp);
18693               return -99;
18694             }
18695           this_low = tmp;
18696           this_hi = this_low + 1;
18697           vec_add1 (low_ports, this_low);
18698           vec_add1 (high_ports, this_hi);
18699         }
18700       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18701         {
18702           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18703             {
18704               errmsg ("incorrect range parameters");
18705               return -99;
18706             }
18707           this_low = tmp;
18708           /* Note: in debug CLI +1 is added to high before
18709              passing to real fn that does "the work"
18710              (ip_source_and_port_range_check_add_del).
18711              This fn is a wrapper around the binary API fn a
18712              control plane will call, which expects this increment
18713              to have occurred. Hence letting the binary API control
18714              plane fn do the increment for consistency between VAT
18715              and other control planes.
18716            */
18717           this_hi = tmp2;
18718           vec_add1 (low_ports, this_low);
18719           vec_add1 (high_ports, this_hi);
18720         }
18721       else
18722         break;
18723     }
18724
18725   if (prefix_set == 0)
18726     {
18727       errmsg ("<address>/<mask> not specified");
18728       return -99;
18729     }
18730
18731   if (vrf_id == ~0)
18732     {
18733       errmsg ("VRF ID required, not specified");
18734       return -99;
18735     }
18736
18737   if (vrf_id == 0)
18738     {
18739       errmsg
18740         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18741       return -99;
18742     }
18743
18744   if (vec_len (low_ports) == 0)
18745     {
18746       errmsg ("At least one port or port range required");
18747       return -99;
18748     }
18749
18750   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18751
18752   mp->is_add = is_add;
18753
18754   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18755
18756   mp->number_of_ranges = vec_len (low_ports);
18757
18758   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18759   vec_free (low_ports);
18760
18761   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18762   vec_free (high_ports);
18763
18764   mp->vrf_id = ntohl (vrf_id);
18765
18766   S (mp);
18767   W (ret);
18768   return ret;
18769 }
18770
18771 int
18772 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18773 {
18774   unformat_input_t *input = vam->input;
18775   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18776   u32 sw_if_index = ~0;
18777   int vrf_set = 0;
18778   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18779   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18780   u8 is_add = 1;
18781   int ret;
18782
18783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18784     {
18785       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18786         ;
18787       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18788         ;
18789       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18790         vrf_set = 1;
18791       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18792         vrf_set = 1;
18793       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18794         vrf_set = 1;
18795       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18796         vrf_set = 1;
18797       else if (unformat (input, "del"))
18798         is_add = 0;
18799       else
18800         break;
18801     }
18802
18803   if (sw_if_index == ~0)
18804     {
18805       errmsg ("Interface required but not specified");
18806       return -99;
18807     }
18808
18809   if (vrf_set == 0)
18810     {
18811       errmsg ("VRF ID required but not specified");
18812       return -99;
18813     }
18814
18815   if (tcp_out_vrf_id == 0
18816       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18817     {
18818       errmsg
18819         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18820       return -99;
18821     }
18822
18823   /* Construct the API message */
18824   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18825
18826   mp->sw_if_index = ntohl (sw_if_index);
18827   mp->is_add = is_add;
18828   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18829   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18830   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18831   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18832
18833   /* send it... */
18834   S (mp);
18835
18836   /* Wait for a reply... */
18837   W (ret);
18838   return ret;
18839 }
18840
18841 static int
18842 api_set_punt (vat_main_t * vam)
18843 {
18844   unformat_input_t *i = vam->input;
18845   vl_api_address_family_t af;
18846   vl_api_set_punt_t *mp;
18847   u32 protocol = ~0;
18848   u32 port = ~0;
18849   int is_add = 1;
18850   int ret;
18851
18852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18853     {
18854       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18855         ;
18856       else if (unformat (i, "protocol %d", &protocol))
18857         ;
18858       else if (unformat (i, "port %d", &port))
18859         ;
18860       else if (unformat (i, "del"))
18861         is_add = 0;
18862       else
18863         {
18864           clib_warning ("parse error '%U'", format_unformat_error, i);
18865           return -99;
18866         }
18867     }
18868
18869   M (SET_PUNT, mp);
18870
18871   mp->is_add = (u8) is_add;
18872   mp->punt.type = PUNT_API_TYPE_L4;
18873   mp->punt.punt.l4.af = af;
18874   mp->punt.punt.l4.protocol = (u8) protocol;
18875   mp->punt.punt.l4.port = htons ((u16) port);
18876
18877   S (mp);
18878   W (ret);
18879   return ret;
18880 }
18881
18882 static int
18883 api_delete_subif (vat_main_t * vam)
18884 {
18885   unformat_input_t *i = vam->input;
18886   vl_api_delete_subif_t *mp;
18887   u32 sw_if_index = ~0;
18888   int ret;
18889
18890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18891     {
18892       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18893         ;
18894       if (unformat (i, "sw_if_index %d", &sw_if_index))
18895         ;
18896       else
18897         break;
18898     }
18899
18900   if (sw_if_index == ~0)
18901     {
18902       errmsg ("missing sw_if_index");
18903       return -99;
18904     }
18905
18906   /* Construct the API message */
18907   M (DELETE_SUBIF, mp);
18908   mp->sw_if_index = ntohl (sw_if_index);
18909
18910   S (mp);
18911   W (ret);
18912   return ret;
18913 }
18914
18915 #define foreach_pbb_vtr_op      \
18916 _("disable",  L2_VTR_DISABLED)  \
18917 _("pop",  L2_VTR_POP_2)         \
18918 _("push",  L2_VTR_PUSH_2)
18919
18920 static int
18921 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18922 {
18923   unformat_input_t *i = vam->input;
18924   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18925   u32 sw_if_index = ~0, vtr_op = ~0;
18926   u16 outer_tag = ~0;
18927   u8 dmac[6], smac[6];
18928   u8 dmac_set = 0, smac_set = 0;
18929   u16 vlanid = 0;
18930   u32 sid = ~0;
18931   u32 tmp;
18932   int ret;
18933
18934   /* Shut up coverity */
18935   clib_memset (dmac, 0, sizeof (dmac));
18936   clib_memset (smac, 0, sizeof (smac));
18937
18938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18939     {
18940       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18941         ;
18942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18943         ;
18944       else if (unformat (i, "vtr_op %d", &vtr_op))
18945         ;
18946 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18947       foreach_pbb_vtr_op
18948 #undef _
18949         else if (unformat (i, "translate_pbb_stag"))
18950         {
18951           if (unformat (i, "%d", &tmp))
18952             {
18953               vtr_op = L2_VTR_TRANSLATE_2_1;
18954               outer_tag = tmp;
18955             }
18956           else
18957             {
18958               errmsg
18959                 ("translate_pbb_stag operation requires outer tag definition");
18960               return -99;
18961             }
18962         }
18963       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18964         dmac_set++;
18965       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18966         smac_set++;
18967       else if (unformat (i, "sid %d", &sid))
18968         ;
18969       else if (unformat (i, "vlanid %d", &tmp))
18970         vlanid = tmp;
18971       else
18972         {
18973           clib_warning ("parse error '%U'", format_unformat_error, i);
18974           return -99;
18975         }
18976     }
18977
18978   if ((sw_if_index == ~0) || (vtr_op == ~0))
18979     {
18980       errmsg ("missing sw_if_index or vtr operation");
18981       return -99;
18982     }
18983   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18984       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18985     {
18986       errmsg
18987         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18988       return -99;
18989     }
18990
18991   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18992   mp->sw_if_index = ntohl (sw_if_index);
18993   mp->vtr_op = ntohl (vtr_op);
18994   mp->outer_tag = ntohs (outer_tag);
18995   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18996   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18997   mp->b_vlanid = ntohs (vlanid);
18998   mp->i_sid = ntohl (sid);
18999
19000   S (mp);
19001   W (ret);
19002   return ret;
19003 }
19004
19005 static int
19006 api_flow_classify_set_interface (vat_main_t * vam)
19007 {
19008   unformat_input_t *i = vam->input;
19009   vl_api_flow_classify_set_interface_t *mp;
19010   u32 sw_if_index;
19011   int sw_if_index_set;
19012   u32 ip4_table_index = ~0;
19013   u32 ip6_table_index = ~0;
19014   u8 is_add = 1;
19015   int ret;
19016
19017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19018     {
19019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19020         sw_if_index_set = 1;
19021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19022         sw_if_index_set = 1;
19023       else if (unformat (i, "del"))
19024         is_add = 0;
19025       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19026         ;
19027       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19028         ;
19029       else
19030         {
19031           clib_warning ("parse error '%U'", format_unformat_error, i);
19032           return -99;
19033         }
19034     }
19035
19036   if (sw_if_index_set == 0)
19037     {
19038       errmsg ("missing interface name or sw_if_index");
19039       return -99;
19040     }
19041
19042   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19043
19044   mp->sw_if_index = ntohl (sw_if_index);
19045   mp->ip4_table_index = ntohl (ip4_table_index);
19046   mp->ip6_table_index = ntohl (ip6_table_index);
19047   mp->is_add = is_add;
19048
19049   S (mp);
19050   W (ret);
19051   return ret;
19052 }
19053
19054 static int
19055 api_flow_classify_dump (vat_main_t * vam)
19056 {
19057   unformat_input_t *i = vam->input;
19058   vl_api_flow_classify_dump_t *mp;
19059   vl_api_control_ping_t *mp_ping;
19060   u8 type = FLOW_CLASSIFY_N_TABLES;
19061   int ret;
19062
19063   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19064     ;
19065   else
19066     {
19067       errmsg ("classify table type must be specified");
19068       return -99;
19069     }
19070
19071   if (!vam->json_output)
19072     {
19073       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19074     }
19075
19076   M (FLOW_CLASSIFY_DUMP, mp);
19077   mp->type = type;
19078   /* send it... */
19079   S (mp);
19080
19081   /* Use a control ping for synchronization */
19082   MPING (CONTROL_PING, mp_ping);
19083   S (mp_ping);
19084
19085   /* Wait for a reply... */
19086   W (ret);
19087   return ret;
19088 }
19089
19090 static int
19091 api_feature_enable_disable (vat_main_t * vam)
19092 {
19093   unformat_input_t *i = vam->input;
19094   vl_api_feature_enable_disable_t *mp;
19095   u8 *arc_name = 0;
19096   u8 *feature_name = 0;
19097   u32 sw_if_index = ~0;
19098   u8 enable = 1;
19099   int ret;
19100
19101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19102     {
19103       if (unformat (i, "arc_name %s", &arc_name))
19104         ;
19105       else if (unformat (i, "feature_name %s", &feature_name))
19106         ;
19107       else
19108         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19109         ;
19110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19111         ;
19112       else if (unformat (i, "disable"))
19113         enable = 0;
19114       else
19115         break;
19116     }
19117
19118   if (arc_name == 0)
19119     {
19120       errmsg ("missing arc name");
19121       return -99;
19122     }
19123   if (vec_len (arc_name) > 63)
19124     {
19125       errmsg ("arc name too long");
19126     }
19127
19128   if (feature_name == 0)
19129     {
19130       errmsg ("missing feature name");
19131       return -99;
19132     }
19133   if (vec_len (feature_name) > 63)
19134     {
19135       errmsg ("feature name too long");
19136     }
19137
19138   if (sw_if_index == ~0)
19139     {
19140       errmsg ("missing interface name or sw_if_index");
19141       return -99;
19142     }
19143
19144   /* Construct the API message */
19145   M (FEATURE_ENABLE_DISABLE, mp);
19146   mp->sw_if_index = ntohl (sw_if_index);
19147   mp->enable = enable;
19148   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19149   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19150   vec_free (arc_name);
19151   vec_free (feature_name);
19152
19153   S (mp);
19154   W (ret);
19155   return ret;
19156 }
19157
19158 static int
19159 api_feature_gso_enable_disable (vat_main_t * vam)
19160 {
19161   unformat_input_t *i = vam->input;
19162   vl_api_feature_gso_enable_disable_t *mp;
19163   u32 sw_if_index = ~0;
19164   u8 enable = 1;
19165   int ret;
19166
19167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19168     {
19169       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19170         ;
19171       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19172         ;
19173       else if (unformat (i, "enable"))
19174         enable = 1;
19175       else if (unformat (i, "disable"))
19176         enable = 0;
19177       else
19178         break;
19179     }
19180
19181   if (sw_if_index == ~0)
19182     {
19183       errmsg ("missing interface name or sw_if_index");
19184       return -99;
19185     }
19186
19187   /* Construct the API message */
19188   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19189   mp->sw_if_index = ntohl (sw_if_index);
19190   mp->enable_disable = enable;
19191
19192   S (mp);
19193   W (ret);
19194   return ret;
19195 }
19196
19197 static int
19198 api_sw_interface_tag_add_del (vat_main_t * vam)
19199 {
19200   unformat_input_t *i = vam->input;
19201   vl_api_sw_interface_tag_add_del_t *mp;
19202   u32 sw_if_index = ~0;
19203   u8 *tag = 0;
19204   u8 enable = 1;
19205   int ret;
19206
19207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19208     {
19209       if (unformat (i, "tag %s", &tag))
19210         ;
19211       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19212         ;
19213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19214         ;
19215       else if (unformat (i, "del"))
19216         enable = 0;
19217       else
19218         break;
19219     }
19220
19221   if (sw_if_index == ~0)
19222     {
19223       errmsg ("missing interface name or sw_if_index");
19224       return -99;
19225     }
19226
19227   if (enable && (tag == 0))
19228     {
19229       errmsg ("no tag specified");
19230       return -99;
19231     }
19232
19233   /* Construct the API message */
19234   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19235   mp->sw_if_index = ntohl (sw_if_index);
19236   mp->is_add = enable;
19237   if (enable)
19238     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19239   vec_free (tag);
19240
19241   S (mp);
19242   W (ret);
19243   return ret;
19244 }
19245
19246 static int
19247 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19248 {
19249   unformat_input_t *i = vam->input;
19250   vl_api_mac_address_t mac = { 0 };
19251   vl_api_sw_interface_add_del_mac_address_t *mp;
19252   u32 sw_if_index = ~0;
19253   u8 is_add = 1;
19254   u8 mac_set = 0;
19255   int ret;
19256
19257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19258     {
19259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19260         ;
19261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19262         ;
19263       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19264         mac_set++;
19265       else if (unformat (i, "del"))
19266         is_add = 0;
19267       else
19268         break;
19269     }
19270
19271   if (sw_if_index == ~0)
19272     {
19273       errmsg ("missing interface name or sw_if_index");
19274       return -99;
19275     }
19276
19277   if (!mac_set)
19278     {
19279       errmsg ("missing MAC address");
19280       return -99;
19281     }
19282
19283   /* Construct the API message */
19284   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19285   mp->sw_if_index = ntohl (sw_if_index);
19286   mp->is_add = is_add;
19287   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19288
19289   S (mp);
19290   W (ret);
19291   return ret;
19292 }
19293
19294 static void vl_api_l2_xconnect_details_t_handler
19295   (vl_api_l2_xconnect_details_t * mp)
19296 {
19297   vat_main_t *vam = &vat_main;
19298
19299   print (vam->ofp, "%15d%15d",
19300          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19301 }
19302
19303 static void vl_api_l2_xconnect_details_t_handler_json
19304   (vl_api_l2_xconnect_details_t * mp)
19305 {
19306   vat_main_t *vam = &vat_main;
19307   vat_json_node_t *node = NULL;
19308
19309   if (VAT_JSON_ARRAY != vam->json_tree.type)
19310     {
19311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19312       vat_json_init_array (&vam->json_tree);
19313     }
19314   node = vat_json_array_add (&vam->json_tree);
19315
19316   vat_json_init_object (node);
19317   vat_json_object_add_uint (node, "rx_sw_if_index",
19318                             ntohl (mp->rx_sw_if_index));
19319   vat_json_object_add_uint (node, "tx_sw_if_index",
19320                             ntohl (mp->tx_sw_if_index));
19321 }
19322
19323 static int
19324 api_l2_xconnect_dump (vat_main_t * vam)
19325 {
19326   vl_api_l2_xconnect_dump_t *mp;
19327   vl_api_control_ping_t *mp_ping;
19328   int ret;
19329
19330   if (!vam->json_output)
19331     {
19332       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19333     }
19334
19335   M (L2_XCONNECT_DUMP, mp);
19336
19337   S (mp);
19338
19339   /* Use a control ping for synchronization */
19340   MPING (CONTROL_PING, mp_ping);
19341   S (mp_ping);
19342
19343   W (ret);
19344   return ret;
19345 }
19346
19347 static int
19348 api_hw_interface_set_mtu (vat_main_t * vam)
19349 {
19350   unformat_input_t *i = vam->input;
19351   vl_api_hw_interface_set_mtu_t *mp;
19352   u32 sw_if_index = ~0;
19353   u32 mtu = 0;
19354   int ret;
19355
19356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19357     {
19358       if (unformat (i, "mtu %d", &mtu))
19359         ;
19360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19361         ;
19362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19363         ;
19364       else
19365         break;
19366     }
19367
19368   if (sw_if_index == ~0)
19369     {
19370       errmsg ("missing interface name or sw_if_index");
19371       return -99;
19372     }
19373
19374   if (mtu == 0)
19375     {
19376       errmsg ("no mtu specified");
19377       return -99;
19378     }
19379
19380   /* Construct the API message */
19381   M (HW_INTERFACE_SET_MTU, mp);
19382   mp->sw_if_index = ntohl (sw_if_index);
19383   mp->mtu = ntohs ((u16) mtu);
19384
19385   S (mp);
19386   W (ret);
19387   return ret;
19388 }
19389
19390 static int
19391 api_p2p_ethernet_add (vat_main_t * vam)
19392 {
19393   unformat_input_t *i = vam->input;
19394   vl_api_p2p_ethernet_add_t *mp;
19395   u32 parent_if_index = ~0;
19396   u32 sub_id = ~0;
19397   u8 remote_mac[6];
19398   u8 mac_set = 0;
19399   int ret;
19400
19401   clib_memset (remote_mac, 0, sizeof (remote_mac));
19402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19403     {
19404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19405         ;
19406       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19407         ;
19408       else
19409         if (unformat
19410             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19411         mac_set++;
19412       else if (unformat (i, "sub_id %d", &sub_id))
19413         ;
19414       else
19415         {
19416           clib_warning ("parse error '%U'", format_unformat_error, i);
19417           return -99;
19418         }
19419     }
19420
19421   if (parent_if_index == ~0)
19422     {
19423       errmsg ("missing interface name or sw_if_index");
19424       return -99;
19425     }
19426   if (mac_set == 0)
19427     {
19428       errmsg ("missing remote mac address");
19429       return -99;
19430     }
19431   if (sub_id == ~0)
19432     {
19433       errmsg ("missing sub-interface id");
19434       return -99;
19435     }
19436
19437   M (P2P_ETHERNET_ADD, mp);
19438   mp->parent_if_index = ntohl (parent_if_index);
19439   mp->subif_id = ntohl (sub_id);
19440   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19441
19442   S (mp);
19443   W (ret);
19444   return ret;
19445 }
19446
19447 static int
19448 api_p2p_ethernet_del (vat_main_t * vam)
19449 {
19450   unformat_input_t *i = vam->input;
19451   vl_api_p2p_ethernet_del_t *mp;
19452   u32 parent_if_index = ~0;
19453   u8 remote_mac[6];
19454   u8 mac_set = 0;
19455   int ret;
19456
19457   clib_memset (remote_mac, 0, sizeof (remote_mac));
19458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19459     {
19460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19461         ;
19462       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19463         ;
19464       else
19465         if (unformat
19466             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19467         mac_set++;
19468       else
19469         {
19470           clib_warning ("parse error '%U'", format_unformat_error, i);
19471           return -99;
19472         }
19473     }
19474
19475   if (parent_if_index == ~0)
19476     {
19477       errmsg ("missing interface name or sw_if_index");
19478       return -99;
19479     }
19480   if (mac_set == 0)
19481     {
19482       errmsg ("missing remote mac address");
19483       return -99;
19484     }
19485
19486   M (P2P_ETHERNET_DEL, mp);
19487   mp->parent_if_index = ntohl (parent_if_index);
19488   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19489
19490   S (mp);
19491   W (ret);
19492   return ret;
19493 }
19494
19495 static int
19496 api_lldp_config (vat_main_t * vam)
19497 {
19498   unformat_input_t *i = vam->input;
19499   vl_api_lldp_config_t *mp;
19500   int tx_hold = 0;
19501   int tx_interval = 0;
19502   u8 *sys_name = NULL;
19503   int ret;
19504
19505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19506     {
19507       if (unformat (i, "system-name %s", &sys_name))
19508         ;
19509       else if (unformat (i, "tx-hold %d", &tx_hold))
19510         ;
19511       else if (unformat (i, "tx-interval %d", &tx_interval))
19512         ;
19513       else
19514         {
19515           clib_warning ("parse error '%U'", format_unformat_error, i);
19516           return -99;
19517         }
19518     }
19519
19520   vec_add1 (sys_name, 0);
19521
19522   M (LLDP_CONFIG, mp);
19523   mp->tx_hold = htonl (tx_hold);
19524   mp->tx_interval = htonl (tx_interval);
19525   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19526   vec_free (sys_name);
19527
19528   S (mp);
19529   W (ret);
19530   return ret;
19531 }
19532
19533 static int
19534 api_sw_interface_set_lldp (vat_main_t * vam)
19535 {
19536   unformat_input_t *i = vam->input;
19537   vl_api_sw_interface_set_lldp_t *mp;
19538   u32 sw_if_index = ~0;
19539   u32 enable = 1;
19540   u8 *port_desc = NULL, *mgmt_oid = NULL;
19541   ip4_address_t ip4_addr;
19542   ip6_address_t ip6_addr;
19543   int ret;
19544
19545   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19546   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19547
19548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19549     {
19550       if (unformat (i, "disable"))
19551         enable = 0;
19552       else
19553         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19554         ;
19555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19556         ;
19557       else if (unformat (i, "port-desc %s", &port_desc))
19558         ;
19559       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19560         ;
19561       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19562         ;
19563       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19564         ;
19565       else
19566         break;
19567     }
19568
19569   if (sw_if_index == ~0)
19570     {
19571       errmsg ("missing interface name or sw_if_index");
19572       return -99;
19573     }
19574
19575   /* Construct the API message */
19576   vec_add1 (port_desc, 0);
19577   vec_add1 (mgmt_oid, 0);
19578   M (SW_INTERFACE_SET_LLDP, mp);
19579   mp->sw_if_index = ntohl (sw_if_index);
19580   mp->enable = enable;
19581   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19582   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19583   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19584   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19585   vec_free (port_desc);
19586   vec_free (mgmt_oid);
19587
19588   S (mp);
19589   W (ret);
19590   return ret;
19591 }
19592
19593 static int
19594 api_tcp_configure_src_addresses (vat_main_t * vam)
19595 {
19596   vl_api_tcp_configure_src_addresses_t *mp;
19597   unformat_input_t *i = vam->input;
19598   vl_api_address_t first, last;
19599   u8 range_set = 0;
19600   u32 vrf_id = 0;
19601   int ret;
19602
19603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19604     {
19605       if (unformat (i, "%U - %U",
19606                     unformat_vl_api_address, &first,
19607                     unformat_vl_api_address, &last))
19608         {
19609           if (range_set)
19610             {
19611               errmsg ("one range per message (range already set)");
19612               return -99;
19613             }
19614           range_set = 1;
19615         }
19616       else if (unformat (i, "vrf %d", &vrf_id))
19617         ;
19618       else
19619         break;
19620     }
19621
19622   if (range_set == 0)
19623     {
19624       errmsg ("address range not set");
19625       return -99;
19626     }
19627
19628   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19629
19630   mp->vrf_id = ntohl (vrf_id);
19631   clib_memcpy (&mp->first_address, &first, sizeof (first));
19632   clib_memcpy (&mp->last_address, &last, sizeof (last));
19633
19634   S (mp);
19635   W (ret);
19636   return ret;
19637 }
19638
19639 static void vl_api_app_namespace_add_del_reply_t_handler
19640   (vl_api_app_namespace_add_del_reply_t * mp)
19641 {
19642   vat_main_t *vam = &vat_main;
19643   i32 retval = ntohl (mp->retval);
19644   if (vam->async_mode)
19645     {
19646       vam->async_errors += (retval < 0);
19647     }
19648   else
19649     {
19650       vam->retval = retval;
19651       if (retval == 0)
19652         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19653       vam->result_ready = 1;
19654     }
19655 }
19656
19657 static void vl_api_app_namespace_add_del_reply_t_handler_json
19658   (vl_api_app_namespace_add_del_reply_t * mp)
19659 {
19660   vat_main_t *vam = &vat_main;
19661   vat_json_node_t node;
19662
19663   vat_json_init_object (&node);
19664   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19665   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19666
19667   vat_json_print (vam->ofp, &node);
19668   vat_json_free (&node);
19669
19670   vam->retval = ntohl (mp->retval);
19671   vam->result_ready = 1;
19672 }
19673
19674 static int
19675 api_app_namespace_add_del (vat_main_t * vam)
19676 {
19677   vl_api_app_namespace_add_del_t *mp;
19678   unformat_input_t *i = vam->input;
19679   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19680   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19681   u64 secret;
19682   int ret;
19683
19684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19685     {
19686       if (unformat (i, "id %_%v%_", &ns_id))
19687         ;
19688       else if (unformat (i, "secret %lu", &secret))
19689         secret_set = 1;
19690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19691         sw_if_index_set = 1;
19692       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19693         ;
19694       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19695         ;
19696       else
19697         break;
19698     }
19699   if (!ns_id || !secret_set || !sw_if_index_set)
19700     {
19701       errmsg ("namespace id, secret and sw_if_index must be set");
19702       return -99;
19703     }
19704   if (vec_len (ns_id) > 64)
19705     {
19706       errmsg ("namespace id too long");
19707       return -99;
19708     }
19709   M (APP_NAMESPACE_ADD_DEL, mp);
19710
19711   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19712   mp->secret = clib_host_to_net_u64 (secret);
19713   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19714   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19715   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19716   vec_free (ns_id);
19717   S (mp);
19718   W (ret);
19719   return ret;
19720 }
19721
19722 static int
19723 api_sock_init_shm (vat_main_t * vam)
19724 {
19725 #if VPP_API_TEST_BUILTIN == 0
19726   unformat_input_t *i = vam->input;
19727   vl_api_shm_elem_config_t *config = 0;
19728   u64 size = 64 << 20;
19729   int rv;
19730
19731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19732     {
19733       if (unformat (i, "size %U", unformat_memory_size, &size))
19734         ;
19735       else
19736         break;
19737     }
19738
19739   /*
19740    * Canned custom ring allocator config.
19741    * Should probably parse all of this
19742    */
19743   vec_validate (config, 6);
19744   config[0].type = VL_API_VLIB_RING;
19745   config[0].size = 256;
19746   config[0].count = 32;
19747
19748   config[1].type = VL_API_VLIB_RING;
19749   config[1].size = 1024;
19750   config[1].count = 16;
19751
19752   config[2].type = VL_API_VLIB_RING;
19753   config[2].size = 4096;
19754   config[2].count = 2;
19755
19756   config[3].type = VL_API_CLIENT_RING;
19757   config[3].size = 256;
19758   config[3].count = 32;
19759
19760   config[4].type = VL_API_CLIENT_RING;
19761   config[4].size = 1024;
19762   config[4].count = 16;
19763
19764   config[5].type = VL_API_CLIENT_RING;
19765   config[5].size = 4096;
19766   config[5].count = 2;
19767
19768   config[6].type = VL_API_QUEUE;
19769   config[6].count = 128;
19770   config[6].size = sizeof (uword);
19771
19772   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19773   if (!rv)
19774     vam->client_index_invalid = 1;
19775   return rv;
19776 #else
19777   return -99;
19778 #endif
19779 }
19780
19781 static void
19782 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19783 {
19784   vat_main_t *vam = &vat_main;
19785   fib_prefix_t lcl, rmt;
19786
19787   ip_prefix_decode (&mp->lcl, &lcl);
19788   ip_prefix_decode (&mp->rmt, &rmt);
19789
19790   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19791     {
19792       print (vam->ofp,
19793              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19794              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19795              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19796              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19797              &rmt.fp_addr.ip4, rmt.fp_len,
19798              clib_net_to_host_u16 (mp->rmt_port),
19799              clib_net_to_host_u32 (mp->action_index), mp->tag);
19800     }
19801   else
19802     {
19803       print (vam->ofp,
19804              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19805              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19806              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19807              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19808              &rmt.fp_addr.ip6, rmt.fp_len,
19809              clib_net_to_host_u16 (mp->rmt_port),
19810              clib_net_to_host_u32 (mp->action_index), mp->tag);
19811     }
19812 }
19813
19814 static void
19815 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19816                                              mp)
19817 {
19818   vat_main_t *vam = &vat_main;
19819   vat_json_node_t *node = NULL;
19820   struct in6_addr ip6;
19821   struct in_addr ip4;
19822
19823   fib_prefix_t lcl, rmt;
19824
19825   ip_prefix_decode (&mp->lcl, &lcl);
19826   ip_prefix_decode (&mp->rmt, &rmt);
19827
19828   if (VAT_JSON_ARRAY != vam->json_tree.type)
19829     {
19830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19831       vat_json_init_array (&vam->json_tree);
19832     }
19833   node = vat_json_array_add (&vam->json_tree);
19834   vat_json_init_object (node);
19835
19836   vat_json_object_add_uint (node, "appns_index",
19837                             clib_net_to_host_u32 (mp->appns_index));
19838   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19839   vat_json_object_add_uint (node, "scope", mp->scope);
19840   vat_json_object_add_uint (node, "action_index",
19841                             clib_net_to_host_u32 (mp->action_index));
19842   vat_json_object_add_uint (node, "lcl_port",
19843                             clib_net_to_host_u16 (mp->lcl_port));
19844   vat_json_object_add_uint (node, "rmt_port",
19845                             clib_net_to_host_u16 (mp->rmt_port));
19846   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19847   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19848   vat_json_object_add_string_copy (node, "tag", mp->tag);
19849   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19850     {
19851       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19852       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19853       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19854       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19855     }
19856   else
19857     {
19858       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19859       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19860       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19861       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19862     }
19863 }
19864
19865 static int
19866 api_session_rule_add_del (vat_main_t * vam)
19867 {
19868   vl_api_session_rule_add_del_t *mp;
19869   unformat_input_t *i = vam->input;
19870   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19871   u32 appns_index = 0, scope = 0;
19872   ip4_address_t lcl_ip4, rmt_ip4;
19873   ip6_address_t lcl_ip6, rmt_ip6;
19874   u8 is_ip4 = 1, conn_set = 0;
19875   u8 is_add = 1, *tag = 0;
19876   int ret;
19877   fib_prefix_t lcl, rmt;
19878
19879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19880     {
19881       if (unformat (i, "del"))
19882         is_add = 0;
19883       else if (unformat (i, "add"))
19884         ;
19885       else if (unformat (i, "proto tcp"))
19886         proto = 0;
19887       else if (unformat (i, "proto udp"))
19888         proto = 1;
19889       else if (unformat (i, "appns %d", &appns_index))
19890         ;
19891       else if (unformat (i, "scope %d", &scope))
19892         ;
19893       else if (unformat (i, "tag %_%v%_", &tag))
19894         ;
19895       else
19896         if (unformat
19897             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19898              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19899              &rmt_port))
19900         {
19901           is_ip4 = 1;
19902           conn_set = 1;
19903         }
19904       else
19905         if (unformat
19906             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19907              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19908              &rmt_port))
19909         {
19910           is_ip4 = 0;
19911           conn_set = 1;
19912         }
19913       else if (unformat (i, "action %d", &action))
19914         ;
19915       else
19916         break;
19917     }
19918   if (proto == ~0 || !conn_set || action == ~0)
19919     {
19920       errmsg ("transport proto, connection and action must be set");
19921       return -99;
19922     }
19923
19924   if (scope > 3)
19925     {
19926       errmsg ("scope should be 0-3");
19927       return -99;
19928     }
19929
19930   M (SESSION_RULE_ADD_DEL, mp);
19931
19932   clib_memset (&lcl, 0, sizeof (lcl));
19933   clib_memset (&rmt, 0, sizeof (rmt));
19934   if (is_ip4)
19935     {
19936       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19937       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19938       lcl.fp_len = lcl_plen;
19939       rmt.fp_len = rmt_plen;
19940     }
19941   else
19942     {
19943       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19944       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19945       lcl.fp_len = lcl_plen;
19946       rmt.fp_len = rmt_plen;
19947     }
19948
19949
19950   ip_prefix_encode (&lcl, &mp->lcl);
19951   ip_prefix_encode (&rmt, &mp->rmt);
19952   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19953   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19954   mp->transport_proto =
19955     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19956   mp->action_index = clib_host_to_net_u32 (action);
19957   mp->appns_index = clib_host_to_net_u32 (appns_index);
19958   mp->scope = scope;
19959   mp->is_add = is_add;
19960   if (tag)
19961     {
19962       clib_memcpy (mp->tag, tag, vec_len (tag));
19963       vec_free (tag);
19964     }
19965
19966   S (mp);
19967   W (ret);
19968   return ret;
19969 }
19970
19971 static int
19972 api_session_rules_dump (vat_main_t * vam)
19973 {
19974   vl_api_session_rules_dump_t *mp;
19975   vl_api_control_ping_t *mp_ping;
19976   int ret;
19977
19978   if (!vam->json_output)
19979     {
19980       print (vam->ofp, "%=20s", "Session Rules");
19981     }
19982
19983   M (SESSION_RULES_DUMP, mp);
19984   /* send it... */
19985   S (mp);
19986
19987   /* Use a control ping for synchronization */
19988   MPING (CONTROL_PING, mp_ping);
19989   S (mp_ping);
19990
19991   /* Wait for a reply... */
19992   W (ret);
19993   return ret;
19994 }
19995
19996 static int
19997 api_ip_container_proxy_add_del (vat_main_t * vam)
19998 {
19999   vl_api_ip_container_proxy_add_del_t *mp;
20000   unformat_input_t *i = vam->input;
20001   u32 sw_if_index = ~0;
20002   vl_api_prefix_t pfx = { };
20003   u8 is_add = 1;
20004   int ret;
20005
20006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20007     {
20008       if (unformat (i, "del"))
20009         is_add = 0;
20010       else if (unformat (i, "add"))
20011         ;
20012       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20013         ;
20014       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20015         ;
20016       else
20017         break;
20018     }
20019   if (sw_if_index == ~0 || pfx.len == 0)
20020     {
20021       errmsg ("address and sw_if_index must be set");
20022       return -99;
20023     }
20024
20025   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20026
20027   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20028   mp->is_add = is_add;
20029   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20030
20031   S (mp);
20032   W (ret);
20033   return ret;
20034 }
20035
20036 static int
20037 api_qos_record_enable_disable (vat_main_t * vam)
20038 {
20039   unformat_input_t *i = vam->input;
20040   vl_api_qos_record_enable_disable_t *mp;
20041   u32 sw_if_index, qs = 0xff;
20042   u8 sw_if_index_set = 0;
20043   u8 enable = 1;
20044   int ret;
20045
20046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20047     {
20048       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20049         sw_if_index_set = 1;
20050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20051         sw_if_index_set = 1;
20052       else if (unformat (i, "%U", unformat_qos_source, &qs))
20053         ;
20054       else if (unformat (i, "disable"))
20055         enable = 0;
20056       else
20057         {
20058           clib_warning ("parse error '%U'", format_unformat_error, i);
20059           return -99;
20060         }
20061     }
20062
20063   if (sw_if_index_set == 0)
20064     {
20065       errmsg ("missing interface name or sw_if_index");
20066       return -99;
20067     }
20068   if (qs == 0xff)
20069     {
20070       errmsg ("input location must be specified");
20071       return -99;
20072     }
20073
20074   M (QOS_RECORD_ENABLE_DISABLE, mp);
20075
20076   mp->record.sw_if_index = ntohl (sw_if_index);
20077   mp->record.input_source = qs;
20078   mp->enable = enable;
20079
20080   S (mp);
20081   W (ret);
20082   return ret;
20083 }
20084
20085
20086 static int
20087 q_or_quit (vat_main_t * vam)
20088 {
20089 #if VPP_API_TEST_BUILTIN == 0
20090   longjmp (vam->jump_buf, 1);
20091 #endif
20092   return 0;                     /* not so much */
20093 }
20094
20095 static int
20096 q (vat_main_t * vam)
20097 {
20098   return q_or_quit (vam);
20099 }
20100
20101 static int
20102 quit (vat_main_t * vam)
20103 {
20104   return q_or_quit (vam);
20105 }
20106
20107 static int
20108 comment (vat_main_t * vam)
20109 {
20110   return 0;
20111 }
20112
20113 static int
20114 elog_save (vat_main_t * vam)
20115 {
20116 #if VPP_API_TEST_BUILTIN == 0
20117   elog_main_t *em = &vam->elog_main;
20118   unformat_input_t *i = vam->input;
20119   char *file, *chroot_file;
20120   clib_error_t *error;
20121
20122   if (!unformat (i, "%s", &file))
20123     {
20124       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20125       return 0;
20126     }
20127
20128   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20129   if (strstr (file, "..") || index (file, '/'))
20130     {
20131       errmsg ("illegal characters in filename '%s'", file);
20132       return 0;
20133     }
20134
20135   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20136
20137   vec_free (file);
20138
20139   errmsg ("Saving %wd of %wd events to %s",
20140           elog_n_events_in_buffer (em),
20141           elog_buffer_capacity (em), chroot_file);
20142
20143   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20144   vec_free (chroot_file);
20145
20146   if (error)
20147     clib_error_report (error);
20148 #else
20149   errmsg ("Use the vpp event loger...");
20150 #endif
20151
20152   return 0;
20153 }
20154
20155 static int
20156 elog_setup (vat_main_t * vam)
20157 {
20158 #if VPP_API_TEST_BUILTIN == 0
20159   elog_main_t *em = &vam->elog_main;
20160   unformat_input_t *i = vam->input;
20161   u32 nevents = 128 << 10;
20162
20163   (void) unformat (i, "nevents %d", &nevents);
20164
20165   elog_init (em, nevents);
20166   vl_api_set_elog_main (em);
20167   vl_api_set_elog_trace_api_messages (1);
20168   errmsg ("Event logger initialized with %u events", nevents);
20169 #else
20170   errmsg ("Use the vpp event loger...");
20171 #endif
20172   return 0;
20173 }
20174
20175 static int
20176 elog_enable (vat_main_t * vam)
20177 {
20178 #if VPP_API_TEST_BUILTIN == 0
20179   elog_main_t *em = &vam->elog_main;
20180
20181   elog_enable_disable (em, 1 /* enable */ );
20182   vl_api_set_elog_trace_api_messages (1);
20183   errmsg ("Event logger enabled...");
20184 #else
20185   errmsg ("Use the vpp event loger...");
20186 #endif
20187   return 0;
20188 }
20189
20190 static int
20191 elog_disable (vat_main_t * vam)
20192 {
20193 #if VPP_API_TEST_BUILTIN == 0
20194   elog_main_t *em = &vam->elog_main;
20195
20196   elog_enable_disable (em, 0 /* enable */ );
20197   vl_api_set_elog_trace_api_messages (1);
20198   errmsg ("Event logger disabled...");
20199 #else
20200   errmsg ("Use the vpp event loger...");
20201 #endif
20202   return 0;
20203 }
20204
20205 static int
20206 statseg (vat_main_t * vam)
20207 {
20208   ssvm_private_t *ssvmp = &vam->stat_segment;
20209   ssvm_shared_header_t *shared_header = ssvmp->sh;
20210   vlib_counter_t **counters;
20211   u64 thread0_index1_packets;
20212   u64 thread0_index1_bytes;
20213   f64 vector_rate, input_rate;
20214   uword *p;
20215
20216   uword *counter_vector_by_name;
20217   if (vam->stat_segment_lockp == 0)
20218     {
20219       errmsg ("Stat segment not mapped...");
20220       return -99;
20221     }
20222
20223   /* look up "/if/rx for sw_if_index 1 as a test */
20224
20225   clib_spinlock_lock (vam->stat_segment_lockp);
20226
20227   counter_vector_by_name = (uword *) shared_header->opaque[1];
20228
20229   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20230   if (p == 0)
20231     {
20232       clib_spinlock_unlock (vam->stat_segment_lockp);
20233       errmsg ("/if/tx not found?");
20234       return -99;
20235     }
20236
20237   /* Fish per-thread vector of combined counters from shared memory */
20238   counters = (vlib_counter_t **) p[0];
20239
20240   if (vec_len (counters[0]) < 2)
20241     {
20242       clib_spinlock_unlock (vam->stat_segment_lockp);
20243       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20244       return -99;
20245     }
20246
20247   /* Read thread 0 sw_if_index 1 counter */
20248   thread0_index1_packets = counters[0][1].packets;
20249   thread0_index1_bytes = counters[0][1].bytes;
20250
20251   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20252   if (p == 0)
20253     {
20254       clib_spinlock_unlock (vam->stat_segment_lockp);
20255       errmsg ("vector_rate not found?");
20256       return -99;
20257     }
20258
20259   vector_rate = *(f64 *) (p[0]);
20260   p = hash_get_mem (counter_vector_by_name, "input_rate");
20261   if (p == 0)
20262     {
20263       clib_spinlock_unlock (vam->stat_segment_lockp);
20264       errmsg ("input_rate not found?");
20265       return -99;
20266     }
20267   input_rate = *(f64 *) (p[0]);
20268
20269   clib_spinlock_unlock (vam->stat_segment_lockp);
20270
20271   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20272          vector_rate, input_rate);
20273   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20274          thread0_index1_packets, thread0_index1_bytes);
20275
20276   return 0;
20277 }
20278
20279 static int
20280 cmd_cmp (void *a1, void *a2)
20281 {
20282   u8 **c1 = a1;
20283   u8 **c2 = a2;
20284
20285   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20286 }
20287
20288 static int
20289 help (vat_main_t * vam)
20290 {
20291   u8 **cmds = 0;
20292   u8 *name = 0;
20293   hash_pair_t *p;
20294   unformat_input_t *i = vam->input;
20295   int j;
20296
20297   if (unformat (i, "%s", &name))
20298     {
20299       uword *hs;
20300
20301       vec_add1 (name, 0);
20302
20303       hs = hash_get_mem (vam->help_by_name, name);
20304       if (hs)
20305         print (vam->ofp, "usage: %s %s", name, hs[0]);
20306       else
20307         print (vam->ofp, "No such msg / command '%s'", name);
20308       vec_free (name);
20309       return 0;
20310     }
20311
20312   print (vam->ofp, "Help is available for the following:");
20313
20314     /* *INDENT-OFF* */
20315     hash_foreach_pair (p, vam->function_by_name,
20316     ({
20317       vec_add1 (cmds, (u8 *)(p->key));
20318     }));
20319     /* *INDENT-ON* */
20320
20321   vec_sort_with_function (cmds, cmd_cmp);
20322
20323   for (j = 0; j < vec_len (cmds); j++)
20324     print (vam->ofp, "%s", cmds[j]);
20325
20326   vec_free (cmds);
20327   return 0;
20328 }
20329
20330 static int
20331 set (vat_main_t * vam)
20332 {
20333   u8 *name = 0, *value = 0;
20334   unformat_input_t *i = vam->input;
20335
20336   if (unformat (i, "%s", &name))
20337     {
20338       /* The input buffer is a vector, not a string. */
20339       value = vec_dup (i->buffer);
20340       vec_delete (value, i->index, 0);
20341       /* Almost certainly has a trailing newline */
20342       if (value[vec_len (value) - 1] == '\n')
20343         value[vec_len (value) - 1] = 0;
20344       /* Make sure it's a proper string, one way or the other */
20345       vec_add1 (value, 0);
20346       (void) clib_macro_set_value (&vam->macro_main,
20347                                    (char *) name, (char *) value);
20348     }
20349   else
20350     errmsg ("usage: set <name> <value>");
20351
20352   vec_free (name);
20353   vec_free (value);
20354   return 0;
20355 }
20356
20357 static int
20358 unset (vat_main_t * vam)
20359 {
20360   u8 *name = 0;
20361
20362   if (unformat (vam->input, "%s", &name))
20363     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20364       errmsg ("unset: %s wasn't set", name);
20365   vec_free (name);
20366   return 0;
20367 }
20368
20369 typedef struct
20370 {
20371   u8 *name;
20372   u8 *value;
20373 } macro_sort_t;
20374
20375
20376 static int
20377 macro_sort_cmp (void *a1, void *a2)
20378 {
20379   macro_sort_t *s1 = a1;
20380   macro_sort_t *s2 = a2;
20381
20382   return strcmp ((char *) (s1->name), (char *) (s2->name));
20383 }
20384
20385 static int
20386 dump_macro_table (vat_main_t * vam)
20387 {
20388   macro_sort_t *sort_me = 0, *sm;
20389   int i;
20390   hash_pair_t *p;
20391
20392     /* *INDENT-OFF* */
20393     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20394     ({
20395       vec_add2 (sort_me, sm, 1);
20396       sm->name = (u8 *)(p->key);
20397       sm->value = (u8 *) (p->value[0]);
20398     }));
20399     /* *INDENT-ON* */
20400
20401   vec_sort_with_function (sort_me, macro_sort_cmp);
20402
20403   if (vec_len (sort_me))
20404     print (vam->ofp, "%-15s%s", "Name", "Value");
20405   else
20406     print (vam->ofp, "The macro table is empty...");
20407
20408   for (i = 0; i < vec_len (sort_me); i++)
20409     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20410   return 0;
20411 }
20412
20413 static int
20414 dump_node_table (vat_main_t * vam)
20415 {
20416   int i, j;
20417   vlib_node_t *node, *next_node;
20418
20419   if (vec_len (vam->graph_nodes) == 0)
20420     {
20421       print (vam->ofp, "Node table empty, issue get_node_graph...");
20422       return 0;
20423     }
20424
20425   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20426     {
20427       node = vam->graph_nodes[0][i];
20428       print (vam->ofp, "[%d] %s", i, node->name);
20429       for (j = 0; j < vec_len (node->next_nodes); j++)
20430         {
20431           if (node->next_nodes[j] != ~0)
20432             {
20433               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20434               print (vam->ofp, "  [%d] %s", j, next_node->name);
20435             }
20436         }
20437     }
20438   return 0;
20439 }
20440
20441 static int
20442 value_sort_cmp (void *a1, void *a2)
20443 {
20444   name_sort_t *n1 = a1;
20445   name_sort_t *n2 = a2;
20446
20447   if (n1->value < n2->value)
20448     return -1;
20449   if (n1->value > n2->value)
20450     return 1;
20451   return 0;
20452 }
20453
20454
20455 static int
20456 dump_msg_api_table (vat_main_t * vam)
20457 {
20458   api_main_t *am = vlibapi_get_main ();
20459   name_sort_t *nses = 0, *ns;
20460   hash_pair_t *hp;
20461   int i;
20462
20463   /* *INDENT-OFF* */
20464   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20465   ({
20466     vec_add2 (nses, ns, 1);
20467     ns->name = (u8 *)(hp->key);
20468     ns->value = (u32) hp->value[0];
20469   }));
20470   /* *INDENT-ON* */
20471
20472   vec_sort_with_function (nses, value_sort_cmp);
20473
20474   for (i = 0; i < vec_len (nses); i++)
20475     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20476   vec_free (nses);
20477   return 0;
20478 }
20479
20480 static int
20481 get_msg_id (vat_main_t * vam)
20482 {
20483   u8 *name_and_crc;
20484   u32 message_index;
20485
20486   if (unformat (vam->input, "%s", &name_and_crc))
20487     {
20488       message_index = vl_msg_api_get_msg_index (name_and_crc);
20489       if (message_index == ~0)
20490         {
20491           print (vam->ofp, " '%s' not found", name_and_crc);
20492           return 0;
20493         }
20494       print (vam->ofp, " '%s' has message index %d",
20495              name_and_crc, message_index);
20496       return 0;
20497     }
20498   errmsg ("name_and_crc required...");
20499   return 0;
20500 }
20501
20502 static int
20503 search_node_table (vat_main_t * vam)
20504 {
20505   unformat_input_t *line_input = vam->input;
20506   u8 *node_to_find;
20507   int j;
20508   vlib_node_t *node, *next_node;
20509   uword *p;
20510
20511   if (vam->graph_node_index_by_name == 0)
20512     {
20513       print (vam->ofp, "Node table empty, issue get_node_graph...");
20514       return 0;
20515     }
20516
20517   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20518     {
20519       if (unformat (line_input, "%s", &node_to_find))
20520         {
20521           vec_add1 (node_to_find, 0);
20522           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20523           if (p == 0)
20524             {
20525               print (vam->ofp, "%s not found...", node_to_find);
20526               goto out;
20527             }
20528           node = vam->graph_nodes[0][p[0]];
20529           print (vam->ofp, "[%d] %s", p[0], node->name);
20530           for (j = 0; j < vec_len (node->next_nodes); j++)
20531             {
20532               if (node->next_nodes[j] != ~0)
20533                 {
20534                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20535                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20536                 }
20537             }
20538         }
20539
20540       else
20541         {
20542           clib_warning ("parse error '%U'", format_unformat_error,
20543                         line_input);
20544           return -99;
20545         }
20546
20547     out:
20548       vec_free (node_to_find);
20549
20550     }
20551
20552   return 0;
20553 }
20554
20555
20556 static int
20557 script (vat_main_t * vam)
20558 {
20559 #if (VPP_API_TEST_BUILTIN==0)
20560   u8 *s = 0;
20561   char *save_current_file;
20562   unformat_input_t save_input;
20563   jmp_buf save_jump_buf;
20564   u32 save_line_number;
20565
20566   FILE *new_fp, *save_ifp;
20567
20568   if (unformat (vam->input, "%s", &s))
20569     {
20570       new_fp = fopen ((char *) s, "r");
20571       if (new_fp == 0)
20572         {
20573           errmsg ("Couldn't open script file %s", s);
20574           vec_free (s);
20575           return -99;
20576         }
20577     }
20578   else
20579     {
20580       errmsg ("Missing script name");
20581       return -99;
20582     }
20583
20584   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20585   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20586   save_ifp = vam->ifp;
20587   save_line_number = vam->input_line_number;
20588   save_current_file = (char *) vam->current_file;
20589
20590   vam->input_line_number = 0;
20591   vam->ifp = new_fp;
20592   vam->current_file = s;
20593   do_one_file (vam);
20594
20595   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20596   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20597   vam->ifp = save_ifp;
20598   vam->input_line_number = save_line_number;
20599   vam->current_file = (u8 *) save_current_file;
20600   vec_free (s);
20601
20602   return 0;
20603 #else
20604   clib_warning ("use the exec command...");
20605   return -99;
20606 #endif
20607 }
20608
20609 static int
20610 echo (vat_main_t * vam)
20611 {
20612   print (vam->ofp, "%v", vam->input->buffer);
20613   return 0;
20614 }
20615
20616 /* List of API message constructors, CLI names map to api_xxx */
20617 #define foreach_vpe_api_msg                                             \
20618 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20619 _(sw_interface_dump,"")                                                 \
20620 _(sw_interface_set_flags,                                               \
20621   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20622 _(sw_interface_add_del_address,                                         \
20623   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20624 _(sw_interface_set_rx_mode,                                             \
20625   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20626 _(sw_interface_set_rx_placement,                                        \
20627   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20628 _(sw_interface_rx_placement_dump,                                       \
20629   "[<intfc> | sw_if_index <id>]")                                         \
20630 _(sw_interface_set_table,                                               \
20631   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20632 _(sw_interface_set_mpls_enable,                                         \
20633   "<intfc> | sw_if_index [disable | dis]")                              \
20634 _(sw_interface_set_vpath,                                               \
20635   "<intfc> | sw_if_index <id> enable | disable")                        \
20636 _(sw_interface_set_vxlan_bypass,                                        \
20637   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20638 _(sw_interface_set_geneve_bypass,                                       \
20639   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20640 _(sw_interface_set_l2_xconnect,                                         \
20641   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20642   "enable | disable")                                                   \
20643 _(sw_interface_set_l2_bridge,                                           \
20644   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20645   "[shg <split-horizon-group>] [bvi]\n"                                 \
20646   "enable | disable")                                                   \
20647 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20648 _(bridge_domain_add_del,                                                \
20649   "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") \
20650 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20651 _(l2fib_add_del,                                                        \
20652   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20653 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20654 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20655 _(l2_flags,                                                             \
20656   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20657 _(bridge_flags,                                                         \
20658   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20659 _(tap_create_v2,                                                        \
20660   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload] [persist] [attach]") \
20661 _(tap_delete_v2,                                                        \
20662   "<vpp-if-name> | sw_if_index <id>")                                   \
20663 _(sw_interface_tap_v2_dump, "")                                         \
20664 _(virtio_pci_create,                                                    \
20665   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20666 _(virtio_pci_delete,                                                    \
20667   "<vpp-if-name> | sw_if_index <id>")                                   \
20668 _(sw_interface_virtio_pci_dump, "")                                     \
20669 _(bond_create,                                                          \
20670   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20671   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20672   "[id <if-id>]")                                                       \
20673 _(bond_delete,                                                          \
20674   "<vpp-if-name> | sw_if_index <id>")                                   \
20675 _(bond_enslave,                                                         \
20676   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20677 _(bond_detach_slave,                                                    \
20678   "sw_if_index <n>")                                                    \
20679  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20680 _(sw_interface_bond_dump, "")                                           \
20681 _(sw_interface_slave_dump,                                              \
20682   "<vpp-if-name> | sw_if_index <id>")                                   \
20683 _(ip_table_add_del,                                                     \
20684   "table <n> [ipv6] [add | del]\n")                                     \
20685 _(ip_route_add_del,                                                     \
20686   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20687   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20688   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20689   "[multipath] [count <n>] [del]")                                      \
20690 _(ip_mroute_add_del,                                                    \
20691   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20692   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20693 _(mpls_table_add_del,                                                   \
20694   "table <n> [add | del]\n")                                            \
20695 _(mpls_route_add_del,                                                   \
20696   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20697   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20698   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20699   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20700   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20701   "[count <n>] [del]")                                                  \
20702 _(mpls_ip_bind_unbind,                                                  \
20703   "<label> <addr/len>")                                                 \
20704 _(mpls_tunnel_add_del,                                                  \
20705   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20706   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20707   "[l2-only]  [out-label <n>]")                                         \
20708 _(sr_mpls_policy_add,                                                   \
20709   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20710 _(sr_mpls_policy_del,                                                   \
20711   "bsid <id>")                                                          \
20712 _(bier_table_add_del,                                                   \
20713   "<label> <sub-domain> <set> <bsl> [del]")                             \
20714 _(bier_route_add_del,                                                   \
20715   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20716   "[<intfc> | sw_if_index <id>]"                                        \
20717   "[weight <n>] [del] [multipath]")                                     \
20718 _(sw_interface_set_unnumbered,                                          \
20719   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20720 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20721 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20722   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20723   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20724   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20725 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20726 _(ip_table_flush, "table <n> [ipv6]")                                   \
20727 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20728 _(set_ip_flow_hash,                                                     \
20729   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20730 _(sw_interface_ip6_enable_disable,                                      \
20731   "<intfc> | sw_if_index <id> enable | disable")                        \
20732 _(l2_patch_add_del,                                                     \
20733   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20734   "enable | disable")                                                   \
20735 _(sr_localsid_add_del,                                                  \
20736   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20737   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20738 _(classify_add_del_table,                                               \
20739   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20740   " [del] [del-chain] mask <mask-value>\n"                              \
20741   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20742   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20743 _(classify_add_del_session,                                             \
20744   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20745   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20746   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20747   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20748 _(classify_set_interface_ip_table,                                      \
20749   "<intfc> | sw_if_index <nn> table <nn>")                              \
20750 _(classify_set_interface_l2_tables,                                     \
20751   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20752   "  [other-table <nn>]")                                               \
20753 _(get_node_index, "node <node-name")                                    \
20754 _(add_node_next, "node <node-name> next <next-node-name>")              \
20755 _(l2tpv3_create_tunnel,                                                 \
20756   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20757   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20758   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20759 _(l2tpv3_set_tunnel_cookies,                                            \
20760   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20761   "[new_remote_cookie <nn>]\n")                                         \
20762 _(l2tpv3_interface_enable_disable,                                      \
20763   "<intfc> | sw_if_index <nn> enable | disable")                        \
20764 _(l2tpv3_set_lookup_key,                                                \
20765   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20766 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20767 _(vxlan_offload_rx,                                                     \
20768   "hw { <interface name> | hw_if_index <nn>} "                          \
20769   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20770 _(vxlan_add_del_tunnel,                                                 \
20771   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20772   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20773   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20774 _(geneve_add_del_tunnel,                                                \
20775   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20776   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20777   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20778 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20779 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20780 _(gre_tunnel_add_del,                                                   \
20781   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20782   "[teb | erspan <session-id>] [del]")                                  \
20783 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20784 _(l2_fib_clear_table, "")                                               \
20785 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20786 _(l2_interface_vlan_tag_rewrite,                                        \
20787   "<intfc> | sw_if_index <nn> \n"                                       \
20788   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20789   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20790 _(create_vhost_user_if,                                                 \
20791         "socket <filename> [server] [renumber <dev_instance>] "         \
20792         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20793         "[mac <mac_address>] [packed]")                                 \
20794 _(modify_vhost_user_if,                                                 \
20795         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20796         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20797 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20798 _(sw_interface_vhost_user_dump, "")                                     \
20799 _(show_version, "")                                                     \
20800 _(show_threads, "")                                                     \
20801 _(vxlan_gpe_add_del_tunnel,                                             \
20802   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20803   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20804   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20805   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20806 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20807 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20808 _(interface_name_renumber,                                              \
20809   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20810 _(input_acl_set_interface,                                              \
20811   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20812   "  [l2-table <nn>] [del]")                                            \
20813 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20814 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20815 _(ip_dump, "ipv4 | ipv6")                                               \
20816 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20817 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20818   "  spid_id <n> ")                                                     \
20819 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20820   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20821   "  integ_alg <alg> integ_key <hex>")                                  \
20822 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20823   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20824   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20825   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20826 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20827   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20828   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20829   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20830   "  [instance <n>]")     \
20831 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20832 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20833 _(delete_loopback,"sw_if_index <nn>")                                   \
20834 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20835 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20836 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20837 _(want_interface_events,  "enable|disable")                             \
20838 _(get_first_msg_id, "client <name>")                                    \
20839 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20840 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20841   "fib-id <nn> [ip4][ip6][default]")                                    \
20842 _(get_node_graph, " ")                                                  \
20843 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20844 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20845 _(ioam_disable, "")                                                     \
20846 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20847                             " sw_if_index <sw_if_index> p <priority> "  \
20848                             "w <weight>] [del]")                        \
20849 _(one_add_del_locator, "locator-set <locator_name> "                    \
20850                         "iface <intf> | sw_if_index <sw_if_index> "     \
20851                         "p <priority> w <weight> [del]")                \
20852 _(one_add_del_local_eid,"vni <vni> eid "                                \
20853                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20854                          "locator-set <locator_name> [del]"             \
20855                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20856 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20857 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20858 _(one_enable_disable, "enable|disable")                                 \
20859 _(one_map_register_enable_disable, "enable|disable")                    \
20860 _(one_map_register_fallback_threshold, "<value>")                       \
20861 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20862 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20863                                "[seid <seid>] "                         \
20864                                "rloc <locator> p <prio> "               \
20865                                "w <weight> [rloc <loc> ... ] "          \
20866                                "action <action> [del-all]")             \
20867 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20868                           "<local-eid>")                                \
20869 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20870 _(one_use_petr, "ip-address> | disable")                                \
20871 _(one_map_request_mode, "src-dst|dst-only")                             \
20872 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20873 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20874 _(one_locator_set_dump, "[local | remote]")                             \
20875 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20876 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20877                        "[local] | [remote]")                            \
20878 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20879 _(one_ndp_bd_get, "")                                                   \
20880 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20881 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20882 _(one_l2_arp_bd_get, "")                                                \
20883 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20884 _(one_stats_enable_disable, "enable|disable")                           \
20885 _(show_one_stats_enable_disable, "")                                    \
20886 _(one_eid_table_vni_dump, "")                                           \
20887 _(one_eid_table_map_dump, "l2|l3")                                      \
20888 _(one_map_resolver_dump, "")                                            \
20889 _(one_map_server_dump, "")                                              \
20890 _(one_adjacencies_get, "vni <vni>")                                     \
20891 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20892 _(show_one_rloc_probe_state, "")                                        \
20893 _(show_one_map_register_state, "")                                      \
20894 _(show_one_status, "")                                                  \
20895 _(one_stats_dump, "")                                                   \
20896 _(one_stats_flush, "")                                                  \
20897 _(one_get_map_request_itr_rlocs, "")                                    \
20898 _(one_map_register_set_ttl, "<ttl>")                                    \
20899 _(one_set_transport_protocol, "udp|api")                                \
20900 _(one_get_transport_protocol, "")                                       \
20901 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20902 _(one_show_xtr_mode, "")                                                \
20903 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20904 _(one_show_pitr_mode, "")                                               \
20905 _(one_enable_disable_petr_mode, "enable|disable")                       \
20906 _(one_show_petr_mode, "")                                               \
20907 _(show_one_nsh_mapping, "")                                             \
20908 _(show_one_pitr, "")                                                    \
20909 _(show_one_use_petr, "")                                                \
20910 _(show_one_map_request_mode, "")                                        \
20911 _(show_one_map_register_ttl, "")                                        \
20912 _(show_one_map_register_fallback_threshold, "")                         \
20913 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20914                             " sw_if_index <sw_if_index> p <priority> "  \
20915                             "w <weight>] [del]")                        \
20916 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20917                         "iface <intf> | sw_if_index <sw_if_index> "     \
20918                         "p <priority> w <weight> [del]")                \
20919 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20920                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20921                          "locator-set <locator_name> [del]"             \
20922                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20923 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20924 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20925 _(lisp_enable_disable, "enable|disable")                                \
20926 _(lisp_map_register_enable_disable, "enable|disable")                   \
20927 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20928 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20929                                "[seid <seid>] "                         \
20930                                "rloc <locator> p <prio> "               \
20931                                "w <weight> [rloc <loc> ... ] "          \
20932                                "action <action> [del-all]")             \
20933 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20934                           "<local-eid>")                                \
20935 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20936 _(lisp_use_petr, "<ip-address> | disable")                              \
20937 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20938 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20939 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20940 _(lisp_locator_set_dump, "[local | remote]")                            \
20941 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20942 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20943                        "[local] | [remote]")                            \
20944 _(lisp_eid_table_vni_dump, "")                                          \
20945 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20946 _(lisp_map_resolver_dump, "")                                           \
20947 _(lisp_map_server_dump, "")                                             \
20948 _(lisp_adjacencies_get, "vni <vni>")                                    \
20949 _(gpe_fwd_entry_vnis_get, "")                                           \
20950 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20951 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20952                                 "[table <table-id>]")                   \
20953 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20954 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20955 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20956 _(gpe_get_encap_mode, "")                                               \
20957 _(lisp_gpe_add_del_iface, "up|down")                                    \
20958 _(lisp_gpe_enable_disable, "enable|disable")                            \
20959 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20960   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20961 _(show_lisp_rloc_probe_state, "")                                       \
20962 _(show_lisp_map_register_state, "")                                     \
20963 _(show_lisp_status, "")                                                 \
20964 _(lisp_get_map_request_itr_rlocs, "")                                   \
20965 _(show_lisp_pitr, "")                                                   \
20966 _(show_lisp_use_petr, "")                                               \
20967 _(show_lisp_map_request_mode, "")                                       \
20968 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20969 _(af_packet_delete, "name <host interface name>")                       \
20970 _(af_packet_dump, "")                                                   \
20971 _(policer_add_del, "name <policer name> <params> [del]")                \
20972 _(policer_dump, "[name <policer name>]")                                \
20973 _(policer_classify_set_interface,                                       \
20974   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20975   "  [l2-table <nn>] [del]")                                            \
20976 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20977 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20978 _(mpls_table_dump, "")                                                  \
20979 _(mpls_route_dump, "table-id <ID>")                                     \
20980 _(classify_table_ids, "")                                               \
20981 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20982 _(classify_table_info, "table_id <nn>")                                 \
20983 _(classify_session_dump, "table_id <nn>")                               \
20984 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20985     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20986     "[template_interval <nn>] [udp_checksum]")                          \
20987 _(ipfix_exporter_dump, "")                                              \
20988 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20989 _(ipfix_classify_stream_dump, "")                                       \
20990 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20991 _(ipfix_classify_table_dump, "")                                        \
20992 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20993 _(sw_interface_span_dump, "[l2]")                                           \
20994 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20995 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20996 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20997 _(pg_enable_disable, "[stream <id>] disable")                           \
20998 _(ip_source_and_port_range_check_add_del,                               \
20999   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21000 _(ip_source_and_port_range_check_interface_add_del,                     \
21001   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21002   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21003 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21004 _(l2_interface_pbb_tag_rewrite,                                         \
21005   "<intfc> | sw_if_index <nn> \n"                                       \
21006   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21007   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21008 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21009 _(flow_classify_set_interface,                                          \
21010   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21011 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21012 _(ip_table_dump, "")                                                    \
21013 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21014 _(ip_mtable_dump, "")                                                   \
21015 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21016 _(feature_enable_disable, "arc_name <arc_name> "                        \
21017   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21018 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21019   "[enable | disable] ")                                                \
21020 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21021 "[disable]")                                                            \
21022 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21023   "mac <mac-address> [del]")                                            \
21024 _(l2_xconnect_dump, "")                                                 \
21025 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21026 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21027 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21028 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21029 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21030 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21031   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21032 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21033 _(sock_init_shm, "size <nnn>")                                          \
21034 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21035 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21036   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21037 _(session_rules_dump, "")                                               \
21038 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21039 _(output_acl_set_interface,                                             \
21040   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21041   "  [l2-table <nn>] [del]")                                            \
21042 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21043
21044 /* List of command functions, CLI names map directly to functions */
21045 #define foreach_cli_function                                    \
21046 _(comment, "usage: comment <ignore-rest-of-line>")              \
21047 _(dump_interface_table, "usage: dump_interface_table")          \
21048 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21049 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21050 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21051 _(dump_macro_table, "usage: dump_macro_table ")                 \
21052 _(dump_node_table, "usage: dump_node_table")                    \
21053 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21054 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21055 _(elog_disable, "usage: elog_disable")                          \
21056 _(elog_enable, "usage: elog_enable")                            \
21057 _(elog_save, "usage: elog_save <filename>")                     \
21058 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21059 _(echo, "usage: echo <message>")                                \
21060 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21061 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21062 _(help, "usage: help")                                          \
21063 _(q, "usage: quit")                                             \
21064 _(quit, "usage: quit")                                          \
21065 _(search_node_table, "usage: search_node_table <name>...")      \
21066 _(set, "usage: set <variable-name> <value>")                    \
21067 _(script, "usage: script <file-name>")                          \
21068 _(statseg, "usage: statseg")                                    \
21069 _(unset, "usage: unset <variable-name>")
21070
21071 #define _(N,n)                                  \
21072     static void vl_api_##n##_t_handler_uni      \
21073     (vl_api_##n##_t * mp)                       \
21074     {                                           \
21075         vat_main_t * vam = &vat_main;           \
21076         if (vam->json_output) {                 \
21077             vl_api_##n##_t_handler_json(mp);    \
21078         } else {                                \
21079             vl_api_##n##_t_handler(mp);         \
21080         }                                       \
21081     }
21082 foreach_vpe_api_reply_msg;
21083 #if VPP_API_TEST_BUILTIN == 0
21084 foreach_standalone_reply_msg;
21085 #endif
21086 #undef _
21087
21088 void
21089 vat_api_hookup (vat_main_t * vam)
21090 {
21091 #define _(N,n)                                                  \
21092     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21093                            vl_api_##n##_t_handler_uni,          \
21094                            vl_noop_handler,                     \
21095                            vl_api_##n##_t_endian,               \
21096                            vl_api_##n##_t_print,                \
21097                            sizeof(vl_api_##n##_t), 1);
21098   foreach_vpe_api_reply_msg;
21099 #if VPP_API_TEST_BUILTIN == 0
21100   foreach_standalone_reply_msg;
21101 #endif
21102 #undef _
21103
21104 #if (VPP_API_TEST_BUILTIN==0)
21105   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21106
21107   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21108
21109   vam->function_by_name = hash_create_string (0, sizeof (uword));
21110
21111   vam->help_by_name = hash_create_string (0, sizeof (uword));
21112 #endif
21113
21114   /* API messages we can send */
21115 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21116   foreach_vpe_api_msg;
21117 #undef _
21118
21119   /* Help strings */
21120 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21121   foreach_vpe_api_msg;
21122 #undef _
21123
21124   /* CLI functions */
21125 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21126   foreach_cli_function;
21127 #undef _
21128
21129   /* Help strings */
21130 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21131   foreach_cli_function;
21132 #undef _
21133 }
21134
21135 #if VPP_API_TEST_BUILTIN
21136 static clib_error_t *
21137 vat_api_hookup_shim (vlib_main_t * vm)
21138 {
21139   vat_api_hookup (&vat_main);
21140   return 0;
21141 }
21142
21143 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21144 #endif
21145
21146 /*
21147  * fd.io coding-style-patch-verification: ON
21148  *
21149  * Local Variables:
21150  * eval: (c-set-style "gnu")
21151  * End:
21152  */