virtio: add vhost sw_if_index filter for sw_interface_vhost_user_dump
[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, &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, &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                   format_ip46_address,
2807                   mp->ip_address, mp->priority, mp->weight);
2808     }
2809
2810   print (vam->ofp, "%v", s);
2811   vec_free (s);
2812 }
2813
2814 static void
2815 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2816 {
2817   vat_main_t *vam = &vat_main;
2818   vat_json_node_t *node = NULL;
2819   struct in6_addr ip6;
2820   struct in_addr ip4;
2821
2822   if (VAT_JSON_ARRAY != vam->json_tree.type)
2823     {
2824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2825       vat_json_init_array (&vam->json_tree);
2826     }
2827   node = vat_json_array_add (&vam->json_tree);
2828   vat_json_init_object (node);
2829
2830   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2831   vat_json_object_add_uint (node, "priority", mp->priority);
2832   vat_json_object_add_uint (node, "weight", mp->weight);
2833
2834   if (mp->local)
2835     vat_json_object_add_uint (node, "sw_if_index",
2836                               clib_net_to_host_u32 (mp->sw_if_index));
2837   else
2838     {
2839       if (mp->ip_address.af)
2840         {
2841           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2842           vat_json_object_add_ip6 (node, "address", ip6);
2843         }
2844       else
2845         {
2846           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2847           vat_json_object_add_ip4 (node, "address", ip4);
2848         }
2849     }
2850 }
2851
2852 static void
2853 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2854                                           mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   u8 *ls_name = 0;
2858
2859   ls_name = format (0, "%s", mp->ls_name);
2860
2861   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2862          ls_name);
2863   vec_free (ls_name);
2864 }
2865
2866 static void
2867   vl_api_one_locator_set_details_t_handler_json
2868   (vl_api_one_locator_set_details_t * mp)
2869 {
2870   vat_main_t *vam = &vat_main;
2871   vat_json_node_t *node = 0;
2872   u8 *ls_name = 0;
2873
2874   ls_name = format (0, "%s", mp->ls_name);
2875   vec_add1 (ls_name, 0);
2876
2877   if (VAT_JSON_ARRAY != vam->json_tree.type)
2878     {
2879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2880       vat_json_init_array (&vam->json_tree);
2881     }
2882   node = vat_json_array_add (&vam->json_tree);
2883
2884   vat_json_init_object (node);
2885   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2886   vat_json_object_add_uint (node, "ls_index",
2887                             clib_net_to_host_u32 (mp->ls_index));
2888   vec_free (ls_name);
2889 }
2890
2891 typedef struct
2892 {
2893   u32 spi;
2894   u8 si;
2895 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2896
2897 uword
2898 unformat_nsh_address (unformat_input_t * input, va_list * args)
2899 {
2900   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2901   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2902 }
2903
2904 static u8 *
2905 format_nsh_address_vat (u8 * s, va_list * args)
2906 {
2907   nsh_t *a = va_arg (*args, nsh_t *);
2908   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2909 }
2910
2911 static u8 *
2912 format_lisp_flat_eid (u8 * s, va_list * args)
2913 {
2914   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2915
2916   switch (eid->type)
2917     {
2918     case EID_TYPE_API_PREFIX:
2919       if (eid->address.prefix.address.af)
2920         return format (s, "%U/%d", format_ip6_address,
2921                        eid->address.prefix.address.un.ip6,
2922                        eid->address.prefix.len);
2923       return format (s, "%U/%d", format_ip4_address,
2924                      eid->address.prefix.address.un.ip4,
2925                      eid->address.prefix.len);
2926     case EID_TYPE_API_MAC:
2927       return format (s, "%U", format_ethernet_address, eid->address.mac);
2928     case EID_TYPE_API_NSH:
2929       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2930     }
2931   return 0;
2932 }
2933
2934 static u8 *
2935 format_lisp_eid_vat (u8 * s, va_list * args)
2936 {
2937   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2938   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2939   u8 is_src_dst = (u8) va_arg (*args, int);
2940
2941   if (is_src_dst)
2942     s = format (s, "%U|", format_lisp_flat_eid, seid);
2943
2944   s = format (s, "%U", format_lisp_flat_eid, deid);
2945
2946   return s;
2947 }
2948
2949 static void
2950 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   u8 *s = 0, *eid = 0;
2954
2955   if (~0 == mp->locator_set_index)
2956     s = format (0, "action: %d", mp->action);
2957   else
2958     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2959
2960   eid = format (0, "%U", format_lisp_eid_vat,
2961                 &mp->deid, &mp->seid, mp->is_src_dst);
2962   vec_add1 (eid, 0);
2963
2964   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2965          clib_net_to_host_u32 (mp->vni),
2966          eid,
2967          mp->is_local ? "local" : "remote",
2968          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2969          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2970
2971   vec_free (s);
2972   vec_free (eid);
2973 }
2974
2975 static void
2976 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2977                                              * mp)
2978 {
2979   vat_main_t *vam = &vat_main;
2980   vat_json_node_t *node = 0;
2981   u8 *eid = 0;
2982
2983   if (VAT_JSON_ARRAY != vam->json_tree.type)
2984     {
2985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2986       vat_json_init_array (&vam->json_tree);
2987     }
2988   node = vat_json_array_add (&vam->json_tree);
2989
2990   vat_json_init_object (node);
2991   if (~0 == mp->locator_set_index)
2992     vat_json_object_add_uint (node, "action", mp->action);
2993   else
2994     vat_json_object_add_uint (node, "locator_set_index",
2995                               clib_net_to_host_u32 (mp->locator_set_index));
2996
2997   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2998   if (mp->deid.type == 3)
2999     {
3000       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3001       vat_json_init_object (nsh_json);
3002       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3003       vat_json_object_add_uint (nsh_json, "spi",
3004                                 clib_net_to_host_u32 (nsh->spi));
3005       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3006     }
3007   else
3008     {
3009       eid = format (0, "%U", format_lisp_eid_vat,
3010                     &mp->deid, &mp->seid, mp->is_src_dst);
3011       vec_add1 (eid, 0);
3012       vat_json_object_add_string_copy (node, "eid", eid);
3013       vec_free (eid);
3014     }
3015   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3016   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3017   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3018
3019   if (mp->key.id)
3020     {
3021       vat_json_object_add_uint (node, "key_id",
3022                                 clib_net_to_host_u16 (mp->key.id));
3023       vat_json_object_add_string_copy (node, "key", mp->key.key);
3024     }
3025 }
3026
3027 static void
3028 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   u8 *seid = 0, *deid = 0;
3032   ip46_address_t lloc, rloc;
3033
3034   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3035
3036   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3037
3038   vec_add1 (deid, 0);
3039   vec_add1 (seid, 0);
3040
3041   if (mp->lloc.af)
3042     {
3043       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3044       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3045     }
3046   else
3047     {
3048       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3049       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3050     }
3051
3052
3053   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3054          clib_net_to_host_u32 (mp->vni),
3055          seid, deid,
3056          format_ip46_address, lloc,
3057          format_ip46_address, rloc,
3058          clib_net_to_host_u32 (mp->pkt_count),
3059          clib_net_to_host_u32 (mp->bytes));
3060
3061   vec_free (deid);
3062   vec_free (seid);
3063 }
3064
3065 static void
3066 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3067 {
3068   struct in6_addr ip6;
3069   struct in_addr ip4;
3070   vat_main_t *vam = &vat_main;
3071   vat_json_node_t *node = 0;
3072   u8 *deid = 0, *seid = 0;
3073
3074   if (VAT_JSON_ARRAY != vam->json_tree.type)
3075     {
3076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3077       vat_json_init_array (&vam->json_tree);
3078     }
3079   node = vat_json_array_add (&vam->json_tree);
3080
3081   vat_json_init_object (node);
3082   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3083
3084   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3085
3086   vec_add1 (deid, 0);
3087   vec_add1 (seid, 0);
3088
3089   vat_json_object_add_string_copy (node, "seid", seid);
3090   vat_json_object_add_string_copy (node, "deid", deid);
3091   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3092
3093   if (mp->lloc.af)
3094     {
3095       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3096       vat_json_object_add_ip6 (node, "lloc", ip6);
3097       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3098       vat_json_object_add_ip6 (node, "rloc", ip6);
3099
3100     }
3101   else
3102     {
3103       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3104       vat_json_object_add_ip4 (node, "lloc", ip4);
3105       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3106       vat_json_object_add_ip4 (node, "rloc", ip4);
3107     }
3108   vat_json_object_add_uint (node, "pkt_count",
3109                             clib_net_to_host_u32 (mp->pkt_count));
3110   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3111
3112   vec_free (deid);
3113   vec_free (seid);
3114 }
3115
3116 static void
3117   vl_api_one_eid_table_map_details_t_handler
3118   (vl_api_one_eid_table_map_details_t * mp)
3119 {
3120   vat_main_t *vam = &vat_main;
3121
3122   u8 *line = format (0, "%=10d%=10d",
3123                      clib_net_to_host_u32 (mp->vni),
3124                      clib_net_to_host_u32 (mp->dp_table));
3125   print (vam->ofp, "%v", line);
3126   vec_free (line);
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_map_details_t_handler_json
3131   (vl_api_one_eid_table_map_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134   vat_json_node_t *node = NULL;
3135
3136   if (VAT_JSON_ARRAY != vam->json_tree.type)
3137     {
3138       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3139       vat_json_init_array (&vam->json_tree);
3140     }
3141   node = vat_json_array_add (&vam->json_tree);
3142   vat_json_init_object (node);
3143   vat_json_object_add_uint (node, "dp_table",
3144                             clib_net_to_host_u32 (mp->dp_table));
3145   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3146 }
3147
3148 static void
3149   vl_api_one_eid_table_vni_details_t_handler
3150   (vl_api_one_eid_table_vni_details_t * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153
3154   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3155   print (vam->ofp, "%v", line);
3156   vec_free (line);
3157 }
3158
3159 static void
3160   vl_api_one_eid_table_vni_details_t_handler_json
3161   (vl_api_one_eid_table_vni_details_t * mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164   vat_json_node_t *node = NULL;
3165
3166   if (VAT_JSON_ARRAY != vam->json_tree.type)
3167     {
3168       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3169       vat_json_init_array (&vam->json_tree);
3170     }
3171   node = vat_json_array_add (&vam->json_tree);
3172   vat_json_init_object (node);
3173   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3174 }
3175
3176 static void
3177   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3178   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   int retval = clib_net_to_host_u32 (mp->retval);
3182
3183   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3184   print (vam->ofp, "fallback threshold value: %d", mp->value);
3185
3186   vam->retval = retval;
3187   vam->result_ready = 1;
3188 }
3189
3190 static void
3191   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3192   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3193 {
3194   vat_main_t *vam = &vat_main;
3195   vat_json_node_t _node, *node = &_node;
3196   int retval = clib_net_to_host_u32 (mp->retval);
3197
3198   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3199   vat_json_init_object (node);
3200   vat_json_object_add_uint (node, "value", mp->value);
3201
3202   vat_json_print (vam->ofp, node);
3203   vat_json_free (node);
3204
3205   vam->retval = retval;
3206   vam->result_ready = 1;
3207 }
3208
3209 static void
3210   vl_api_show_one_map_register_state_reply_t_handler
3211   (vl_api_show_one_map_register_state_reply_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   int retval = clib_net_to_host_u32 (mp->retval);
3215
3216   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3217
3218   vam->retval = retval;
3219   vam->result_ready = 1;
3220 }
3221
3222 static void
3223   vl_api_show_one_map_register_state_reply_t_handler_json
3224   (vl_api_show_one_map_register_state_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   vat_json_node_t _node, *node = &_node;
3228   int retval = clib_net_to_host_u32 (mp->retval);
3229
3230   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3231
3232   vat_json_init_object (node);
3233   vat_json_object_add_string_copy (node, "state", s);
3234
3235   vat_json_print (vam->ofp, node);
3236   vat_json_free (node);
3237
3238   vam->retval = retval;
3239   vam->result_ready = 1;
3240   vec_free (s);
3241 }
3242
3243 static void
3244   vl_api_show_one_rloc_probe_state_reply_t_handler
3245   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3246 {
3247   vat_main_t *vam = &vat_main;
3248   int retval = clib_net_to_host_u32 (mp->retval);
3249
3250   if (retval)
3251     goto end;
3252
3253   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3254 end:
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257 }
3258
3259 static void
3260   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3261   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t _node, *node = &_node;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266
3267   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3268   vat_json_init_object (node);
3269   vat_json_object_add_string_copy (node, "state", s);
3270
3271   vat_json_print (vam->ofp, node);
3272   vat_json_free (node);
3273
3274   vam->retval = retval;
3275   vam->result_ready = 1;
3276   vec_free (s);
3277 }
3278
3279 static void
3280   vl_api_show_one_stats_enable_disable_reply_t_handler
3281   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284   int retval = clib_net_to_host_u32 (mp->retval);
3285
3286   if (retval)
3287     goto end;
3288
3289   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3290 end:
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293 }
3294
3295 static void
3296   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3297   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300   vat_json_node_t _node, *node = &_node;
3301   int retval = clib_net_to_host_u32 (mp->retval);
3302
3303   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3304   vat_json_init_object (node);
3305   vat_json_object_add_string_copy (node, "state", s);
3306
3307   vat_json_print (vam->ofp, node);
3308   vat_json_free (node);
3309
3310   vam->retval = retval;
3311   vam->result_ready = 1;
3312   vec_free (s);
3313 }
3314
3315 static void
3316 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3317 {
3318   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3319   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3320   e->vni = clib_net_to_host_u32 (e->vni);
3321 }
3322
3323 static void
3324   gpe_fwd_entries_get_reply_t_net_to_host
3325   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3326 {
3327   u32 i;
3328
3329   mp->count = clib_net_to_host_u32 (mp->count);
3330   for (i = 0; i < mp->count; i++)
3331     {
3332       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3333     }
3334 }
3335
3336 static u8 *
3337 format_gpe_encap_mode (u8 * s, va_list * args)
3338 {
3339   u32 mode = va_arg (*args, u32);
3340
3341   switch (mode)
3342     {
3343     case 0:
3344       return format (s, "lisp");
3345     case 1:
3346       return format (s, "vxlan");
3347     }
3348   return 0;
3349 }
3350
3351 static void
3352   vl_api_gpe_get_encap_mode_reply_t_handler
3353   (vl_api_gpe_get_encap_mode_reply_t * mp)
3354 {
3355   vat_main_t *vam = &vat_main;
3356
3357   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3358   vam->retval = ntohl (mp->retval);
3359   vam->result_ready = 1;
3360 }
3361
3362 static void
3363   vl_api_gpe_get_encap_mode_reply_t_handler_json
3364   (vl_api_gpe_get_encap_mode_reply_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   vat_json_node_t node;
3368
3369   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3370   vec_add1 (encap_mode, 0);
3371
3372   vat_json_init_object (&node);
3373   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3374
3375   vec_free (encap_mode);
3376   vat_json_print (vam->ofp, &node);
3377   vat_json_free (&node);
3378
3379   vam->retval = ntohl (mp->retval);
3380   vam->result_ready = 1;
3381 }
3382
3383 static void
3384   vl_api_gpe_fwd_entry_path_details_t_handler
3385   (vl_api_gpe_fwd_entry_path_details_t * mp)
3386 {
3387   vat_main_t *vam = &vat_main;
3388   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3389
3390   if (mp->lcl_loc.addr.af)
3391     format_ip_address_fcn = format_ip6_address;
3392   else
3393     format_ip_address_fcn = format_ip4_address;
3394
3395   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3396          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3397          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3398 }
3399
3400 static void
3401 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3402 {
3403   struct in6_addr ip6;
3404   struct in_addr ip4;
3405
3406   if (loc->addr.af)
3407     {
3408       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3409       vat_json_object_add_ip6 (n, "address", ip6);
3410     }
3411   else
3412     {
3413       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3414       vat_json_object_add_ip4 (n, "address", ip4);
3415     }
3416   vat_json_object_add_uint (n, "weight", loc->weight);
3417 }
3418
3419 static void
3420   vl_api_gpe_fwd_entry_path_details_t_handler_json
3421   (vl_api_gpe_fwd_entry_path_details_t * mp)
3422 {
3423   vat_main_t *vam = &vat_main;
3424   vat_json_node_t *node = NULL;
3425   vat_json_node_t *loc_node;
3426
3427   if (VAT_JSON_ARRAY != vam->json_tree.type)
3428     {
3429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3430       vat_json_init_array (&vam->json_tree);
3431     }
3432   node = vat_json_array_add (&vam->json_tree);
3433   vat_json_init_object (node);
3434
3435   loc_node = vat_json_object_add (node, "local_locator");
3436   vat_json_init_object (loc_node);
3437   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3438
3439   loc_node = vat_json_object_add (node, "remote_locator");
3440   vat_json_init_object (loc_node);
3441   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3442 }
3443
3444 static void
3445   vl_api_gpe_fwd_entries_get_reply_t_handler
3446   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3447 {
3448   vat_main_t *vam = &vat_main;
3449   u32 i;
3450   int retval = clib_net_to_host_u32 (mp->retval);
3451   vl_api_gpe_fwd_entry_t *e;
3452
3453   if (retval)
3454     goto end;
3455
3456   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3457
3458   for (i = 0; i < mp->count; i++)
3459     {
3460       e = &mp->entries[i];
3461       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3462              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3463     }
3464
3465 end:
3466   vam->retval = retval;
3467   vam->result_ready = 1;
3468 }
3469
3470 static void
3471   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u8 *s = 0;
3475   vat_main_t *vam = &vat_main;
3476   vat_json_node_t *e = 0, root;
3477   u32 i;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479   vl_api_gpe_fwd_entry_t *fwd;
3480
3481   if (retval)
3482     goto end;
3483
3484   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3485   vat_json_init_array (&root);
3486
3487   for (i = 0; i < mp->count; i++)
3488     {
3489       e = vat_json_array_add (&root);
3490       fwd = &mp->entries[i];
3491
3492       vat_json_init_object (e);
3493       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3494       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3495       vat_json_object_add_int (e, "vni", fwd->vni);
3496       vat_json_object_add_int (e, "action", fwd->action);
3497
3498       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3499       vec_add1 (s, 0);
3500       vat_json_object_add_string_copy (e, "leid", s);
3501       vec_free (s);
3502
3503       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3504       vec_add1 (s, 0);
3505       vat_json_object_add_string_copy (e, "reid", s);
3506       vec_free (s);
3507     }
3508
3509   vat_json_print (vam->ofp, &root);
3510   vat_json_free (&root);
3511
3512 end:
3513   vam->retval = retval;
3514   vam->result_ready = 1;
3515 }
3516
3517 static void
3518   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3519   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   u32 i, n;
3523   int retval = clib_net_to_host_u32 (mp->retval);
3524   vl_api_gpe_native_fwd_rpath_t *r;
3525
3526   if (retval)
3527     goto end;
3528
3529   n = clib_net_to_host_u32 (mp->count);
3530
3531   for (i = 0; i < n; i++)
3532     {
3533       r = &mp->entries[i];
3534       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3535              clib_net_to_host_u32 (r->fib_index),
3536              clib_net_to_host_u32 (r->nh_sw_if_index),
3537              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3538              r->nh_addr.un);
3539     }
3540
3541 end:
3542   vam->retval = retval;
3543   vam->result_ready = 1;
3544 }
3545
3546 static void
3547   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3548   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3549 {
3550   vat_main_t *vam = &vat_main;
3551   vat_json_node_t root, *e;
3552   u32 i, n;
3553   int retval = clib_net_to_host_u32 (mp->retval);
3554   vl_api_gpe_native_fwd_rpath_t *r;
3555   u8 *s;
3556
3557   if (retval)
3558     goto end;
3559
3560   n = clib_net_to_host_u32 (mp->count);
3561   vat_json_init_array (&root);
3562
3563   for (i = 0; i < n; i++)
3564     {
3565       e = vat_json_array_add (&root);
3566       vat_json_init_object (e);
3567       r = &mp->entries[i];
3568       s =
3569         format (0, "%U",
3570                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3571                 r->nh_addr.un);
3572       vec_add1 (s, 0);
3573       vat_json_object_add_string_copy (e, "ip4", s);
3574       vec_free (s);
3575
3576       vat_json_object_add_uint (e, "fib_index",
3577                                 clib_net_to_host_u32 (r->fib_index));
3578       vat_json_object_add_uint (e, "nh_sw_if_index",
3579                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3580     }
3581
3582   vat_json_print (vam->ofp, &root);
3583   vat_json_free (&root);
3584
3585 end:
3586   vam->retval = retval;
3587   vam->result_ready = 1;
3588 }
3589
3590 static void
3591   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3592   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   u32 i, n;
3596   int retval = clib_net_to_host_u32 (mp->retval);
3597
3598   if (retval)
3599     goto end;
3600
3601   n = clib_net_to_host_u32 (mp->count);
3602
3603   for (i = 0; i < n; i++)
3604     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3605
3606 end:
3607   vam->retval = retval;
3608   vam->result_ready = 1;
3609 }
3610
3611 static void
3612   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3613   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3614 {
3615   vat_main_t *vam = &vat_main;
3616   vat_json_node_t root;
3617   u32 i, n;
3618   int retval = clib_net_to_host_u32 (mp->retval);
3619
3620   if (retval)
3621     goto end;
3622
3623   n = clib_net_to_host_u32 (mp->count);
3624   vat_json_init_array (&root);
3625
3626   for (i = 0; i < n; i++)
3627     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3628
3629   vat_json_print (vam->ofp, &root);
3630   vat_json_free (&root);
3631
3632 end:
3633   vam->retval = retval;
3634   vam->result_ready = 1;
3635 }
3636
3637 static void
3638   vl_api_one_ndp_entries_get_reply_t_handler
3639   (vl_api_one_ndp_entries_get_reply_t * mp)
3640 {
3641   vat_main_t *vam = &vat_main;
3642   u32 i, n;
3643   int retval = clib_net_to_host_u32 (mp->retval);
3644
3645   if (retval)
3646     goto end;
3647
3648   n = clib_net_to_host_u32 (mp->count);
3649
3650   for (i = 0; i < n; i++)
3651     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3652            format_ethernet_address, mp->entries[i].mac);
3653
3654 end:
3655   vam->retval = retval;
3656   vam->result_ready = 1;
3657 }
3658
3659 static void
3660   vl_api_one_ndp_entries_get_reply_t_handler_json
3661   (vl_api_one_ndp_entries_get_reply_t * mp)
3662 {
3663   u8 *s = 0;
3664   vat_main_t *vam = &vat_main;
3665   vat_json_node_t *e = 0, root;
3666   u32 i, n;
3667   int retval = clib_net_to_host_u32 (mp->retval);
3668   vl_api_one_ndp_entry_t *arp_entry;
3669
3670   if (retval)
3671     goto end;
3672
3673   n = clib_net_to_host_u32 (mp->count);
3674   vat_json_init_array (&root);
3675
3676   for (i = 0; i < n; i++)
3677     {
3678       e = vat_json_array_add (&root);
3679       arp_entry = &mp->entries[i];
3680
3681       vat_json_init_object (e);
3682       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3683       vec_add1 (s, 0);
3684
3685       vat_json_object_add_string_copy (e, "mac", s);
3686       vec_free (s);
3687
3688       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3689       vec_add1 (s, 0);
3690       vat_json_object_add_string_copy (e, "ip6", s);
3691       vec_free (s);
3692     }
3693
3694   vat_json_print (vam->ofp, &root);
3695   vat_json_free (&root);
3696
3697 end:
3698   vam->retval = retval;
3699   vam->result_ready = 1;
3700 }
3701
3702 static void
3703   vl_api_one_l2_arp_entries_get_reply_t_handler
3704   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   u32 i, n;
3708   int retval = clib_net_to_host_u32 (mp->retval);
3709
3710   if (retval)
3711     goto end;
3712
3713   n = clib_net_to_host_u32 (mp->count);
3714
3715   for (i = 0; i < n; i++)
3716     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3717            format_ethernet_address, mp->entries[i].mac);
3718
3719 end:
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3726   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3727 {
3728   u8 *s = 0;
3729   vat_main_t *vam = &vat_main;
3730   vat_json_node_t *e = 0, root;
3731   u32 i, n;
3732   int retval = clib_net_to_host_u32 (mp->retval);
3733   vl_api_one_l2_arp_entry_t *arp_entry;
3734
3735   if (retval)
3736     goto end;
3737
3738   n = clib_net_to_host_u32 (mp->count);
3739   vat_json_init_array (&root);
3740
3741   for (i = 0; i < n; i++)
3742     {
3743       e = vat_json_array_add (&root);
3744       arp_entry = &mp->entries[i];
3745
3746       vat_json_init_object (e);
3747       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3748       vec_add1 (s, 0);
3749
3750       vat_json_object_add_string_copy (e, "mac", s);
3751       vec_free (s);
3752
3753       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3754       vec_add1 (s, 0);
3755       vat_json_object_add_string_copy (e, "ip4", s);
3756       vec_free (s);
3757     }
3758
3759   vat_json_print (vam->ofp, &root);
3760   vat_json_free (&root);
3761
3762 end:
3763   vam->retval = retval;
3764   vam->result_ready = 1;
3765 }
3766
3767 static void
3768 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3769 {
3770   vat_main_t *vam = &vat_main;
3771   u32 i, n;
3772   int retval = clib_net_to_host_u32 (mp->retval);
3773
3774   if (retval)
3775     goto end;
3776
3777   n = clib_net_to_host_u32 (mp->count);
3778
3779   for (i = 0; i < n; i++)
3780     {
3781       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3782     }
3783
3784 end:
3785   vam->retval = retval;
3786   vam->result_ready = 1;
3787 }
3788
3789 static void
3790   vl_api_one_ndp_bd_get_reply_t_handler_json
3791   (vl_api_one_ndp_bd_get_reply_t * mp)
3792 {
3793   vat_main_t *vam = &vat_main;
3794   vat_json_node_t root;
3795   u32 i, n;
3796   int retval = clib_net_to_host_u32 (mp->retval);
3797
3798   if (retval)
3799     goto end;
3800
3801   n = clib_net_to_host_u32 (mp->count);
3802   vat_json_init_array (&root);
3803
3804   for (i = 0; i < n; i++)
3805     {
3806       vat_json_array_add_uint (&root,
3807                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3808     }
3809
3810   vat_json_print (vam->ofp, &root);
3811   vat_json_free (&root);
3812
3813 end:
3814   vam->retval = retval;
3815   vam->result_ready = 1;
3816 }
3817
3818 static void
3819   vl_api_one_l2_arp_bd_get_reply_t_handler
3820   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   u32 i, n;
3824   int retval = clib_net_to_host_u32 (mp->retval);
3825
3826   if (retval)
3827     goto end;
3828
3829   n = clib_net_to_host_u32 (mp->count);
3830
3831   for (i = 0; i < n; i++)
3832     {
3833       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3834     }
3835
3836 end:
3837   vam->retval = retval;
3838   vam->result_ready = 1;
3839 }
3840
3841 static void
3842   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3843   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3844 {
3845   vat_main_t *vam = &vat_main;
3846   vat_json_node_t root;
3847   u32 i, n;
3848   int retval = clib_net_to_host_u32 (mp->retval);
3849
3850   if (retval)
3851     goto end;
3852
3853   n = clib_net_to_host_u32 (mp->count);
3854   vat_json_init_array (&root);
3855
3856   for (i = 0; i < n; i++)
3857     {
3858       vat_json_array_add_uint (&root,
3859                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3860     }
3861
3862   vat_json_print (vam->ofp, &root);
3863   vat_json_free (&root);
3864
3865 end:
3866   vam->retval = retval;
3867   vam->result_ready = 1;
3868 }
3869
3870 static void
3871   vl_api_one_adjacencies_get_reply_t_handler
3872   (vl_api_one_adjacencies_get_reply_t * mp)
3873 {
3874   vat_main_t *vam = &vat_main;
3875   u32 i, n;
3876   int retval = clib_net_to_host_u32 (mp->retval);
3877   vl_api_one_adjacency_t *a;
3878
3879   if (retval)
3880     goto end;
3881
3882   n = clib_net_to_host_u32 (mp->count);
3883
3884   for (i = 0; i < n; i++)
3885     {
3886       a = &mp->adjacencies[i];
3887       print (vam->ofp, "%U %40U",
3888              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3889     }
3890
3891 end:
3892   vam->retval = retval;
3893   vam->result_ready = 1;
3894 }
3895
3896 static void
3897   vl_api_one_adjacencies_get_reply_t_handler_json
3898   (vl_api_one_adjacencies_get_reply_t * mp)
3899 {
3900   u8 *s = 0;
3901   vat_main_t *vam = &vat_main;
3902   vat_json_node_t *e = 0, root;
3903   u32 i, n;
3904   int retval = clib_net_to_host_u32 (mp->retval);
3905   vl_api_one_adjacency_t *a;
3906
3907   if (retval)
3908     goto end;
3909
3910   n = clib_net_to_host_u32 (mp->count);
3911   vat_json_init_array (&root);
3912
3913   for (i = 0; i < n; i++)
3914     {
3915       e = vat_json_array_add (&root);
3916       a = &mp->adjacencies[i];
3917
3918       vat_json_init_object (e);
3919       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3920       vec_add1 (s, 0);
3921       vat_json_object_add_string_copy (e, "leid", s);
3922       vec_free (s);
3923
3924       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3925       vec_add1 (s, 0);
3926       vat_json_object_add_string_copy (e, "reid", s);
3927       vec_free (s);
3928     }
3929
3930   vat_json_print (vam->ofp, &root);
3931   vat_json_free (&root);
3932
3933 end:
3934   vam->retval = retval;
3935   vam->result_ready = 1;
3936 }
3937
3938 static void
3939 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942
3943   print (vam->ofp, "%=20U",
3944          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3945          mp->ip_address.un);
3946 }
3947
3948 static void
3949   vl_api_one_map_server_details_t_handler_json
3950   (vl_api_one_map_server_details_t * mp)
3951 {
3952   vat_main_t *vam = &vat_main;
3953   vat_json_node_t *node = NULL;
3954   struct in6_addr ip6;
3955   struct in_addr ip4;
3956
3957   if (VAT_JSON_ARRAY != vam->json_tree.type)
3958     {
3959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3960       vat_json_init_array (&vam->json_tree);
3961     }
3962   node = vat_json_array_add (&vam->json_tree);
3963
3964   vat_json_init_object (node);
3965   if (mp->ip_address.af)
3966     {
3967       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3968       vat_json_object_add_ip6 (node, "map-server", ip6);
3969     }
3970   else
3971     {
3972       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3973       vat_json_object_add_ip4 (node, "map-server", ip4);
3974     }
3975 }
3976
3977 static void
3978 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3979                                            * mp)
3980 {
3981   vat_main_t *vam = &vat_main;
3982
3983   print (vam->ofp, "%=20U",
3984          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3985          mp->ip_address.un);
3986 }
3987
3988 static void
3989   vl_api_one_map_resolver_details_t_handler_json
3990   (vl_api_one_map_resolver_details_t * mp)
3991 {
3992   vat_main_t *vam = &vat_main;
3993   vat_json_node_t *node = NULL;
3994   struct in6_addr ip6;
3995   struct in_addr ip4;
3996
3997   if (VAT_JSON_ARRAY != vam->json_tree.type)
3998     {
3999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4000       vat_json_init_array (&vam->json_tree);
4001     }
4002   node = vat_json_array_add (&vam->json_tree);
4003
4004   vat_json_init_object (node);
4005   if (mp->ip_address.af)
4006     {
4007       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4008       vat_json_object_add_ip6 (node, "map resolver", ip6);
4009     }
4010   else
4011     {
4012       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4013       vat_json_object_add_ip4 (node, "map resolver", ip4);
4014     }
4015 }
4016
4017 static void
4018 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4019 {
4020   vat_main_t *vam = &vat_main;
4021   i32 retval = ntohl (mp->retval);
4022
4023   if (0 <= retval)
4024     {
4025       print (vam->ofp, "feature: %s\ngpe: %s",
4026              mp->feature_status ? "enabled" : "disabled",
4027              mp->gpe_status ? "enabled" : "disabled");
4028     }
4029
4030   vam->retval = retval;
4031   vam->result_ready = 1;
4032 }
4033
4034 static void
4035   vl_api_show_one_status_reply_t_handler_json
4036   (vl_api_show_one_status_reply_t * mp)
4037 {
4038   vat_main_t *vam = &vat_main;
4039   vat_json_node_t node;
4040   u8 *gpe_status = NULL;
4041   u8 *feature_status = NULL;
4042
4043   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4044   feature_status = format (0, "%s",
4045                            mp->feature_status ? "enabled" : "disabled");
4046   vec_add1 (gpe_status, 0);
4047   vec_add1 (feature_status, 0);
4048
4049   vat_json_init_object (&node);
4050   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4051   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4052
4053   vec_free (gpe_status);
4054   vec_free (feature_status);
4055
4056   vat_json_print (vam->ofp, &node);
4057   vat_json_free (&node);
4058
4059   vam->retval = ntohl (mp->retval);
4060   vam->result_ready = 1;
4061 }
4062
4063 static void
4064   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4065   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4066 {
4067   vat_main_t *vam = &vat_main;
4068   i32 retval = ntohl (mp->retval);
4069
4070   if (retval >= 0)
4071     {
4072       print (vam->ofp, "%=20s", mp->locator_set_name);
4073     }
4074
4075   vam->retval = retval;
4076   vam->result_ready = 1;
4077 }
4078
4079 static void
4080   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4081   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4082 {
4083   vat_main_t *vam = &vat_main;
4084   vat_json_node_t *node = NULL;
4085
4086   if (VAT_JSON_ARRAY != vam->json_tree.type)
4087     {
4088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4089       vat_json_init_array (&vam->json_tree);
4090     }
4091   node = vat_json_array_add (&vam->json_tree);
4092
4093   vat_json_init_object (node);
4094   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4095
4096   vat_json_print (vam->ofp, node);
4097   vat_json_free (node);
4098
4099   vam->retval = ntohl (mp->retval);
4100   vam->result_ready = 1;
4101 }
4102
4103 static u8 *
4104 format_lisp_map_request_mode (u8 * s, va_list * args)
4105 {
4106   u32 mode = va_arg (*args, u32);
4107
4108   switch (mode)
4109     {
4110     case 0:
4111       return format (0, "dst-only");
4112     case 1:
4113       return format (0, "src-dst");
4114     }
4115   return 0;
4116 }
4117
4118 static void
4119   vl_api_show_one_map_request_mode_reply_t_handler
4120   (vl_api_show_one_map_request_mode_reply_t * mp)
4121 {
4122   vat_main_t *vam = &vat_main;
4123   i32 retval = ntohl (mp->retval);
4124
4125   if (0 <= retval)
4126     {
4127       u32 mode = mp->mode;
4128       print (vam->ofp, "map_request_mode: %U",
4129              format_lisp_map_request_mode, mode);
4130     }
4131
4132   vam->retval = retval;
4133   vam->result_ready = 1;
4134 }
4135
4136 static void
4137   vl_api_show_one_map_request_mode_reply_t_handler_json
4138   (vl_api_show_one_map_request_mode_reply_t * mp)
4139 {
4140   vat_main_t *vam = &vat_main;
4141   vat_json_node_t node;
4142   u8 *s = 0;
4143   u32 mode;
4144
4145   mode = mp->mode;
4146   s = format (0, "%U", format_lisp_map_request_mode, mode);
4147   vec_add1 (s, 0);
4148
4149   vat_json_init_object (&node);
4150   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4151   vat_json_print (vam->ofp, &node);
4152   vat_json_free (&node);
4153
4154   vec_free (s);
4155   vam->retval = ntohl (mp->retval);
4156   vam->result_ready = 1;
4157 }
4158
4159 static void
4160   vl_api_one_show_xtr_mode_reply_t_handler
4161   (vl_api_one_show_xtr_mode_reply_t * mp)
4162 {
4163   vat_main_t *vam = &vat_main;
4164   i32 retval = ntohl (mp->retval);
4165
4166   if (0 <= retval)
4167     {
4168       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4169     }
4170
4171   vam->retval = retval;
4172   vam->result_ready = 1;
4173 }
4174
4175 static void
4176   vl_api_one_show_xtr_mode_reply_t_handler_json
4177   (vl_api_one_show_xtr_mode_reply_t * mp)
4178 {
4179   vat_main_t *vam = &vat_main;
4180   vat_json_node_t node;
4181   u8 *status = 0;
4182
4183   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4184   vec_add1 (status, 0);
4185
4186   vat_json_init_object (&node);
4187   vat_json_object_add_string_copy (&node, "status", status);
4188
4189   vec_free (status);
4190
4191   vat_json_print (vam->ofp, &node);
4192   vat_json_free (&node);
4193
4194   vam->retval = ntohl (mp->retval);
4195   vam->result_ready = 1;
4196 }
4197
4198 static void
4199   vl_api_one_show_pitr_mode_reply_t_handler
4200   (vl_api_one_show_pitr_mode_reply_t * mp)
4201 {
4202   vat_main_t *vam = &vat_main;
4203   i32 retval = ntohl (mp->retval);
4204
4205   if (0 <= retval)
4206     {
4207       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4208     }
4209
4210   vam->retval = retval;
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_show_pitr_mode_reply_t_handler_json
4216   (vl_api_one_show_pitr_mode_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   vat_json_node_t node;
4220   u8 *status = 0;
4221
4222   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4223   vec_add1 (status, 0);
4224
4225   vat_json_init_object (&node);
4226   vat_json_object_add_string_copy (&node, "status", status);
4227
4228   vec_free (status);
4229
4230   vat_json_print (vam->ofp, &node);
4231   vat_json_free (&node);
4232
4233   vam->retval = ntohl (mp->retval);
4234   vam->result_ready = 1;
4235 }
4236
4237 static void
4238   vl_api_one_show_petr_mode_reply_t_handler
4239   (vl_api_one_show_petr_mode_reply_t * mp)
4240 {
4241   vat_main_t *vam = &vat_main;
4242   i32 retval = ntohl (mp->retval);
4243
4244   if (0 <= retval)
4245     {
4246       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4247     }
4248
4249   vam->retval = retval;
4250   vam->result_ready = 1;
4251 }
4252
4253 static void
4254   vl_api_one_show_petr_mode_reply_t_handler_json
4255   (vl_api_one_show_petr_mode_reply_t * mp)
4256 {
4257   vat_main_t *vam = &vat_main;
4258   vat_json_node_t node;
4259   u8 *status = 0;
4260
4261   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4262   vec_add1 (status, 0);
4263
4264   vat_json_init_object (&node);
4265   vat_json_object_add_string_copy (&node, "status", status);
4266
4267   vec_free (status);
4268
4269   vat_json_print (vam->ofp, &node);
4270   vat_json_free (&node);
4271
4272   vam->retval = ntohl (mp->retval);
4273   vam->result_ready = 1;
4274 }
4275
4276 static void
4277   vl_api_show_one_use_petr_reply_t_handler
4278   (vl_api_show_one_use_petr_reply_t * mp)
4279 {
4280   vat_main_t *vam = &vat_main;
4281   i32 retval = ntohl (mp->retval);
4282
4283   if (0 <= retval)
4284     {
4285       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4286       if (mp->status)
4287         {
4288           print (vam->ofp, "Proxy-ETR address; %U",
4289                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4290                  mp->ip_address.un);
4291         }
4292     }
4293
4294   vam->retval = retval;
4295   vam->result_ready = 1;
4296 }
4297
4298 static void
4299   vl_api_show_one_use_petr_reply_t_handler_json
4300   (vl_api_show_one_use_petr_reply_t * mp)
4301 {
4302   vat_main_t *vam = &vat_main;
4303   vat_json_node_t node;
4304   u8 *status = 0;
4305   struct in_addr ip4;
4306   struct in6_addr ip6;
4307
4308   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4309   vec_add1 (status, 0);
4310
4311   vat_json_init_object (&node);
4312   vat_json_object_add_string_copy (&node, "status", status);
4313   if (mp->status)
4314     {
4315       if (mp->ip_address.af)
4316         {
4317           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4318           vat_json_object_add_ip6 (&node, "address", ip6);
4319         }
4320       else
4321         {
4322           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4323           vat_json_object_add_ip4 (&node, "address", ip4);
4324         }
4325     }
4326
4327   vec_free (status);
4328
4329   vat_json_print (vam->ofp, &node);
4330   vat_json_free (&node);
4331
4332   vam->retval = ntohl (mp->retval);
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_show_one_nsh_mapping_reply_t_handler
4338   (vl_api_show_one_nsh_mapping_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   i32 retval = ntohl (mp->retval);
4342
4343   if (0 <= retval)
4344     {
4345       print (vam->ofp, "%-20s%-16s",
4346              mp->is_set ? "set" : "not-set",
4347              mp->is_set ? (char *) mp->locator_set_name : "");
4348     }
4349
4350   vam->retval = retval;
4351   vam->result_ready = 1;
4352 }
4353
4354 static void
4355   vl_api_show_one_nsh_mapping_reply_t_handler_json
4356   (vl_api_show_one_nsh_mapping_reply_t * mp)
4357 {
4358   vat_main_t *vam = &vat_main;
4359   vat_json_node_t node;
4360   u8 *status = 0;
4361
4362   status = format (0, "%s", mp->is_set ? "yes" : "no");
4363   vec_add1 (status, 0);
4364
4365   vat_json_init_object (&node);
4366   vat_json_object_add_string_copy (&node, "is_set", status);
4367   if (mp->is_set)
4368     {
4369       vat_json_object_add_string_copy (&node, "locator_set",
4370                                        mp->locator_set_name);
4371     }
4372
4373   vec_free (status);
4374
4375   vat_json_print (vam->ofp, &node);
4376   vat_json_free (&node);
4377
4378   vam->retval = ntohl (mp->retval);
4379   vam->result_ready = 1;
4380 }
4381
4382 static void
4383   vl_api_show_one_map_register_ttl_reply_t_handler
4384   (vl_api_show_one_map_register_ttl_reply_t * mp)
4385 {
4386   vat_main_t *vam = &vat_main;
4387   i32 retval = ntohl (mp->retval);
4388
4389   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4390
4391   if (0 <= retval)
4392     {
4393       print (vam->ofp, "ttl: %u", mp->ttl);
4394     }
4395
4396   vam->retval = retval;
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401   vl_api_show_one_map_register_ttl_reply_t_handler_json
4402   (vl_api_show_one_map_register_ttl_reply_t * mp)
4403 {
4404   vat_main_t *vam = &vat_main;
4405   vat_json_node_t node;
4406
4407   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4408   vat_json_init_object (&node);
4409   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4410
4411   vat_json_print (vam->ofp, &node);
4412   vat_json_free (&node);
4413
4414   vam->retval = ntohl (mp->retval);
4415   vam->result_ready = 1;
4416 }
4417
4418 static void
4419 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4420 {
4421   vat_main_t *vam = &vat_main;
4422   i32 retval = ntohl (mp->retval);
4423
4424   if (0 <= retval)
4425     {
4426       print (vam->ofp, "%-20s%-16s",
4427              mp->status ? "enabled" : "disabled",
4428              mp->status ? (char *) mp->locator_set_name : "");
4429     }
4430
4431   vam->retval = retval;
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   vat_json_node_t node;
4440   u8 *status = 0;
4441
4442   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4443   vec_add1 (status, 0);
4444
4445   vat_json_init_object (&node);
4446   vat_json_object_add_string_copy (&node, "status", status);
4447   if (mp->status)
4448     {
4449       vat_json_object_add_string_copy (&node, "locator_set",
4450                                        mp->locator_set_name);
4451     }
4452
4453   vec_free (status);
4454
4455   vat_json_print (vam->ofp, &node);
4456   vat_json_free (&node);
4457
4458   vam->retval = ntohl (mp->retval);
4459   vam->result_ready = 1;
4460 }
4461
4462 static u8 *
4463 format_policer_type (u8 * s, va_list * va)
4464 {
4465   u32 i = va_arg (*va, u32);
4466
4467   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4468     s = format (s, "1r2c");
4469   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4470     s = format (s, "1r3c");
4471   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4472     s = format (s, "2r3c-2698");
4473   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4474     s = format (s, "2r3c-4115");
4475   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4476     s = format (s, "2r3c-mef5cf1");
4477   else
4478     s = format (s, "ILLEGAL");
4479   return s;
4480 }
4481
4482 static u8 *
4483 format_policer_rate_type (u8 * s, va_list * va)
4484 {
4485   u32 i = va_arg (*va, u32);
4486
4487   if (i == SSE2_QOS_RATE_KBPS)
4488     s = format (s, "kbps");
4489   else if (i == SSE2_QOS_RATE_PPS)
4490     s = format (s, "pps");
4491   else
4492     s = format (s, "ILLEGAL");
4493   return s;
4494 }
4495
4496 static u8 *
4497 format_policer_round_type (u8 * s, va_list * va)
4498 {
4499   u32 i = va_arg (*va, u32);
4500
4501   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4502     s = format (s, "closest");
4503   else if (i == SSE2_QOS_ROUND_TO_UP)
4504     s = format (s, "up");
4505   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4506     s = format (s, "down");
4507   else
4508     s = format (s, "ILLEGAL");
4509   return s;
4510 }
4511
4512 static u8 *
4513 format_policer_action_type (u8 * s, va_list * va)
4514 {
4515   u32 i = va_arg (*va, u32);
4516
4517   if (i == SSE2_QOS_ACTION_DROP)
4518     s = format (s, "drop");
4519   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4520     s = format (s, "transmit");
4521   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4522     s = format (s, "mark-and-transmit");
4523   else
4524     s = format (s, "ILLEGAL");
4525   return s;
4526 }
4527
4528 static u8 *
4529 format_dscp (u8 * s, va_list * va)
4530 {
4531   u32 i = va_arg (*va, u32);
4532   char *t = 0;
4533
4534   switch (i)
4535     {
4536 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4537       foreach_vnet_dscp
4538 #undef _
4539     default:
4540       return format (s, "ILLEGAL");
4541     }
4542   s = format (s, "%s", t);
4543   return s;
4544 }
4545
4546 static void
4547 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4548 {
4549   vat_main_t *vam = &vat_main;
4550   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4551
4552   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4553     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4554   else
4555     conform_dscp_str = format (0, "");
4556
4557   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4558     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4559   else
4560     exceed_dscp_str = format (0, "");
4561
4562   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4563     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4564   else
4565     violate_dscp_str = format (0, "");
4566
4567   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4568          "rate type %U, round type %U, %s rate, %s color-aware, "
4569          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4570          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4571          "conform action %U%s, exceed action %U%s, violate action %U%s",
4572          mp->name,
4573          format_policer_type, mp->type,
4574          ntohl (mp->cir),
4575          ntohl (mp->eir),
4576          clib_net_to_host_u64 (mp->cb),
4577          clib_net_to_host_u64 (mp->eb),
4578          format_policer_rate_type, mp->rate_type,
4579          format_policer_round_type, mp->round_type,
4580          mp->single_rate ? "single" : "dual",
4581          mp->color_aware ? "is" : "not",
4582          ntohl (mp->cir_tokens_per_period),
4583          ntohl (mp->pir_tokens_per_period),
4584          ntohl (mp->scale),
4585          ntohl (mp->current_limit),
4586          ntohl (mp->current_bucket),
4587          ntohl (mp->extended_limit),
4588          ntohl (mp->extended_bucket),
4589          clib_net_to_host_u64 (mp->last_update_time),
4590          format_policer_action_type, mp->conform_action.type,
4591          conform_dscp_str,
4592          format_policer_action_type, mp->exceed_action.type,
4593          exceed_dscp_str,
4594          format_policer_action_type, mp->violate_action.type,
4595          violate_dscp_str);
4596
4597   vec_free (conform_dscp_str);
4598   vec_free (exceed_dscp_str);
4599   vec_free (violate_dscp_str);
4600 }
4601
4602 static void vl_api_policer_details_t_handler_json
4603   (vl_api_policer_details_t * mp)
4604 {
4605   vat_main_t *vam = &vat_main;
4606   vat_json_node_t *node;
4607   u8 *rate_type_str, *round_type_str, *type_str;
4608   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4609
4610   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4611   round_type_str =
4612     format (0, "%U", format_policer_round_type, mp->round_type);
4613   type_str = format (0, "%U", format_policer_type, mp->type);
4614   conform_action_str = format (0, "%U", format_policer_action_type,
4615                                mp->conform_action.type);
4616   exceed_action_str = format (0, "%U", format_policer_action_type,
4617                               mp->exceed_action.type);
4618   violate_action_str = format (0, "%U", format_policer_action_type,
4619                                mp->violate_action.type);
4620
4621   if (VAT_JSON_ARRAY != vam->json_tree.type)
4622     {
4623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4624       vat_json_init_array (&vam->json_tree);
4625     }
4626   node = vat_json_array_add (&vam->json_tree);
4627
4628   vat_json_init_object (node);
4629   vat_json_object_add_string_copy (node, "name", mp->name);
4630   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4631   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4632   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4633   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4634   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4635   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4636   vat_json_object_add_string_copy (node, "type", type_str);
4637   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4638   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4639   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4640   vat_json_object_add_uint (node, "cir_tokens_per_period",
4641                             ntohl (mp->cir_tokens_per_period));
4642   vat_json_object_add_uint (node, "eir_tokens_per_period",
4643                             ntohl (mp->pir_tokens_per_period));
4644   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4645   vat_json_object_add_uint (node, "current_bucket",
4646                             ntohl (mp->current_bucket));
4647   vat_json_object_add_uint (node, "extended_limit",
4648                             ntohl (mp->extended_limit));
4649   vat_json_object_add_uint (node, "extended_bucket",
4650                             ntohl (mp->extended_bucket));
4651   vat_json_object_add_uint (node, "last_update_time",
4652                             ntohl (mp->last_update_time));
4653   vat_json_object_add_string_copy (node, "conform_action",
4654                                    conform_action_str);
4655   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4656     {
4657       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4658       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4659       vec_free (dscp_str);
4660     }
4661   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4662   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4663     {
4664       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4665       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4666       vec_free (dscp_str);
4667     }
4668   vat_json_object_add_string_copy (node, "violate_action",
4669                                    violate_action_str);
4670   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4671     {
4672       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4673       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4674       vec_free (dscp_str);
4675     }
4676
4677   vec_free (rate_type_str);
4678   vec_free (round_type_str);
4679   vec_free (type_str);
4680   vec_free (conform_action_str);
4681   vec_free (exceed_action_str);
4682   vec_free (violate_action_str);
4683 }
4684
4685 static void
4686 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4687                                            mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   int i, count = ntohl (mp->count);
4691
4692   if (count > 0)
4693     print (vam->ofp, "classify table ids (%d) : ", count);
4694   for (i = 0; i < count; i++)
4695     {
4696       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4697       print (vam->ofp, (i < count - 1) ? "," : "");
4698     }
4699   vam->retval = ntohl (mp->retval);
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704   vl_api_classify_table_ids_reply_t_handler_json
4705   (vl_api_classify_table_ids_reply_t * mp)
4706 {
4707   vat_main_t *vam = &vat_main;
4708   int i, count = ntohl (mp->count);
4709
4710   if (count > 0)
4711     {
4712       vat_json_node_t node;
4713
4714       vat_json_init_object (&node);
4715       for (i = 0; i < count; i++)
4716         {
4717           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4718         }
4719       vat_json_print (vam->ofp, &node);
4720       vat_json_free (&node);
4721     }
4722   vam->retval = ntohl (mp->retval);
4723   vam->result_ready = 1;
4724 }
4725
4726 static void
4727   vl_api_classify_table_by_interface_reply_t_handler
4728   (vl_api_classify_table_by_interface_reply_t * mp)
4729 {
4730   vat_main_t *vam = &vat_main;
4731   u32 table_id;
4732
4733   table_id = ntohl (mp->l2_table_id);
4734   if (table_id != ~0)
4735     print (vam->ofp, "l2 table id : %d", table_id);
4736   else
4737     print (vam->ofp, "l2 table id : No input ACL tables configured");
4738   table_id = ntohl (mp->ip4_table_id);
4739   if (table_id != ~0)
4740     print (vam->ofp, "ip4 table id : %d", table_id);
4741   else
4742     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4743   table_id = ntohl (mp->ip6_table_id);
4744   if (table_id != ~0)
4745     print (vam->ofp, "ip6 table id : %d", table_id);
4746   else
4747     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4748   vam->retval = ntohl (mp->retval);
4749   vam->result_ready = 1;
4750 }
4751
4752 static void
4753   vl_api_classify_table_by_interface_reply_t_handler_json
4754   (vl_api_classify_table_by_interface_reply_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t node;
4758
4759   vat_json_init_object (&node);
4760
4761   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4762   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4763   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4764
4765   vat_json_print (vam->ofp, &node);
4766   vat_json_free (&node);
4767
4768   vam->retval = ntohl (mp->retval);
4769   vam->result_ready = 1;
4770 }
4771
4772 static void vl_api_policer_add_del_reply_t_handler
4773   (vl_api_policer_add_del_reply_t * mp)
4774 {
4775   vat_main_t *vam = &vat_main;
4776   i32 retval = ntohl (mp->retval);
4777   if (vam->async_mode)
4778     {
4779       vam->async_errors += (retval < 0);
4780     }
4781   else
4782     {
4783       vam->retval = retval;
4784       vam->result_ready = 1;
4785       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4786         /*
4787          * Note: this is just barely thread-safe, depends on
4788          * the main thread spinning waiting for an answer...
4789          */
4790         errmsg ("policer index %d", ntohl (mp->policer_index));
4791     }
4792 }
4793
4794 static void vl_api_policer_add_del_reply_t_handler_json
4795   (vl_api_policer_add_del_reply_t * mp)
4796 {
4797   vat_main_t *vam = &vat_main;
4798   vat_json_node_t node;
4799
4800   vat_json_init_object (&node);
4801   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4802   vat_json_object_add_uint (&node, "policer_index",
4803                             ntohl (mp->policer_index));
4804
4805   vat_json_print (vam->ofp, &node);
4806   vat_json_free (&node);
4807
4808   vam->retval = ntohl (mp->retval);
4809   vam->result_ready = 1;
4810 }
4811
4812 /* Format hex dump. */
4813 u8 *
4814 format_hex_bytes (u8 * s, va_list * va)
4815 {
4816   u8 *bytes = va_arg (*va, u8 *);
4817   int n_bytes = va_arg (*va, int);
4818   uword i;
4819
4820   /* Print short or long form depending on byte count. */
4821   uword short_form = n_bytes <= 32;
4822   u32 indent = format_get_indent (s);
4823
4824   if (n_bytes == 0)
4825     return s;
4826
4827   for (i = 0; i < n_bytes; i++)
4828     {
4829       if (!short_form && (i % 32) == 0)
4830         s = format (s, "%08x: ", i);
4831       s = format (s, "%02x", bytes[i]);
4832       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4833         s = format (s, "\n%U", format_white_space, indent);
4834     }
4835
4836   return s;
4837 }
4838
4839 static void
4840 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4841                                             * mp)
4842 {
4843   vat_main_t *vam = &vat_main;
4844   i32 retval = ntohl (mp->retval);
4845   if (retval == 0)
4846     {
4847       print (vam->ofp, "classify table info :");
4848       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4849              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4850              ntohl (mp->miss_next_index));
4851       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4852              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4853              ntohl (mp->match_n_vectors));
4854       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4855              ntohl (mp->mask_length));
4856     }
4857   vam->retval = retval;
4858   vam->result_ready = 1;
4859 }
4860
4861 static void
4862   vl_api_classify_table_info_reply_t_handler_json
4863   (vl_api_classify_table_info_reply_t * mp)
4864 {
4865   vat_main_t *vam = &vat_main;
4866   vat_json_node_t node;
4867
4868   i32 retval = ntohl (mp->retval);
4869   if (retval == 0)
4870     {
4871       vat_json_init_object (&node);
4872
4873       vat_json_object_add_int (&node, "sessions",
4874                                ntohl (mp->active_sessions));
4875       vat_json_object_add_int (&node, "nexttbl",
4876                                ntohl (mp->next_table_index));
4877       vat_json_object_add_int (&node, "nextnode",
4878                                ntohl (mp->miss_next_index));
4879       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4880       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4881       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4882       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4883                       ntohl (mp->mask_length), 0);
4884       vat_json_object_add_string_copy (&node, "mask", s);
4885
4886       vat_json_print (vam->ofp, &node);
4887       vat_json_free (&node);
4888     }
4889   vam->retval = ntohl (mp->retval);
4890   vam->result_ready = 1;
4891 }
4892
4893 static void
4894 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4895                                            mp)
4896 {
4897   vat_main_t *vam = &vat_main;
4898
4899   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4900          ntohl (mp->hit_next_index), ntohl (mp->advance),
4901          ntohl (mp->opaque_index));
4902   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4903          ntohl (mp->match_length));
4904 }
4905
4906 static void
4907   vl_api_classify_session_details_t_handler_json
4908   (vl_api_classify_session_details_t * mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911   vat_json_node_t *node = NULL;
4912
4913   if (VAT_JSON_ARRAY != vam->json_tree.type)
4914     {
4915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4916       vat_json_init_array (&vam->json_tree);
4917     }
4918   node = vat_json_array_add (&vam->json_tree);
4919
4920   vat_json_init_object (node);
4921   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4922   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4923   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4924   u8 *s =
4925     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4926             0);
4927   vat_json_object_add_string_copy (node, "match", s);
4928 }
4929
4930 static void vl_api_pg_create_interface_reply_t_handler
4931   (vl_api_pg_create_interface_reply_t * mp)
4932 {
4933   vat_main_t *vam = &vat_main;
4934
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_pg_create_interface_reply_t_handler_json
4940   (vl_api_pg_create_interface_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   vat_json_node_t node;
4944
4945   i32 retval = ntohl (mp->retval);
4946   if (retval == 0)
4947     {
4948       vat_json_init_object (&node);
4949
4950       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4951
4952       vat_json_print (vam->ofp, &node);
4953       vat_json_free (&node);
4954     }
4955   vam->retval = ntohl (mp->retval);
4956   vam->result_ready = 1;
4957 }
4958
4959 static void vl_api_policer_classify_details_t_handler
4960   (vl_api_policer_classify_details_t * mp)
4961 {
4962   vat_main_t *vam = &vat_main;
4963
4964   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4965          ntohl (mp->table_index));
4966 }
4967
4968 static void vl_api_policer_classify_details_t_handler_json
4969   (vl_api_policer_classify_details_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972   vat_json_node_t *node;
4973
4974   if (VAT_JSON_ARRAY != vam->json_tree.type)
4975     {
4976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4977       vat_json_init_array (&vam->json_tree);
4978     }
4979   node = vat_json_array_add (&vam->json_tree);
4980
4981   vat_json_init_object (node);
4982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4983   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4984 }
4985
4986 static void vl_api_flow_classify_details_t_handler
4987   (vl_api_flow_classify_details_t * mp)
4988 {
4989   vat_main_t *vam = &vat_main;
4990
4991   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4992          ntohl (mp->table_index));
4993 }
4994
4995 static void vl_api_flow_classify_details_t_handler_json
4996   (vl_api_flow_classify_details_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   vat_json_node_t *node;
5000
5001   if (VAT_JSON_ARRAY != vam->json_tree.type)
5002     {
5003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5004       vat_json_init_array (&vam->json_tree);
5005     }
5006   node = vat_json_array_add (&vam->json_tree);
5007
5008   vat_json_init_object (node);
5009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5010   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5011 }
5012
5013 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5014 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5015 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5016 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5017 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5018 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5019 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5020 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5021 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5022 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5023
5024 /*
5025  * Generate boilerplate reply handlers, which
5026  * dig the return value out of the xxx_reply_t API message,
5027  * stick it into vam->retval, and set vam->result_ready
5028  *
5029  * Could also do this by pointing N message decode slots at
5030  * a single function, but that could break in subtle ways.
5031  */
5032
5033 #define foreach_standard_reply_retval_handler           \
5034 _(sw_interface_set_flags_reply)                         \
5035 _(sw_interface_add_del_address_reply)                   \
5036 _(sw_interface_set_rx_mode_reply)                       \
5037 _(sw_interface_set_rx_placement_reply)                  \
5038 _(sw_interface_set_table_reply)                         \
5039 _(sw_interface_set_mpls_enable_reply)                   \
5040 _(sw_interface_set_vpath_reply)                         \
5041 _(sw_interface_set_vxlan_bypass_reply)                  \
5042 _(sw_interface_set_geneve_bypass_reply)                 \
5043 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5044 _(sw_interface_set_l2_bridge_reply)                     \
5045 _(sw_interface_set_bond_weight_reply)                   \
5046 _(bridge_domain_add_del_reply)                          \
5047 _(sw_interface_set_l2_xconnect_reply)                   \
5048 _(l2fib_add_del_reply)                                  \
5049 _(l2fib_flush_int_reply)                                \
5050 _(l2fib_flush_bd_reply)                                 \
5051 _(ip_route_add_del_reply)                               \
5052 _(ip_table_add_del_reply)                               \
5053 _(ip_table_replace_begin_reply)                         \
5054 _(ip_table_flush_reply)                                 \
5055 _(ip_table_replace_end_reply)                           \
5056 _(ip_mroute_add_del_reply)                              \
5057 _(mpls_route_add_del_reply)                             \
5058 _(mpls_table_add_del_reply)                             \
5059 _(mpls_ip_bind_unbind_reply)                            \
5060 _(bier_route_add_del_reply)                             \
5061 _(bier_table_add_del_reply)                             \
5062 _(sw_interface_set_unnumbered_reply)                    \
5063 _(set_ip_flow_hash_reply)                               \
5064 _(sw_interface_ip6_enable_disable_reply)                \
5065 _(l2_patch_add_del_reply)                               \
5066 _(sr_mpls_policy_add_reply)                             \
5067 _(sr_mpls_policy_mod_reply)                             \
5068 _(sr_mpls_policy_del_reply)                             \
5069 _(sr_policy_add_reply)                                  \
5070 _(sr_policy_mod_reply)                                  \
5071 _(sr_policy_del_reply)                                  \
5072 _(sr_localsid_add_del_reply)                            \
5073 _(sr_steering_add_del_reply)                            \
5074 _(classify_add_del_session_reply)                       \
5075 _(classify_set_interface_ip_table_reply)                \
5076 _(classify_set_interface_l2_tables_reply)               \
5077 _(l2tpv3_set_tunnel_cookies_reply)                      \
5078 _(l2tpv3_interface_enable_disable_reply)                \
5079 _(l2tpv3_set_lookup_key_reply)                          \
5080 _(l2_fib_clear_table_reply)                             \
5081 _(l2_interface_efp_filter_reply)                        \
5082 _(l2_interface_vlan_tag_rewrite_reply)                  \
5083 _(modify_vhost_user_if_reply)                           \
5084 _(delete_vhost_user_if_reply)                           \
5085 _(want_l2_macs_events_reply)                            \
5086 _(input_acl_set_interface_reply)                        \
5087 _(ipsec_spd_add_del_reply)                              \
5088 _(ipsec_interface_add_del_spd_reply)                    \
5089 _(ipsec_spd_entry_add_del_reply)                        \
5090 _(ipsec_sad_entry_add_del_reply)                        \
5091 _(ipsec_tunnel_if_add_del_reply)                        \
5092 _(ipsec_tunnel_if_set_sa_reply)                         \
5093 _(delete_loopback_reply)                                \
5094 _(bd_ip_mac_add_del_reply)                              \
5095 _(bd_ip_mac_flush_reply)                                \
5096 _(want_interface_events_reply)                          \
5097 _(cop_interface_enable_disable_reply)                   \
5098 _(cop_whitelist_enable_disable_reply)                   \
5099 _(sw_interface_clear_stats_reply)                       \
5100 _(ioam_enable_reply)                                    \
5101 _(ioam_disable_reply)                                   \
5102 _(one_add_del_locator_reply)                            \
5103 _(one_add_del_local_eid_reply)                          \
5104 _(one_add_del_remote_mapping_reply)                     \
5105 _(one_add_del_adjacency_reply)                          \
5106 _(one_add_del_map_resolver_reply)                       \
5107 _(one_add_del_map_server_reply)                         \
5108 _(one_enable_disable_reply)                             \
5109 _(one_rloc_probe_enable_disable_reply)                  \
5110 _(one_map_register_enable_disable_reply)                \
5111 _(one_map_register_set_ttl_reply)                       \
5112 _(one_set_transport_protocol_reply)                     \
5113 _(one_map_register_fallback_threshold_reply)            \
5114 _(one_pitr_set_locator_set_reply)                       \
5115 _(one_map_request_mode_reply)                           \
5116 _(one_add_del_map_request_itr_rlocs_reply)              \
5117 _(one_eid_table_add_del_map_reply)                      \
5118 _(one_use_petr_reply)                                   \
5119 _(one_stats_enable_disable_reply)                       \
5120 _(one_add_del_l2_arp_entry_reply)                       \
5121 _(one_add_del_ndp_entry_reply)                          \
5122 _(one_stats_flush_reply)                                \
5123 _(one_enable_disable_xtr_mode_reply)                    \
5124 _(one_enable_disable_pitr_mode_reply)                   \
5125 _(one_enable_disable_petr_mode_reply)                   \
5126 _(gpe_enable_disable_reply)                             \
5127 _(gpe_set_encap_mode_reply)                             \
5128 _(gpe_add_del_iface_reply)                              \
5129 _(gpe_add_del_native_fwd_rpath_reply)                   \
5130 _(af_packet_delete_reply)                               \
5131 _(policer_classify_set_interface_reply)                 \
5132 _(set_ipfix_exporter_reply)                             \
5133 _(set_ipfix_classify_stream_reply)                      \
5134 _(ipfix_classify_table_add_del_reply)                   \
5135 _(flow_classify_set_interface_reply)                    \
5136 _(sw_interface_span_enable_disable_reply)               \
5137 _(pg_capture_reply)                                     \
5138 _(pg_enable_disable_reply)                              \
5139 _(ip_source_and_port_range_check_add_del_reply)         \
5140 _(ip_source_and_port_range_check_interface_add_del_reply)\
5141 _(delete_subif_reply)                                   \
5142 _(l2_interface_pbb_tag_rewrite_reply)                   \
5143 _(set_punt_reply)                                       \
5144 _(feature_enable_disable_reply)                         \
5145 _(feature_gso_enable_disable_reply)                     \
5146 _(sw_interface_tag_add_del_reply)                       \
5147 _(sw_interface_add_del_mac_address_reply)               \
5148 _(hw_interface_set_mtu_reply)                           \
5149 _(p2p_ethernet_add_reply)                               \
5150 _(p2p_ethernet_del_reply)                               \
5151 _(lldp_config_reply)                                    \
5152 _(sw_interface_set_lldp_reply)                          \
5153 _(tcp_configure_src_addresses_reply)                    \
5154 _(session_rule_add_del_reply)                           \
5155 _(ip_container_proxy_add_del_reply)                     \
5156 _(output_acl_set_interface_reply)                       \
5157 _(qos_record_enable_disable_reply)
5158
5159 #define _(n)                                    \
5160     static void vl_api_##n##_t_handler          \
5161     (vl_api_##n##_t * mp)                       \
5162     {                                           \
5163         vat_main_t * vam = &vat_main;           \
5164         i32 retval = ntohl(mp->retval);         \
5165         if (vam->async_mode) {                  \
5166             vam->async_errors += (retval < 0);  \
5167         } else {                                \
5168             vam->retval = retval;               \
5169             vam->result_ready = 1;              \
5170         }                                       \
5171     }
5172 foreach_standard_reply_retval_handler;
5173 #undef _
5174
5175 #define _(n)                                    \
5176     static void vl_api_##n##_t_handler_json     \
5177     (vl_api_##n##_t * mp)                       \
5178     {                                           \
5179         vat_main_t * vam = &vat_main;           \
5180         vat_json_node_t node;                   \
5181         vat_json_init_object(&node);            \
5182         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5183         vat_json_print(vam->ofp, &node);        \
5184         vam->retval = ntohl(mp->retval);        \
5185         vam->result_ready = 1;                  \
5186     }
5187 foreach_standard_reply_retval_handler;
5188 #undef _
5189
5190 /*
5191  * Table of message reply handlers, must include boilerplate handlers
5192  * we just generated
5193  */
5194
5195 #define foreach_vpe_api_reply_msg                                       \
5196 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5197 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5198 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5199 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5200 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5201 _(CLI_REPLY, cli_reply)                                                 \
5202 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5203 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5204   sw_interface_add_del_address_reply)                                   \
5205 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5206 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5207 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5208 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5209 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5210 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5211 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5212 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5213 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5214 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5215   sw_interface_set_l2_xconnect_reply)                                   \
5216 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5217   sw_interface_set_l2_bridge_reply)                                     \
5218 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5219 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5220 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5221 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5222 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5223 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5224 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5225 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5226 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5227 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5228 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5229 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5230 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5231 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5232 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5233 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5234 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5235 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5236 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5237 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5238 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5239 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5240 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5241 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5242 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5243 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5244 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5245 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5246 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5247 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5248 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5249 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5250 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5251 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5252   sw_interface_set_unnumbered_reply)                                    \
5253 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5254 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5255 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5256 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5257   sw_interface_ip6_enable_disable_reply)                                \
5258 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5259 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5260 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5261 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5262 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5263 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5264 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5265 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5266 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5267 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5268 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5269 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5270 classify_set_interface_ip_table_reply)                                  \
5271 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5272   classify_set_interface_l2_tables_reply)                               \
5273 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5274 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5275 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5276 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5277 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5278   l2tpv3_interface_enable_disable_reply)                                \
5279 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5280 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5281 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5282 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5283 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5284 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5285 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5286 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5287 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5288 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5289 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5290 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5291 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5292 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5293 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5294 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5295 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5296 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5297 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5298 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5299 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5300 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5301 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5302 _(L2_MACS_EVENT, l2_macs_event)                                         \
5303 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5304 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5305 _(IP_DETAILS, ip_details)                                               \
5306 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5307 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5308 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5309 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5310 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5311 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5312 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5313 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5314 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5315 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5316 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5317 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5318 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5319 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5320 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5321 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5322 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5323 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5324 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5325 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5326 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5327 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5328 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5329 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5330 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5331 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5332 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5333 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5334   one_map_register_enable_disable_reply)                                \
5335 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5336 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5337 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5338 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5339   one_map_register_fallback_threshold_reply)                            \
5340 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5341   one_rloc_probe_enable_disable_reply)                                  \
5342 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5343 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5344 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5345 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5346 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5347 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5348 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5349 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5350 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5351 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5352 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5353 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5354 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5355 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5356 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5357 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5358   show_one_stats_enable_disable_reply)                                  \
5359 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5360 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5361 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5362 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5363 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5364 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5365 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5366 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5367   one_enable_disable_pitr_mode_reply)                                   \
5368 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5369   one_enable_disable_petr_mode_reply)                                   \
5370 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5371 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5372 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5373 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5374 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5375 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5376 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5377 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5378 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5379 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5380 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5381 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5382   gpe_add_del_native_fwd_rpath_reply)                                   \
5383 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5384   gpe_fwd_entry_path_details)                                           \
5385 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5386 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5387   one_add_del_map_request_itr_rlocs_reply)                              \
5388 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5389   one_get_map_request_itr_rlocs_reply)                                  \
5390 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5391 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5392 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5393 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5394 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5395 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5396   show_one_map_register_state_reply)                                    \
5397 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5398 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5399   show_one_map_register_fallback_threshold_reply)                       \
5400 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5401 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5402 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5403 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5404 _(POLICER_DETAILS, policer_details)                                     \
5405 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5406 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5407 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5408 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5409 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5410 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5411 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5412 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5413 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5414 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5415 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5416 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5417 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5418 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5419 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5420 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5421 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5422 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5423 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5424 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5425 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5426 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5427 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5428 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5429  ip_source_and_port_range_check_add_del_reply)                          \
5430 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5431  ip_source_and_port_range_check_interface_add_del_reply)                \
5432 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5433 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5434 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5435 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5436 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5437 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5438 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5439 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5440 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5441 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5442 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5443 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5444 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5445 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5446 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5447 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5448 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5449 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5450 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5451 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5452 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5453 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5454 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5455
5456 #define foreach_standalone_reply_msg                                    \
5457 _(SW_INTERFACE_EVENT, sw_interface_event)
5458
5459 typedef struct
5460 {
5461   u8 *name;
5462   u32 value;
5463 } name_sort_t;
5464
5465 #define STR_VTR_OP_CASE(op)     \
5466     case L2_VTR_ ## op:         \
5467         return "" # op;
5468
5469 static const char *
5470 str_vtr_op (u32 vtr_op)
5471 {
5472   switch (vtr_op)
5473     {
5474       STR_VTR_OP_CASE (DISABLED);
5475       STR_VTR_OP_CASE (PUSH_1);
5476       STR_VTR_OP_CASE (PUSH_2);
5477       STR_VTR_OP_CASE (POP_1);
5478       STR_VTR_OP_CASE (POP_2);
5479       STR_VTR_OP_CASE (TRANSLATE_1_1);
5480       STR_VTR_OP_CASE (TRANSLATE_1_2);
5481       STR_VTR_OP_CASE (TRANSLATE_2_1);
5482       STR_VTR_OP_CASE (TRANSLATE_2_2);
5483     }
5484
5485   return "UNKNOWN";
5486 }
5487
5488 static int
5489 dump_sub_interface_table (vat_main_t * vam)
5490 {
5491   const sw_interface_subif_t *sub = NULL;
5492
5493   if (vam->json_output)
5494     {
5495       clib_warning
5496         ("JSON output supported only for VPE API calls and dump_stats_table");
5497       return -99;
5498     }
5499
5500   print (vam->ofp,
5501          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5502          "Interface", "sw_if_index",
5503          "sub id", "dot1ad", "tags", "outer id",
5504          "inner id", "exact", "default", "outer any", "inner any");
5505
5506   vec_foreach (sub, vam->sw_if_subif_table)
5507   {
5508     print (vam->ofp,
5509            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5510            sub->interface_name,
5511            sub->sw_if_index,
5512            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5513            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5514            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5515            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5516     if (sub->vtr_op != L2_VTR_DISABLED)
5517       {
5518         print (vam->ofp,
5519                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5520                "tag1: %d tag2: %d ]",
5521                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5522                sub->vtr_tag1, sub->vtr_tag2);
5523       }
5524   }
5525
5526   return 0;
5527 }
5528
5529 static int
5530 name_sort_cmp (void *a1, void *a2)
5531 {
5532   name_sort_t *n1 = a1;
5533   name_sort_t *n2 = a2;
5534
5535   return strcmp ((char *) n1->name, (char *) n2->name);
5536 }
5537
5538 static int
5539 dump_interface_table (vat_main_t * vam)
5540 {
5541   hash_pair_t *p;
5542   name_sort_t *nses = 0, *ns;
5543
5544   if (vam->json_output)
5545     {
5546       clib_warning
5547         ("JSON output supported only for VPE API calls and dump_stats_table");
5548       return -99;
5549     }
5550
5551   /* *INDENT-OFF* */
5552   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5553   ({
5554     vec_add2 (nses, ns, 1);
5555     ns->name = (u8 *)(p->key);
5556     ns->value = (u32) p->value[0];
5557   }));
5558   /* *INDENT-ON* */
5559
5560   vec_sort_with_function (nses, name_sort_cmp);
5561
5562   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5563   vec_foreach (ns, nses)
5564   {
5565     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5566   }
5567   vec_free (nses);
5568   return 0;
5569 }
5570
5571 static int
5572 dump_ip_table (vat_main_t * vam, int is_ipv6)
5573 {
5574   const ip_details_t *det = NULL;
5575   const ip_address_details_t *address = NULL;
5576   u32 i = ~0;
5577
5578   print (vam->ofp, "%-12s", "sw_if_index");
5579
5580   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5581   {
5582     i++;
5583     if (!det->present)
5584       {
5585         continue;
5586       }
5587     print (vam->ofp, "%-12d", i);
5588     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5589     if (!det->addr)
5590       {
5591         continue;
5592       }
5593     vec_foreach (address, det->addr)
5594     {
5595       print (vam->ofp,
5596              "            %-30U%-13d",
5597              is_ipv6 ? format_ip6_address : format_ip4_address,
5598              address->ip, address->prefix_length);
5599     }
5600   }
5601
5602   return 0;
5603 }
5604
5605 static int
5606 dump_ipv4_table (vat_main_t * vam)
5607 {
5608   if (vam->json_output)
5609     {
5610       clib_warning
5611         ("JSON output supported only for VPE API calls and dump_stats_table");
5612       return -99;
5613     }
5614
5615   return dump_ip_table (vam, 0);
5616 }
5617
5618 static int
5619 dump_ipv6_table (vat_main_t * vam)
5620 {
5621   if (vam->json_output)
5622     {
5623       clib_warning
5624         ("JSON output supported only for VPE API calls and dump_stats_table");
5625       return -99;
5626     }
5627
5628   return dump_ip_table (vam, 1);
5629 }
5630
5631 /*
5632  * Pass CLI buffers directly in the CLI_INBAND API message,
5633  * instead of an additional shared memory area.
5634  */
5635 static int
5636 exec_inband (vat_main_t * vam)
5637 {
5638   vl_api_cli_inband_t *mp;
5639   unformat_input_t *i = vam->input;
5640   int ret;
5641
5642   if (vec_len (i->buffer) == 0)
5643     return -1;
5644
5645   if (vam->exec_mode == 0 && unformat (i, "mode"))
5646     {
5647       vam->exec_mode = 1;
5648       return 0;
5649     }
5650   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5651     {
5652       vam->exec_mode = 0;
5653       return 0;
5654     }
5655
5656   /*
5657    * In order for the CLI command to work, it
5658    * must be a vector ending in \n, not a C-string ending
5659    * in \n\0.
5660    */
5661   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5662   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5663
5664   S (mp);
5665   W (ret);
5666   /* json responses may or may not include a useful reply... */
5667   if (vec_len (vam->cmd_reply))
5668     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5669   return ret;
5670 }
5671
5672 int
5673 exec (vat_main_t * vam)
5674 {
5675   return exec_inband (vam);
5676 }
5677
5678 static int
5679 api_create_loopback (vat_main_t * vam)
5680 {
5681   unformat_input_t *i = vam->input;
5682   vl_api_create_loopback_t *mp;
5683   vl_api_create_loopback_instance_t *mp_lbi;
5684   u8 mac_address[6];
5685   u8 mac_set = 0;
5686   u8 is_specified = 0;
5687   u32 user_instance = 0;
5688   int ret;
5689
5690   clib_memset (mac_address, 0, sizeof (mac_address));
5691
5692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5693     {
5694       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5695         mac_set = 1;
5696       if (unformat (i, "instance %d", &user_instance))
5697         is_specified = 1;
5698       else
5699         break;
5700     }
5701
5702   if (is_specified)
5703     {
5704       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5705       mp_lbi->is_specified = is_specified;
5706       if (is_specified)
5707         mp_lbi->user_instance = htonl (user_instance);
5708       if (mac_set)
5709         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5710       S (mp_lbi);
5711     }
5712   else
5713     {
5714       /* Construct the API message */
5715       M (CREATE_LOOPBACK, mp);
5716       if (mac_set)
5717         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5718       S (mp);
5719     }
5720
5721   W (ret);
5722   return ret;
5723 }
5724
5725 static int
5726 api_delete_loopback (vat_main_t * vam)
5727 {
5728   unformat_input_t *i = vam->input;
5729   vl_api_delete_loopback_t *mp;
5730   u32 sw_if_index = ~0;
5731   int ret;
5732
5733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5734     {
5735       if (unformat (i, "sw_if_index %d", &sw_if_index))
5736         ;
5737       else
5738         break;
5739     }
5740
5741   if (sw_if_index == ~0)
5742     {
5743       errmsg ("missing sw_if_index");
5744       return -99;
5745     }
5746
5747   /* Construct the API message */
5748   M (DELETE_LOOPBACK, mp);
5749   mp->sw_if_index = ntohl (sw_if_index);
5750
5751   S (mp);
5752   W (ret);
5753   return ret;
5754 }
5755
5756 static int
5757 api_want_interface_events (vat_main_t * vam)
5758 {
5759   unformat_input_t *i = vam->input;
5760   vl_api_want_interface_events_t *mp;
5761   int enable = -1;
5762   int ret;
5763
5764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5765     {
5766       if (unformat (i, "enable"))
5767         enable = 1;
5768       else if (unformat (i, "disable"))
5769         enable = 0;
5770       else
5771         break;
5772     }
5773
5774   if (enable == -1)
5775     {
5776       errmsg ("missing enable|disable");
5777       return -99;
5778     }
5779
5780   M (WANT_INTERFACE_EVENTS, mp);
5781   mp->enable_disable = enable;
5782
5783   vam->interface_event_display = enable;
5784
5785   S (mp);
5786   W (ret);
5787   return ret;
5788 }
5789
5790
5791 /* Note: non-static, called once to set up the initial intfc table */
5792 int
5793 api_sw_interface_dump (vat_main_t * vam)
5794 {
5795   vl_api_sw_interface_dump_t *mp;
5796   vl_api_control_ping_t *mp_ping;
5797   hash_pair_t *p;
5798   name_sort_t *nses = 0, *ns;
5799   sw_interface_subif_t *sub = NULL;
5800   int ret;
5801
5802   /* Toss the old name table */
5803   /* *INDENT-OFF* */
5804   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5805   ({
5806     vec_add2 (nses, ns, 1);
5807     ns->name = (u8 *)(p->key);
5808     ns->value = (u32) p->value[0];
5809   }));
5810   /* *INDENT-ON* */
5811
5812   hash_free (vam->sw_if_index_by_interface_name);
5813
5814   vec_foreach (ns, nses) vec_free (ns->name);
5815
5816   vec_free (nses);
5817
5818   vec_foreach (sub, vam->sw_if_subif_table)
5819   {
5820     vec_free (sub->interface_name);
5821   }
5822   vec_free (vam->sw_if_subif_table);
5823
5824   /* recreate the interface name hash table */
5825   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5826
5827   /*
5828    * Ask for all interface names. Otherwise, the epic catalog of
5829    * name filters becomes ridiculously long, and vat ends up needing
5830    * to be taught about new interface types.
5831    */
5832   M (SW_INTERFACE_DUMP, mp);
5833   S (mp);
5834
5835   /* Use a control ping for synchronization */
5836   MPING (CONTROL_PING, mp_ping);
5837   S (mp_ping);
5838
5839   W (ret);
5840   return ret;
5841 }
5842
5843 static int
5844 api_sw_interface_set_flags (vat_main_t * vam)
5845 {
5846   unformat_input_t *i = vam->input;
5847   vl_api_sw_interface_set_flags_t *mp;
5848   u32 sw_if_index;
5849   u8 sw_if_index_set = 0;
5850   u8 admin_up = 0;
5851   int ret;
5852
5853   /* Parse args required to build the message */
5854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5855     {
5856       if (unformat (i, "admin-up"))
5857         admin_up = 1;
5858       else if (unformat (i, "admin-down"))
5859         admin_up = 0;
5860       else
5861         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5862         sw_if_index_set = 1;
5863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5864         sw_if_index_set = 1;
5865       else
5866         break;
5867     }
5868
5869   if (sw_if_index_set == 0)
5870     {
5871       errmsg ("missing interface name or sw_if_index");
5872       return -99;
5873     }
5874
5875   /* Construct the API message */
5876   M (SW_INTERFACE_SET_FLAGS, mp);
5877   mp->sw_if_index = ntohl (sw_if_index);
5878   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5879
5880   /* send it... */
5881   S (mp);
5882
5883   /* Wait for a reply, return the good/bad news... */
5884   W (ret);
5885   return ret;
5886 }
5887
5888 static int
5889 api_sw_interface_set_rx_mode (vat_main_t * vam)
5890 {
5891   unformat_input_t *i = vam->input;
5892   vl_api_sw_interface_set_rx_mode_t *mp;
5893   u32 sw_if_index;
5894   u8 sw_if_index_set = 0;
5895   int ret;
5896   u8 queue_id_valid = 0;
5897   u32 queue_id;
5898   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5899
5900   /* Parse args required to build the message */
5901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902     {
5903       if (unformat (i, "queue %d", &queue_id))
5904         queue_id_valid = 1;
5905       else if (unformat (i, "polling"))
5906         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5907       else if (unformat (i, "interrupt"))
5908         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5909       else if (unformat (i, "adaptive"))
5910         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5911       else
5912         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5913         sw_if_index_set = 1;
5914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5915         sw_if_index_set = 1;
5916       else
5917         break;
5918     }
5919
5920   if (sw_if_index_set == 0)
5921     {
5922       errmsg ("missing interface name or sw_if_index");
5923       return -99;
5924     }
5925   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5926     {
5927       errmsg ("missing rx-mode");
5928       return -99;
5929     }
5930
5931   /* Construct the API message */
5932   M (SW_INTERFACE_SET_RX_MODE, mp);
5933   mp->sw_if_index = ntohl (sw_if_index);
5934   mp->mode = (vl_api_rx_mode_t) mode;
5935   mp->queue_id_valid = queue_id_valid;
5936   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5937
5938   /* send it... */
5939   S (mp);
5940
5941   /* Wait for a reply, return the good/bad news... */
5942   W (ret);
5943   return ret;
5944 }
5945
5946 static int
5947 api_sw_interface_set_rx_placement (vat_main_t * vam)
5948 {
5949   unformat_input_t *i = vam->input;
5950   vl_api_sw_interface_set_rx_placement_t *mp;
5951   u32 sw_if_index;
5952   u8 sw_if_index_set = 0;
5953   int ret;
5954   u8 is_main = 0;
5955   u32 queue_id, thread_index;
5956
5957   /* Parse args required to build the message */
5958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5959     {
5960       if (unformat (i, "queue %d", &queue_id))
5961         ;
5962       else if (unformat (i, "main"))
5963         is_main = 1;
5964       else if (unformat (i, "worker %d", &thread_index))
5965         ;
5966       else
5967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5968         sw_if_index_set = 1;
5969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5970         sw_if_index_set = 1;
5971       else
5972         break;
5973     }
5974
5975   if (sw_if_index_set == 0)
5976     {
5977       errmsg ("missing interface name or sw_if_index");
5978       return -99;
5979     }
5980
5981   if (is_main)
5982     thread_index = 0;
5983   /* Construct the API message */
5984   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5985   mp->sw_if_index = ntohl (sw_if_index);
5986   mp->worker_id = ntohl (thread_index);
5987   mp->queue_id = ntohl (queue_id);
5988   mp->is_main = is_main;
5989
5990   /* send it... */
5991   S (mp);
5992   /* Wait for a reply, return the good/bad news... */
5993   W (ret);
5994   return ret;
5995 }
5996
5997 static void vl_api_sw_interface_rx_placement_details_t_handler
5998   (vl_api_sw_interface_rx_placement_details_t * mp)
5999 {
6000   vat_main_t *vam = &vat_main;
6001   u32 worker_id = ntohl (mp->worker_id);
6002
6003   print (vam->ofp,
6004          "\n%-11d %-11s %-6d %-5d %-9s",
6005          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6006          worker_id, ntohl (mp->queue_id),
6007          (mp->mode ==
6008           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6009 }
6010
6011 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6012   (vl_api_sw_interface_rx_placement_details_t * mp)
6013 {
6014   vat_main_t *vam = &vat_main;
6015   vat_json_node_t *node = NULL;
6016
6017   if (VAT_JSON_ARRAY != vam->json_tree.type)
6018     {
6019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6020       vat_json_init_array (&vam->json_tree);
6021     }
6022   node = vat_json_array_add (&vam->json_tree);
6023
6024   vat_json_init_object (node);
6025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6026   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6027   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6028   vat_json_object_add_uint (node, "mode", mp->mode);
6029 }
6030
6031 static int
6032 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6033 {
6034   unformat_input_t *i = vam->input;
6035   vl_api_sw_interface_rx_placement_dump_t *mp;
6036   vl_api_control_ping_t *mp_ping;
6037   int ret;
6038   u32 sw_if_index;
6039   u8 sw_if_index_set = 0;
6040
6041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6042     {
6043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6044         sw_if_index_set++;
6045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6046         sw_if_index_set++;
6047       else
6048         break;
6049     }
6050
6051   print (vam->ofp,
6052          "\n%-11s %-11s %-6s %-5s %-4s",
6053          "sw_if_index", "main/worker", "thread", "queue", "mode");
6054
6055   /* Dump Interface rx placement */
6056   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6057
6058   if (sw_if_index_set)
6059     mp->sw_if_index = htonl (sw_if_index);
6060   else
6061     mp->sw_if_index = ~0;
6062
6063   S (mp);
6064
6065   /* Use a control ping for synchronization */
6066   MPING (CONTROL_PING, mp_ping);
6067   S (mp_ping);
6068
6069   W (ret);
6070   return ret;
6071 }
6072
6073 static int
6074 api_sw_interface_clear_stats (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_sw_interface_clear_stats_t *mp;
6078   u32 sw_if_index;
6079   u8 sw_if_index_set = 0;
6080   int ret;
6081
6082   /* Parse args required to build the message */
6083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6084     {
6085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6086         sw_if_index_set = 1;
6087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6088         sw_if_index_set = 1;
6089       else
6090         break;
6091     }
6092
6093   /* Construct the API message */
6094   M (SW_INTERFACE_CLEAR_STATS, mp);
6095
6096   if (sw_if_index_set == 1)
6097     mp->sw_if_index = ntohl (sw_if_index);
6098   else
6099     mp->sw_if_index = ~0;
6100
6101   /* send it... */
6102   S (mp);
6103
6104   /* Wait for a reply, return the good/bad news... */
6105   W (ret);
6106   return ret;
6107 }
6108
6109 static int
6110 api_sw_interface_add_del_address (vat_main_t * vam)
6111 {
6112   unformat_input_t *i = vam->input;
6113   vl_api_sw_interface_add_del_address_t *mp;
6114   u32 sw_if_index;
6115   u8 sw_if_index_set = 0;
6116   u8 is_add = 1, del_all = 0;
6117   u32 address_length = 0;
6118   u8 v4_address_set = 0;
6119   u8 v6_address_set = 0;
6120   ip4_address_t v4address;
6121   ip6_address_t v6address;
6122   int ret;
6123
6124   /* Parse args required to build the message */
6125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6126     {
6127       if (unformat (i, "del-all"))
6128         del_all = 1;
6129       else if (unformat (i, "del"))
6130         is_add = 0;
6131       else
6132         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6133         sw_if_index_set = 1;
6134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6135         sw_if_index_set = 1;
6136       else if (unformat (i, "%U/%d",
6137                          unformat_ip4_address, &v4address, &address_length))
6138         v4_address_set = 1;
6139       else if (unformat (i, "%U/%d",
6140                          unformat_ip6_address, &v6address, &address_length))
6141         v6_address_set = 1;
6142       else
6143         break;
6144     }
6145
6146   if (sw_if_index_set == 0)
6147     {
6148       errmsg ("missing interface name or sw_if_index");
6149       return -99;
6150     }
6151   if (v4_address_set && v6_address_set)
6152     {
6153       errmsg ("both v4 and v6 addresses set");
6154       return -99;
6155     }
6156   if (!v4_address_set && !v6_address_set && !del_all)
6157     {
6158       errmsg ("no addresses set");
6159       return -99;
6160     }
6161
6162   /* Construct the API message */
6163   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6164
6165   mp->sw_if_index = ntohl (sw_if_index);
6166   mp->is_add = is_add;
6167   mp->del_all = del_all;
6168   if (v6_address_set)
6169     {
6170       mp->prefix.address.af = ADDRESS_IP6;
6171       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6172     }
6173   else
6174     {
6175       mp->prefix.address.af = ADDRESS_IP4;
6176       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6177     }
6178   mp->prefix.len = address_length;
6179
6180   /* send it... */
6181   S (mp);
6182
6183   /* Wait for a reply, return good/bad news  */
6184   W (ret);
6185   return ret;
6186 }
6187
6188 static int
6189 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6190 {
6191   unformat_input_t *i = vam->input;
6192   vl_api_sw_interface_set_mpls_enable_t *mp;
6193   u32 sw_if_index;
6194   u8 sw_if_index_set = 0;
6195   u8 enable = 1;
6196   int ret;
6197
6198   /* Parse args required to build the message */
6199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6200     {
6201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6202         sw_if_index_set = 1;
6203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6204         sw_if_index_set = 1;
6205       else if (unformat (i, "disable"))
6206         enable = 0;
6207       else if (unformat (i, "dis"))
6208         enable = 0;
6209       else
6210         break;
6211     }
6212
6213   if (sw_if_index_set == 0)
6214     {
6215       errmsg ("missing interface name or sw_if_index");
6216       return -99;
6217     }
6218
6219   /* Construct the API message */
6220   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6221
6222   mp->sw_if_index = ntohl (sw_if_index);
6223   mp->enable = enable;
6224
6225   /* send it... */
6226   S (mp);
6227
6228   /* Wait for a reply... */
6229   W (ret);
6230   return ret;
6231 }
6232
6233 static int
6234 api_sw_interface_set_table (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_sw_interface_set_table_t *mp;
6238   u32 sw_if_index, vrf_id = 0;
6239   u8 sw_if_index_set = 0;
6240   u8 is_ipv6 = 0;
6241   int ret;
6242
6243   /* Parse args required to build the message */
6244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6245     {
6246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6247         sw_if_index_set = 1;
6248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6249         sw_if_index_set = 1;
6250       else if (unformat (i, "vrf %d", &vrf_id))
6251         ;
6252       else if (unformat (i, "ipv6"))
6253         is_ipv6 = 1;
6254       else
6255         break;
6256     }
6257
6258   if (sw_if_index_set == 0)
6259     {
6260       errmsg ("missing interface name or sw_if_index");
6261       return -99;
6262     }
6263
6264   /* Construct the API message */
6265   M (SW_INTERFACE_SET_TABLE, mp);
6266
6267   mp->sw_if_index = ntohl (sw_if_index);
6268   mp->is_ipv6 = is_ipv6;
6269   mp->vrf_id = ntohl (vrf_id);
6270
6271   /* send it... */
6272   S (mp);
6273
6274   /* Wait for a reply... */
6275   W (ret);
6276   return ret;
6277 }
6278
6279 static void vl_api_sw_interface_get_table_reply_t_handler
6280   (vl_api_sw_interface_get_table_reply_t * mp)
6281 {
6282   vat_main_t *vam = &vat_main;
6283
6284   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6285
6286   vam->retval = ntohl (mp->retval);
6287   vam->result_ready = 1;
6288
6289 }
6290
6291 static void vl_api_sw_interface_get_table_reply_t_handler_json
6292   (vl_api_sw_interface_get_table_reply_t * mp)
6293 {
6294   vat_main_t *vam = &vat_main;
6295   vat_json_node_t node;
6296
6297   vat_json_init_object (&node);
6298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6299   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6300
6301   vat_json_print (vam->ofp, &node);
6302   vat_json_free (&node);
6303
6304   vam->retval = ntohl (mp->retval);
6305   vam->result_ready = 1;
6306 }
6307
6308 static int
6309 api_sw_interface_get_table (vat_main_t * vam)
6310 {
6311   unformat_input_t *i = vam->input;
6312   vl_api_sw_interface_get_table_t *mp;
6313   u32 sw_if_index;
6314   u8 sw_if_index_set = 0;
6315   u8 is_ipv6 = 0;
6316   int ret;
6317
6318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6319     {
6320       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6321         sw_if_index_set = 1;
6322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6323         sw_if_index_set = 1;
6324       else if (unformat (i, "ipv6"))
6325         is_ipv6 = 1;
6326       else
6327         break;
6328     }
6329
6330   if (sw_if_index_set == 0)
6331     {
6332       errmsg ("missing interface name or sw_if_index");
6333       return -99;
6334     }
6335
6336   M (SW_INTERFACE_GET_TABLE, mp);
6337   mp->sw_if_index = htonl (sw_if_index);
6338   mp->is_ipv6 = is_ipv6;
6339
6340   S (mp);
6341   W (ret);
6342   return ret;
6343 }
6344
6345 static int
6346 api_sw_interface_set_vpath (vat_main_t * vam)
6347 {
6348   unformat_input_t *i = vam->input;
6349   vl_api_sw_interface_set_vpath_t *mp;
6350   u32 sw_if_index = 0;
6351   u8 sw_if_index_set = 0;
6352   u8 is_enable = 0;
6353   int ret;
6354
6355   /* Parse args required to build the message */
6356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6357     {
6358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6359         sw_if_index_set = 1;
6360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "enable"))
6363         is_enable = 1;
6364       else if (unformat (i, "disable"))
6365         is_enable = 0;
6366       else
6367         break;
6368     }
6369
6370   if (sw_if_index_set == 0)
6371     {
6372       errmsg ("missing interface name or sw_if_index");
6373       return -99;
6374     }
6375
6376   /* Construct the API message */
6377   M (SW_INTERFACE_SET_VPATH, mp);
6378
6379   mp->sw_if_index = ntohl (sw_if_index);
6380   mp->enable = is_enable;
6381
6382   /* send it... */
6383   S (mp);
6384
6385   /* Wait for a reply... */
6386   W (ret);
6387   return ret;
6388 }
6389
6390 static int
6391 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6392 {
6393   unformat_input_t *i = vam->input;
6394   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6395   u32 sw_if_index = 0;
6396   u8 sw_if_index_set = 0;
6397   u8 is_enable = 1;
6398   u8 is_ipv6 = 0;
6399   int ret;
6400
6401   /* Parse args required to build the message */
6402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403     {
6404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "enable"))
6409         is_enable = 1;
6410       else if (unformat (i, "disable"))
6411         is_enable = 0;
6412       else if (unformat (i, "ip4"))
6413         is_ipv6 = 0;
6414       else if (unformat (i, "ip6"))
6415         is_ipv6 = 1;
6416       else
6417         break;
6418     }
6419
6420   if (sw_if_index_set == 0)
6421     {
6422       errmsg ("missing interface name or sw_if_index");
6423       return -99;
6424     }
6425
6426   /* Construct the API message */
6427   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6428
6429   mp->sw_if_index = ntohl (sw_if_index);
6430   mp->enable = is_enable;
6431   mp->is_ipv6 = is_ipv6;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_geneve_bypass_t *mp;
6446   u32 sw_if_index = 0;
6447   u8 sw_if_index_set = 0;
6448   u8 is_enable = 1;
6449   u8 is_ipv6 = 0;
6450   int ret;
6451
6452   /* Parse args required to build the message */
6453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6454     {
6455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "enable"))
6460         is_enable = 1;
6461       else if (unformat (i, "disable"))
6462         is_enable = 0;
6463       else if (unformat (i, "ip4"))
6464         is_ipv6 = 0;
6465       else if (unformat (i, "ip6"))
6466         is_ipv6 = 1;
6467       else
6468         break;
6469     }
6470
6471   if (sw_if_index_set == 0)
6472     {
6473       errmsg ("missing interface name or sw_if_index");
6474       return -99;
6475     }
6476
6477   /* Construct the API message */
6478   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6479
6480   mp->sw_if_index = ntohl (sw_if_index);
6481   mp->enable = is_enable;
6482   mp->is_ipv6 = is_ipv6;
6483
6484   /* send it... */
6485   S (mp);
6486
6487   /* Wait for a reply... */
6488   W (ret);
6489   return ret;
6490 }
6491
6492 static int
6493 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_sw_interface_set_l2_xconnect_t *mp;
6497   u32 rx_sw_if_index;
6498   u8 rx_sw_if_index_set = 0;
6499   u32 tx_sw_if_index;
6500   u8 tx_sw_if_index_set = 0;
6501   u8 enable = 1;
6502   int ret;
6503
6504   /* Parse args required to build the message */
6505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506     {
6507       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6508         rx_sw_if_index_set = 1;
6509       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6510         tx_sw_if_index_set = 1;
6511       else if (unformat (i, "rx"))
6512         {
6513           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6514             {
6515               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6516                             &rx_sw_if_index))
6517                 rx_sw_if_index_set = 1;
6518             }
6519           else
6520             break;
6521         }
6522       else if (unformat (i, "tx"))
6523         {
6524           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6525             {
6526               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6527                             &tx_sw_if_index))
6528                 tx_sw_if_index_set = 1;
6529             }
6530           else
6531             break;
6532         }
6533       else if (unformat (i, "enable"))
6534         enable = 1;
6535       else if (unformat (i, "disable"))
6536         enable = 0;
6537       else
6538         break;
6539     }
6540
6541   if (rx_sw_if_index_set == 0)
6542     {
6543       errmsg ("missing rx interface name or rx_sw_if_index");
6544       return -99;
6545     }
6546
6547   if (enable && (tx_sw_if_index_set == 0))
6548     {
6549       errmsg ("missing tx interface name or tx_sw_if_index");
6550       return -99;
6551     }
6552
6553   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6554
6555   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6556   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6557   mp->enable = enable;
6558
6559   S (mp);
6560   W (ret);
6561   return ret;
6562 }
6563
6564 static int
6565 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6566 {
6567   unformat_input_t *i = vam->input;
6568   vl_api_sw_interface_set_l2_bridge_t *mp;
6569   vl_api_l2_port_type_t port_type;
6570   u32 rx_sw_if_index;
6571   u8 rx_sw_if_index_set = 0;
6572   u32 bd_id;
6573   u8 bd_id_set = 0;
6574   u32 shg = 0;
6575   u8 enable = 1;
6576   int ret;
6577
6578   port_type = L2_API_PORT_TYPE_NORMAL;
6579
6580   /* Parse args required to build the message */
6581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6582     {
6583       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6584         rx_sw_if_index_set = 1;
6585       else if (unformat (i, "bd_id %d", &bd_id))
6586         bd_id_set = 1;
6587       else
6588         if (unformat
6589             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6590         rx_sw_if_index_set = 1;
6591       else if (unformat (i, "shg %d", &shg))
6592         ;
6593       else if (unformat (i, "bvi"))
6594         port_type = L2_API_PORT_TYPE_BVI;
6595       else if (unformat (i, "uu-fwd"))
6596         port_type = L2_API_PORT_TYPE_UU_FWD;
6597       else if (unformat (i, "enable"))
6598         enable = 1;
6599       else if (unformat (i, "disable"))
6600         enable = 0;
6601       else
6602         break;
6603     }
6604
6605   if (rx_sw_if_index_set == 0)
6606     {
6607       errmsg ("missing rx interface name or sw_if_index");
6608       return -99;
6609     }
6610
6611   if (enable && (bd_id_set == 0))
6612     {
6613       errmsg ("missing bridge domain");
6614       return -99;
6615     }
6616
6617   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6618
6619   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6620   mp->bd_id = ntohl (bd_id);
6621   mp->shg = (u8) shg;
6622   mp->port_type = ntohl (port_type);
6623   mp->enable = enable;
6624
6625   S (mp);
6626   W (ret);
6627   return ret;
6628 }
6629
6630 static int
6631 api_bridge_domain_dump (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_bridge_domain_dump_t *mp;
6635   vl_api_control_ping_t *mp_ping;
6636   u32 bd_id = ~0;
6637   int ret;
6638
6639   /* Parse args required to build the message */
6640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6641     {
6642       if (unformat (i, "bd_id %d", &bd_id))
6643         ;
6644       else
6645         break;
6646     }
6647
6648   M (BRIDGE_DOMAIN_DUMP, mp);
6649   mp->bd_id = ntohl (bd_id);
6650   S (mp);
6651
6652   /* Use a control ping for synchronization */
6653   MPING (CONTROL_PING, mp_ping);
6654   S (mp_ping);
6655
6656   W (ret);
6657   return ret;
6658 }
6659
6660 static int
6661 api_bridge_domain_add_del (vat_main_t * vam)
6662 {
6663   unformat_input_t *i = vam->input;
6664   vl_api_bridge_domain_add_del_t *mp;
6665   u32 bd_id = ~0;
6666   u8 is_add = 1;
6667   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6668   u8 *bd_tag = NULL;
6669   u32 mac_age = 0;
6670   int ret;
6671
6672   /* Parse args required to build the message */
6673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6674     {
6675       if (unformat (i, "bd_id %d", &bd_id))
6676         ;
6677       else if (unformat (i, "flood %d", &flood))
6678         ;
6679       else if (unformat (i, "uu-flood %d", &uu_flood))
6680         ;
6681       else if (unformat (i, "forward %d", &forward))
6682         ;
6683       else if (unformat (i, "learn %d", &learn))
6684         ;
6685       else if (unformat (i, "arp-term %d", &arp_term))
6686         ;
6687       else if (unformat (i, "mac-age %d", &mac_age))
6688         ;
6689       else if (unformat (i, "bd-tag %s", &bd_tag))
6690         ;
6691       else if (unformat (i, "del"))
6692         {
6693           is_add = 0;
6694           flood = uu_flood = forward = learn = 0;
6695         }
6696       else
6697         break;
6698     }
6699
6700   if (bd_id == ~0)
6701     {
6702       errmsg ("missing bridge domain");
6703       ret = -99;
6704       goto done;
6705     }
6706
6707   if (mac_age > 255)
6708     {
6709       errmsg ("mac age must be less than 256 ");
6710       ret = -99;
6711       goto done;
6712     }
6713
6714   if ((bd_tag) && (vec_len (bd_tag) > 63))
6715     {
6716       errmsg ("bd-tag cannot be longer than 63");
6717       ret = -99;
6718       goto done;
6719     }
6720
6721   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6722
6723   mp->bd_id = ntohl (bd_id);
6724   mp->flood = flood;
6725   mp->uu_flood = uu_flood;
6726   mp->forward = forward;
6727   mp->learn = learn;
6728   mp->arp_term = arp_term;
6729   mp->is_add = is_add;
6730   mp->mac_age = (u8) mac_age;
6731   if (bd_tag)
6732     {
6733       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6734       mp->bd_tag[vec_len (bd_tag)] = 0;
6735     }
6736   S (mp);
6737   W (ret);
6738
6739 done:
6740   vec_free (bd_tag);
6741   return ret;
6742 }
6743
6744 static int
6745 api_l2fib_flush_bd (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_l2fib_flush_bd_t *mp;
6749   u32 bd_id = ~0;
6750   int ret;
6751
6752   /* Parse args required to build the message */
6753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6754     {
6755       if (unformat (i, "bd_id %d", &bd_id));
6756       else
6757         break;
6758     }
6759
6760   if (bd_id == ~0)
6761     {
6762       errmsg ("missing bridge domain");
6763       return -99;
6764     }
6765
6766   M (L2FIB_FLUSH_BD, mp);
6767
6768   mp->bd_id = htonl (bd_id);
6769
6770   S (mp);
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_l2fib_flush_int (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_l2fib_flush_int_t *mp;
6780   u32 sw_if_index = ~0;
6781   int ret;
6782
6783   /* Parse args required to build the message */
6784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6785     {
6786       if (unformat (i, "sw_if_index %d", &sw_if_index));
6787       else
6788         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6789       else
6790         break;
6791     }
6792
6793   if (sw_if_index == ~0)
6794     {
6795       errmsg ("missing interface name or sw_if_index");
6796       return -99;
6797     }
6798
6799   M (L2FIB_FLUSH_INT, mp);
6800
6801   mp->sw_if_index = ntohl (sw_if_index);
6802
6803   S (mp);
6804   W (ret);
6805   return ret;
6806 }
6807
6808 static int
6809 api_l2fib_add_del (vat_main_t * vam)
6810 {
6811   unformat_input_t *i = vam->input;
6812   vl_api_l2fib_add_del_t *mp;
6813   f64 timeout;
6814   u8 mac[6] = { 0 };
6815   u8 mac_set = 0;
6816   u32 bd_id;
6817   u8 bd_id_set = 0;
6818   u32 sw_if_index = 0;
6819   u8 sw_if_index_set = 0;
6820   u8 is_add = 1;
6821   u8 static_mac = 0;
6822   u8 filter_mac = 0;
6823   u8 bvi_mac = 0;
6824   int count = 1;
6825   f64 before = 0;
6826   int j;
6827
6828   /* Parse args required to build the message */
6829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6830     {
6831       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6832         mac_set = 1;
6833       else if (unformat (i, "bd_id %d", &bd_id))
6834         bd_id_set = 1;
6835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6836         sw_if_index_set = 1;
6837       else if (unformat (i, "sw_if"))
6838         {
6839           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6840             {
6841               if (unformat
6842                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6843                 sw_if_index_set = 1;
6844             }
6845           else
6846             break;
6847         }
6848       else if (unformat (i, "static"))
6849         static_mac = 1;
6850       else if (unformat (i, "filter"))
6851         {
6852           filter_mac = 1;
6853           static_mac = 1;
6854         }
6855       else if (unformat (i, "bvi"))
6856         {
6857           bvi_mac = 1;
6858           static_mac = 1;
6859         }
6860       else if (unformat (i, "del"))
6861         is_add = 0;
6862       else if (unformat (i, "count %d", &count))
6863         ;
6864       else
6865         break;
6866     }
6867
6868   if (mac_set == 0)
6869     {
6870       errmsg ("missing mac address");
6871       return -99;
6872     }
6873
6874   if (bd_id_set == 0)
6875     {
6876       errmsg ("missing bridge domain");
6877       return -99;
6878     }
6879
6880   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6881     {
6882       errmsg ("missing interface name or sw_if_index");
6883       return -99;
6884     }
6885
6886   if (count > 1)
6887     {
6888       /* Turn on async mode */
6889       vam->async_mode = 1;
6890       vam->async_errors = 0;
6891       before = vat_time_now (vam);
6892     }
6893
6894   for (j = 0; j < count; j++)
6895     {
6896       M (L2FIB_ADD_DEL, mp);
6897
6898       clib_memcpy (mp->mac, mac, 6);
6899       mp->bd_id = ntohl (bd_id);
6900       mp->is_add = is_add;
6901       mp->sw_if_index = ntohl (sw_if_index);
6902
6903       if (is_add)
6904         {
6905           mp->static_mac = static_mac;
6906           mp->filter_mac = filter_mac;
6907           mp->bvi_mac = bvi_mac;
6908         }
6909       increment_mac_address (mac);
6910       /* send it... */
6911       S (mp);
6912     }
6913
6914   if (count > 1)
6915     {
6916       vl_api_control_ping_t *mp_ping;
6917       f64 after;
6918
6919       /* Shut off async mode */
6920       vam->async_mode = 0;
6921
6922       MPING (CONTROL_PING, mp_ping);
6923       S (mp_ping);
6924
6925       timeout = vat_time_now (vam) + 1.0;
6926       while (vat_time_now (vam) < timeout)
6927         if (vam->result_ready == 1)
6928           goto out;
6929       vam->retval = -99;
6930
6931     out:
6932       if (vam->retval == -99)
6933         errmsg ("timeout");
6934
6935       if (vam->async_errors > 0)
6936         {
6937           errmsg ("%d asynchronous errors", vam->async_errors);
6938           vam->retval = -98;
6939         }
6940       vam->async_errors = 0;
6941       after = vat_time_now (vam);
6942
6943       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6944              count, after - before, count / (after - before));
6945     }
6946   else
6947     {
6948       int ret;
6949
6950       /* Wait for a reply... */
6951       W (ret);
6952       return ret;
6953     }
6954   /* Return the good/bad news */
6955   return (vam->retval);
6956 }
6957
6958 static int
6959 api_bridge_domain_set_mac_age (vat_main_t * vam)
6960 {
6961   unformat_input_t *i = vam->input;
6962   vl_api_bridge_domain_set_mac_age_t *mp;
6963   u32 bd_id = ~0;
6964   u32 mac_age = 0;
6965   int ret;
6966
6967   /* Parse args required to build the message */
6968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6969     {
6970       if (unformat (i, "bd_id %d", &bd_id));
6971       else if (unformat (i, "mac-age %d", &mac_age));
6972       else
6973         break;
6974     }
6975
6976   if (bd_id == ~0)
6977     {
6978       errmsg ("missing bridge domain");
6979       return -99;
6980     }
6981
6982   if (mac_age > 255)
6983     {
6984       errmsg ("mac age must be less than 256 ");
6985       return -99;
6986     }
6987
6988   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6989
6990   mp->bd_id = htonl (bd_id);
6991   mp->mac_age = (u8) mac_age;
6992
6993   S (mp);
6994   W (ret);
6995   return ret;
6996 }
6997
6998 static int
6999 api_l2_flags (vat_main_t * vam)
7000 {
7001   unformat_input_t *i = vam->input;
7002   vl_api_l2_flags_t *mp;
7003   u32 sw_if_index;
7004   u32 flags = 0;
7005   u8 sw_if_index_set = 0;
7006   u8 is_set = 0;
7007   int ret;
7008
7009   /* Parse args required to build the message */
7010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7011     {
7012       if (unformat (i, "sw_if_index %d", &sw_if_index))
7013         sw_if_index_set = 1;
7014       else if (unformat (i, "sw_if"))
7015         {
7016           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017             {
7018               if (unformat
7019                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7020                 sw_if_index_set = 1;
7021             }
7022           else
7023             break;
7024         }
7025       else if (unformat (i, "learn"))
7026         flags |= L2_LEARN;
7027       else if (unformat (i, "forward"))
7028         flags |= L2_FWD;
7029       else if (unformat (i, "flood"))
7030         flags |= L2_FLOOD;
7031       else if (unformat (i, "uu-flood"))
7032         flags |= L2_UU_FLOOD;
7033       else if (unformat (i, "arp-term"))
7034         flags |= L2_ARP_TERM;
7035       else if (unformat (i, "off"))
7036         is_set = 0;
7037       else if (unformat (i, "disable"))
7038         is_set = 0;
7039       else
7040         break;
7041     }
7042
7043   if (sw_if_index_set == 0)
7044     {
7045       errmsg ("missing interface name or sw_if_index");
7046       return -99;
7047     }
7048
7049   M (L2_FLAGS, mp);
7050
7051   mp->sw_if_index = ntohl (sw_if_index);
7052   mp->feature_bitmap = ntohl (flags);
7053   mp->is_set = is_set;
7054
7055   S (mp);
7056   W (ret);
7057   return ret;
7058 }
7059
7060 static int
7061 api_bridge_flags (vat_main_t * vam)
7062 {
7063   unformat_input_t *i = vam->input;
7064   vl_api_bridge_flags_t *mp;
7065   u32 bd_id;
7066   u8 bd_id_set = 0;
7067   u8 is_set = 1;
7068   bd_flags_t flags = 0;
7069   int ret;
7070
7071   /* Parse args required to build the message */
7072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7073     {
7074       if (unformat (i, "bd_id %d", &bd_id))
7075         bd_id_set = 1;
7076       else if (unformat (i, "learn"))
7077         flags |= BRIDGE_API_FLAG_LEARN;
7078       else if (unformat (i, "forward"))
7079         flags |= BRIDGE_API_FLAG_FWD;
7080       else if (unformat (i, "flood"))
7081         flags |= BRIDGE_API_FLAG_FLOOD;
7082       else if (unformat (i, "uu-flood"))
7083         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7084       else if (unformat (i, "arp-term"))
7085         flags |= BRIDGE_API_FLAG_ARP_TERM;
7086       else if (unformat (i, "off"))
7087         is_set = 0;
7088       else if (unformat (i, "disable"))
7089         is_set = 0;
7090       else
7091         break;
7092     }
7093
7094   if (bd_id_set == 0)
7095     {
7096       errmsg ("missing bridge domain");
7097       return -99;
7098     }
7099
7100   M (BRIDGE_FLAGS, mp);
7101
7102   mp->bd_id = ntohl (bd_id);
7103   mp->flags = ntohl (flags);
7104   mp->is_set = is_set;
7105
7106   S (mp);
7107   W (ret);
7108   return ret;
7109 }
7110
7111 static int
7112 api_bd_ip_mac_add_del (vat_main_t * vam)
7113 {
7114   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7115   vl_api_mac_address_t mac = { 0 };
7116   unformat_input_t *i = vam->input;
7117   vl_api_bd_ip_mac_add_del_t *mp;
7118   u32 bd_id;
7119   u8 is_add = 1;
7120   u8 bd_id_set = 0;
7121   u8 ip_set = 0;
7122   u8 mac_set = 0;
7123   int ret;
7124
7125
7126   /* Parse args required to build the message */
7127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7128     {
7129       if (unformat (i, "bd_id %d", &bd_id))
7130         {
7131           bd_id_set++;
7132         }
7133       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7134         {
7135           ip_set++;
7136         }
7137       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7138         {
7139           mac_set++;
7140         }
7141       else if (unformat (i, "del"))
7142         is_add = 0;
7143       else
7144         break;
7145     }
7146
7147   if (bd_id_set == 0)
7148     {
7149       errmsg ("missing bridge domain");
7150       return -99;
7151     }
7152   else if (ip_set == 0)
7153     {
7154       errmsg ("missing IP address");
7155       return -99;
7156     }
7157   else if (mac_set == 0)
7158     {
7159       errmsg ("missing MAC address");
7160       return -99;
7161     }
7162
7163   M (BD_IP_MAC_ADD_DEL, mp);
7164
7165   mp->entry.bd_id = ntohl (bd_id);
7166   mp->is_add = is_add;
7167
7168   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7169   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7170
7171   S (mp);
7172   W (ret);
7173   return ret;
7174 }
7175
7176 static int
7177 api_bd_ip_mac_flush (vat_main_t * vam)
7178 {
7179   unformat_input_t *i = vam->input;
7180   vl_api_bd_ip_mac_flush_t *mp;
7181   u32 bd_id;
7182   u8 bd_id_set = 0;
7183   int ret;
7184
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "bd_id %d", &bd_id))
7188         {
7189           bd_id_set++;
7190         }
7191       else
7192         break;
7193     }
7194
7195   if (bd_id_set == 0)
7196     {
7197       errmsg ("missing bridge domain");
7198       return -99;
7199     }
7200
7201   M (BD_IP_MAC_FLUSH, mp);
7202
7203   mp->bd_id = ntohl (bd_id);
7204
7205   S (mp);
7206   W (ret);
7207   return ret;
7208 }
7209
7210 static void vl_api_bd_ip_mac_details_t_handler
7211   (vl_api_bd_ip_mac_details_t * mp)
7212 {
7213   vat_main_t *vam = &vat_main;
7214
7215   print (vam->ofp,
7216          "\n%-5d %U %U",
7217          ntohl (mp->entry.bd_id),
7218          format_vl_api_mac_address, mp->entry.mac,
7219          format_vl_api_address, &mp->entry.ip);
7220 }
7221
7222 static void vl_api_bd_ip_mac_details_t_handler_json
7223   (vl_api_bd_ip_mac_details_t * mp)
7224 {
7225   vat_main_t *vam = &vat_main;
7226   vat_json_node_t *node = NULL;
7227
7228   if (VAT_JSON_ARRAY != vam->json_tree.type)
7229     {
7230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7231       vat_json_init_array (&vam->json_tree);
7232     }
7233   node = vat_json_array_add (&vam->json_tree);
7234
7235   vat_json_init_object (node);
7236   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7237   vat_json_object_add_string_copy (node, "mac_address",
7238                                    format (0, "%U", format_vl_api_mac_address,
7239                                            &mp->entry.mac));
7240   u8 *ip = 0;
7241
7242   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7243   vat_json_object_add_string_copy (node, "ip_address", ip);
7244   vec_free (ip);
7245 }
7246
7247 static int
7248 api_bd_ip_mac_dump (vat_main_t * vam)
7249 {
7250   unformat_input_t *i = vam->input;
7251   vl_api_bd_ip_mac_dump_t *mp;
7252   vl_api_control_ping_t *mp_ping;
7253   int ret;
7254   u32 bd_id;
7255   u8 bd_id_set = 0;
7256
7257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7258     {
7259       if (unformat (i, "bd_id %d", &bd_id))
7260         {
7261           bd_id_set++;
7262         }
7263       else
7264         break;
7265     }
7266
7267   print (vam->ofp,
7268          "\n%-5s %-7s %-20s %-30s",
7269          "bd_id", "is_ipv6", "mac_address", "ip_address");
7270
7271   /* Dump Bridge Domain Ip to Mac entries */
7272   M (BD_IP_MAC_DUMP, mp);
7273
7274   if (bd_id_set)
7275     mp->bd_id = htonl (bd_id);
7276   else
7277     mp->bd_id = ~0;
7278
7279   S (mp);
7280
7281   /* Use a control ping for synchronization */
7282   MPING (CONTROL_PING, mp_ping);
7283   S (mp_ping);
7284
7285   W (ret);
7286   return ret;
7287 }
7288
7289 static int
7290 api_tap_create_v2 (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_tap_create_v2_t *mp;
7294   u8 mac_address[6];
7295   u8 random_mac = 1;
7296   u32 id = ~0;
7297   u32 num_rx_queues = 0;
7298   u8 *host_if_name = 0;
7299   u8 host_if_name_set = 0;
7300   u8 *host_ns = 0;
7301   u8 host_ns_set = 0;
7302   u8 host_mac_addr[6];
7303   u8 host_mac_addr_set = 0;
7304   u8 *host_bridge = 0;
7305   u8 host_bridge_set = 0;
7306   u8 host_ip4_prefix_set = 0;
7307   u8 host_ip6_prefix_set = 0;
7308   ip4_address_t host_ip4_addr;
7309   ip4_address_t host_ip4_gw;
7310   u8 host_ip4_gw_set = 0;
7311   u32 host_ip4_prefix_len = 0;
7312   ip6_address_t host_ip6_addr;
7313   ip6_address_t host_ip6_gw;
7314   u8 host_ip6_gw_set = 0;
7315   u32 host_ip6_prefix_len = 0;
7316   u32 host_mtu_size = 0;
7317   u8 host_mtu_set = 0;
7318   u32 tap_flags = 0;
7319   int ret;
7320   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7321
7322   clib_memset (mac_address, 0, sizeof (mac_address));
7323
7324   /* Parse args required to build the message */
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "id %u", &id))
7328         ;
7329       else
7330         if (unformat
7331             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7332         random_mac = 0;
7333       else if (unformat (i, "host-if-name %s", &host_if_name))
7334         host_if_name_set = 1;
7335       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7336         ;
7337       else if (unformat (i, "host-ns %s", &host_ns))
7338         host_ns_set = 1;
7339       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7340                          host_mac_addr))
7341         host_mac_addr_set = 1;
7342       else if (unformat (i, "host-bridge %s", &host_bridge))
7343         host_bridge_set = 1;
7344       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7345                          &host_ip4_addr, &host_ip4_prefix_len))
7346         host_ip4_prefix_set = 1;
7347       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7348                          &host_ip6_addr, &host_ip6_prefix_len))
7349         host_ip6_prefix_set = 1;
7350       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7351                          &host_ip4_gw))
7352         host_ip4_gw_set = 1;
7353       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7354                          &host_ip6_gw))
7355         host_ip6_gw_set = 1;
7356       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7357         ;
7358       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7359         ;
7360       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7361         host_mtu_set = 1;
7362       else if (unformat (i, "no-gso"))
7363         tap_flags &= ~TAP_API_FLAG_GSO;
7364       else if (unformat (i, "gso"))
7365         tap_flags |= TAP_API_FLAG_GSO;
7366       else if (unformat (i, "csum-offload"))
7367         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7368       else if (unformat (i, "persist"))
7369         tap_flags |= TAP_API_FLAG_PERSIST;
7370       else if (unformat (i, "attach"))
7371         tap_flags |= TAP_API_FLAG_ATTACH;
7372       else if (unformat (i, "tun"))
7373         tap_flags |= TAP_API_FLAG_TUN;
7374       else if (unformat (i, "gro-coalesce"))
7375         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7376       else
7377         break;
7378     }
7379
7380   if (vec_len (host_if_name) > 63)
7381     {
7382       errmsg ("tap name too long. ");
7383       return -99;
7384     }
7385   if (vec_len (host_ns) > 63)
7386     {
7387       errmsg ("host name space too long. ");
7388       return -99;
7389     }
7390   if (vec_len (host_bridge) > 63)
7391     {
7392       errmsg ("host bridge name too long. ");
7393       return -99;
7394     }
7395   if (host_ip4_prefix_len > 32)
7396     {
7397       errmsg ("host ip4 prefix length not valid. ");
7398       return -99;
7399     }
7400   if (host_ip6_prefix_len > 128)
7401     {
7402       errmsg ("host ip6 prefix length not valid. ");
7403       return -99;
7404     }
7405   if (!is_pow2 (rx_ring_sz))
7406     {
7407       errmsg ("rx ring size must be power of 2. ");
7408       return -99;
7409     }
7410   if (rx_ring_sz > 32768)
7411     {
7412       errmsg ("rx ring size must be 32768 or lower. ");
7413       return -99;
7414     }
7415   if (!is_pow2 (tx_ring_sz))
7416     {
7417       errmsg ("tx ring size must be power of 2. ");
7418       return -99;
7419     }
7420   if (tx_ring_sz > 32768)
7421     {
7422       errmsg ("tx ring size must be 32768 or lower. ");
7423       return -99;
7424     }
7425   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7426     {
7427       errmsg ("host MTU size must be in between 64 and 65355. ");
7428       return -99;
7429     }
7430
7431   /* Construct the API message */
7432   M (TAP_CREATE_V2, mp);
7433
7434   mp->id = ntohl (id);
7435   mp->use_random_mac = random_mac;
7436   mp->num_rx_queues = (u8) num_rx_queues;
7437   mp->tx_ring_sz = ntohs (tx_ring_sz);
7438   mp->rx_ring_sz = ntohs (rx_ring_sz);
7439   mp->host_mtu_set = host_mtu_set;
7440   mp->host_mtu_size = ntohl (host_mtu_size);
7441   mp->host_mac_addr_set = host_mac_addr_set;
7442   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7443   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7444   mp->host_ip4_gw_set = host_ip4_gw_set;
7445   mp->host_ip6_gw_set = host_ip6_gw_set;
7446   mp->tap_flags = ntohl (tap_flags);
7447   mp->host_namespace_set = host_ns_set;
7448   mp->host_if_name_set = host_if_name_set;
7449   mp->host_bridge_set = host_bridge_set;
7450
7451   if (random_mac == 0)
7452     clib_memcpy (mp->mac_address, mac_address, 6);
7453   if (host_mac_addr_set)
7454     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7455   if (host_if_name_set)
7456     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7457   if (host_ns_set)
7458     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7459   if (host_bridge_set)
7460     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7461   if (host_ip4_prefix_set)
7462     {
7463       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7464       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7465     }
7466   if (host_ip6_prefix_set)
7467     {
7468       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7469       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7470     }
7471   if (host_ip4_gw_set)
7472     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7473   if (host_ip6_gw_set)
7474     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7475
7476   vec_free (host_ns);
7477   vec_free (host_if_name);
7478   vec_free (host_bridge);
7479
7480   /* send it... */
7481   S (mp);
7482
7483   /* Wait for a reply... */
7484   W (ret);
7485   return ret;
7486 }
7487
7488 static int
7489 api_tap_delete_v2 (vat_main_t * vam)
7490 {
7491   unformat_input_t *i = vam->input;
7492   vl_api_tap_delete_v2_t *mp;
7493   u32 sw_if_index = ~0;
7494   u8 sw_if_index_set = 0;
7495   int ret;
7496
7497   /* Parse args required to build the message */
7498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7499     {
7500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7501         sw_if_index_set = 1;
7502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7503         sw_if_index_set = 1;
7504       else
7505         break;
7506     }
7507
7508   if (sw_if_index_set == 0)
7509     {
7510       errmsg ("missing vpp interface name. ");
7511       return -99;
7512     }
7513
7514   /* Construct the API message */
7515   M (TAP_DELETE_V2, mp);
7516
7517   mp->sw_if_index = ntohl (sw_if_index);
7518
7519   /* send it... */
7520   S (mp);
7521
7522   /* Wait for a reply... */
7523   W (ret);
7524   return ret;
7525 }
7526
7527 uword
7528 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7529 {
7530   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7531   u32 x[4];
7532
7533   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7534     return 0;
7535
7536   addr->domain = x[0];
7537   addr->bus = x[1];
7538   addr->slot = x[2];
7539   addr->function = x[3];
7540
7541   return 1;
7542 }
7543
7544 static int
7545 api_virtio_pci_create (vat_main_t * vam)
7546 {
7547   unformat_input_t *i = vam->input;
7548   vl_api_virtio_pci_create_t *mp;
7549   u8 mac_address[6];
7550   u8 random_mac = 1;
7551   u8 gso_enabled = 0;
7552   u8 checksum_offload_enabled = 0;
7553   u32 pci_addr = 0;
7554   u64 features = (u64) ~ (0ULL);
7555   int ret;
7556
7557   clib_memset (mac_address, 0, sizeof (mac_address));
7558
7559   /* Parse args required to build the message */
7560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7561     {
7562       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7563         {
7564           random_mac = 0;
7565         }
7566       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7567         ;
7568       else if (unformat (i, "features 0x%llx", &features))
7569         ;
7570       else if (unformat (i, "gso-enabled"))
7571         gso_enabled = 1;
7572       else if (unformat (i, "csum-offload-enabled"))
7573         checksum_offload_enabled = 1;
7574       else
7575         break;
7576     }
7577
7578   if (pci_addr == 0)
7579     {
7580       errmsg ("pci address must be non zero. ");
7581       return -99;
7582     }
7583
7584   /* Construct the API message */
7585   M (VIRTIO_PCI_CREATE, mp);
7586
7587   mp->use_random_mac = random_mac;
7588
7589   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7590   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7591   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7592   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7593
7594   mp->features = clib_host_to_net_u64 (features);
7595   mp->gso_enabled = gso_enabled;
7596   mp->checksum_offload_enabled = checksum_offload_enabled;
7597
7598   if (random_mac == 0)
7599     clib_memcpy (mp->mac_address, mac_address, 6);
7600
7601   /* send it... */
7602   S (mp);
7603
7604   /* Wait for a reply... */
7605   W (ret);
7606   return ret;
7607 }
7608
7609 static int
7610 api_virtio_pci_delete (vat_main_t * vam)
7611 {
7612   unformat_input_t *i = vam->input;
7613   vl_api_virtio_pci_delete_t *mp;
7614   u32 sw_if_index = ~0;
7615   u8 sw_if_index_set = 0;
7616   int ret;
7617
7618   /* Parse args required to build the message */
7619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7620     {
7621       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7622         sw_if_index_set = 1;
7623       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7624         sw_if_index_set = 1;
7625       else
7626         break;
7627     }
7628
7629   if (sw_if_index_set == 0)
7630     {
7631       errmsg ("missing vpp interface name. ");
7632       return -99;
7633     }
7634
7635   /* Construct the API message */
7636   M (VIRTIO_PCI_DELETE, mp);
7637
7638   mp->sw_if_index = htonl (sw_if_index);
7639
7640   /* send it... */
7641   S (mp);
7642
7643   /* Wait for a reply... */
7644   W (ret);
7645   return ret;
7646 }
7647
7648 static int
7649 api_bond_create (vat_main_t * vam)
7650 {
7651   unformat_input_t *i = vam->input;
7652   vl_api_bond_create_t *mp;
7653   u8 mac_address[6];
7654   u8 custom_mac = 0;
7655   int ret;
7656   u8 mode;
7657   u8 lb;
7658   u8 mode_is_set = 0;
7659   u32 id = ~0;
7660   u8 numa_only = 0;
7661
7662   clib_memset (mac_address, 0, sizeof (mac_address));
7663   lb = BOND_LB_L2;
7664
7665   /* Parse args required to build the message */
7666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7667     {
7668       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7669         mode_is_set = 1;
7670       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7671                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7672         ;
7673       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7674                          mac_address))
7675         custom_mac = 1;
7676       else if (unformat (i, "numa-only"))
7677         numa_only = 1;
7678       else if (unformat (i, "id %u", &id))
7679         ;
7680       else
7681         break;
7682     }
7683
7684   if (mode_is_set == 0)
7685     {
7686       errmsg ("Missing bond mode. ");
7687       return -99;
7688     }
7689
7690   /* Construct the API message */
7691   M (BOND_CREATE, mp);
7692
7693   mp->use_custom_mac = custom_mac;
7694
7695   mp->mode = htonl (mode);
7696   mp->lb = htonl (lb);
7697   mp->id = htonl (id);
7698   mp->numa_only = numa_only;
7699
7700   if (custom_mac)
7701     clib_memcpy (mp->mac_address, mac_address, 6);
7702
7703   /* send it... */
7704   S (mp);
7705
7706   /* Wait for a reply... */
7707   W (ret);
7708   return ret;
7709 }
7710
7711 static int
7712 api_bond_delete (vat_main_t * vam)
7713 {
7714   unformat_input_t *i = vam->input;
7715   vl_api_bond_delete_t *mp;
7716   u32 sw_if_index = ~0;
7717   u8 sw_if_index_set = 0;
7718   int ret;
7719
7720   /* Parse args required to build the message */
7721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7722     {
7723       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7724         sw_if_index_set = 1;
7725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7726         sw_if_index_set = 1;
7727       else
7728         break;
7729     }
7730
7731   if (sw_if_index_set == 0)
7732     {
7733       errmsg ("missing vpp interface name. ");
7734       return -99;
7735     }
7736
7737   /* Construct the API message */
7738   M (BOND_DELETE, mp);
7739
7740   mp->sw_if_index = ntohl (sw_if_index);
7741
7742   /* send it... */
7743   S (mp);
7744
7745   /* Wait for a reply... */
7746   W (ret);
7747   return ret;
7748 }
7749
7750 static int
7751 api_bond_enslave (vat_main_t * vam)
7752 {
7753   unformat_input_t *i = vam->input;
7754   vl_api_bond_enslave_t *mp;
7755   u32 bond_sw_if_index;
7756   int ret;
7757   u8 is_passive;
7758   u8 is_long_timeout;
7759   u32 bond_sw_if_index_is_set = 0;
7760   u32 sw_if_index;
7761   u8 sw_if_index_is_set = 0;
7762
7763   /* Parse args required to build the message */
7764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7765     {
7766       if (unformat (i, "sw_if_index %d", &sw_if_index))
7767         sw_if_index_is_set = 1;
7768       else if (unformat (i, "bond %u", &bond_sw_if_index))
7769         bond_sw_if_index_is_set = 1;
7770       else if (unformat (i, "passive %d", &is_passive))
7771         ;
7772       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7773         ;
7774       else
7775         break;
7776     }
7777
7778   if (bond_sw_if_index_is_set == 0)
7779     {
7780       errmsg ("Missing bond sw_if_index. ");
7781       return -99;
7782     }
7783   if (sw_if_index_is_set == 0)
7784     {
7785       errmsg ("Missing slave sw_if_index. ");
7786       return -99;
7787     }
7788
7789   /* Construct the API message */
7790   M (BOND_ENSLAVE, mp);
7791
7792   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7793   mp->sw_if_index = ntohl (sw_if_index);
7794   mp->is_long_timeout = is_long_timeout;
7795   mp->is_passive = is_passive;
7796
7797   /* send it... */
7798   S (mp);
7799
7800   /* Wait for a reply... */
7801   W (ret);
7802   return ret;
7803 }
7804
7805 static int
7806 api_bond_detach_slave (vat_main_t * vam)
7807 {
7808   unformat_input_t *i = vam->input;
7809   vl_api_bond_detach_slave_t *mp;
7810   u32 sw_if_index = ~0;
7811   u8 sw_if_index_set = 0;
7812   int ret;
7813
7814   /* Parse args required to build the message */
7815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7816     {
7817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7818         sw_if_index_set = 1;
7819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7820         sw_if_index_set = 1;
7821       else
7822         break;
7823     }
7824
7825   if (sw_if_index_set == 0)
7826     {
7827       errmsg ("missing vpp interface name. ");
7828       return -99;
7829     }
7830
7831   /* Construct the API message */
7832   M (BOND_DETACH_SLAVE, mp);
7833
7834   mp->sw_if_index = ntohl (sw_if_index);
7835
7836   /* send it... */
7837   S (mp);
7838
7839   /* Wait for a reply... */
7840   W (ret);
7841   return ret;
7842 }
7843
7844 static int
7845 api_ip_table_add_del (vat_main_t * vam)
7846 {
7847   unformat_input_t *i = vam->input;
7848   vl_api_ip_table_add_del_t *mp;
7849   u32 table_id = ~0;
7850   u8 is_ipv6 = 0;
7851   u8 is_add = 1;
7852   int ret = 0;
7853
7854   /* Parse args required to build the message */
7855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7856     {
7857       if (unformat (i, "ipv6"))
7858         is_ipv6 = 1;
7859       else if (unformat (i, "del"))
7860         is_add = 0;
7861       else if (unformat (i, "add"))
7862         is_add = 1;
7863       else if (unformat (i, "table %d", &table_id))
7864         ;
7865       else
7866         {
7867           clib_warning ("parse error '%U'", format_unformat_error, i);
7868           return -99;
7869         }
7870     }
7871
7872   if (~0 == table_id)
7873     {
7874       errmsg ("missing table-ID");
7875       return -99;
7876     }
7877
7878   /* Construct the API message */
7879   M (IP_TABLE_ADD_DEL, mp);
7880
7881   mp->table.table_id = ntohl (table_id);
7882   mp->table.is_ip6 = is_ipv6;
7883   mp->is_add = is_add;
7884
7885   /* send it... */
7886   S (mp);
7887
7888   /* Wait for a reply... */
7889   W (ret);
7890
7891   return ret;
7892 }
7893
7894 uword
7895 unformat_fib_path (unformat_input_t * input, va_list * args)
7896 {
7897   vat_main_t *vam = va_arg (*args, vat_main_t *);
7898   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7899   u32 weight, preference;
7900   mpls_label_t out_label;
7901
7902   clib_memset (path, 0, sizeof (*path));
7903   path->weight = 1;
7904   path->sw_if_index = ~0;
7905   path->rpf_id = ~0;
7906   path->n_labels = 0;
7907
7908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7909     {
7910       if (unformat (input, "%U %U",
7911                     unformat_vl_api_ip4_address,
7912                     &path->nh.address.ip4,
7913                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7914         {
7915           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7916         }
7917       else if (unformat (input, "%U %U",
7918                          unformat_vl_api_ip6_address,
7919                          &path->nh.address.ip6,
7920                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7921         {
7922           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7923         }
7924       else if (unformat (input, "weight %u", &weight))
7925         {
7926           path->weight = weight;
7927         }
7928       else if (unformat (input, "preference %u", &preference))
7929         {
7930           path->preference = preference;
7931         }
7932       else if (unformat (input, "%U next-hop-table %d",
7933                          unformat_vl_api_ip4_address,
7934                          &path->nh.address.ip4, &path->table_id))
7935         {
7936           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7937         }
7938       else if (unformat (input, "%U next-hop-table %d",
7939                          unformat_vl_api_ip6_address,
7940                          &path->nh.address.ip6, &path->table_id))
7941         {
7942           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7943         }
7944       else if (unformat (input, "%U",
7945                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7946         {
7947           /*
7948            * the recursive next-hops are by default in the default table
7949            */
7950           path->table_id = 0;
7951           path->sw_if_index = ~0;
7952           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7953         }
7954       else if (unformat (input, "%U",
7955                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7956         {
7957           /*
7958            * the recursive next-hops are by default in the default table
7959            */
7960           path->table_id = 0;
7961           path->sw_if_index = ~0;
7962           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7963         }
7964       else if (unformat (input, "resolve-via-host"))
7965         {
7966           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7967         }
7968       else if (unformat (input, "resolve-via-attached"))
7969         {
7970           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7971         }
7972       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7973         {
7974           path->type = FIB_API_PATH_TYPE_LOCAL;
7975           path->sw_if_index = ~0;
7976           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7977         }
7978       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7979         {
7980           path->type = FIB_API_PATH_TYPE_LOCAL;
7981           path->sw_if_index = ~0;
7982           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7983         }
7984       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7985         ;
7986       else if (unformat (input, "via-label %d", &path->nh.via_label))
7987         {
7988           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7989           path->sw_if_index = ~0;
7990         }
7991       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7992         {
7993           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7994           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7995         }
7996       else if (unformat (input, "local"))
7997         {
7998           path->type = FIB_API_PATH_TYPE_LOCAL;
7999         }
8000       else if (unformat (input, "out-labels"))
8001         {
8002           while (unformat (input, "%d", &out_label))
8003             {
8004               path->label_stack[path->n_labels].label = out_label;
8005               path->label_stack[path->n_labels].is_uniform = 0;
8006               path->label_stack[path->n_labels].ttl = 64;
8007               path->n_labels++;
8008             }
8009         }
8010       else if (unformat (input, "via"))
8011         {
8012           /* new path, back up and return */
8013           unformat_put_input (input);
8014           unformat_put_input (input);
8015           unformat_put_input (input);
8016           unformat_put_input (input);
8017           break;
8018         }
8019       else
8020         {
8021           return (0);
8022         }
8023     }
8024
8025   path->proto = ntohl (path->proto);
8026   path->type = ntohl (path->type);
8027   path->flags = ntohl (path->flags);
8028   path->table_id = ntohl (path->table_id);
8029   path->sw_if_index = ntohl (path->sw_if_index);
8030
8031   return (1);
8032 }
8033
8034 static int
8035 api_ip_route_add_del (vat_main_t * vam)
8036 {
8037   unformat_input_t *i = vam->input;
8038   vl_api_ip_route_add_del_t *mp;
8039   u32 vrf_id = 0;
8040   u8 is_add = 1;
8041   u8 is_multipath = 0;
8042   u8 prefix_set = 0;
8043   u8 path_count = 0;
8044   vl_api_prefix_t pfx = { };
8045   vl_api_fib_path_t paths[8];
8046   int count = 1;
8047   int j;
8048   f64 before = 0;
8049   u32 random_add_del = 0;
8050   u32 *random_vector = 0;
8051   u32 random_seed = 0xdeaddabe;
8052
8053   /* Parse args required to build the message */
8054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8055     {
8056       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8057         prefix_set = 1;
8058       else if (unformat (i, "del"))
8059         is_add = 0;
8060       else if (unformat (i, "add"))
8061         is_add = 1;
8062       else if (unformat (i, "vrf %d", &vrf_id))
8063         ;
8064       else if (unformat (i, "count %d", &count))
8065         ;
8066       else if (unformat (i, "random"))
8067         random_add_del = 1;
8068       else if (unformat (i, "multipath"))
8069         is_multipath = 1;
8070       else if (unformat (i, "seed %d", &random_seed))
8071         ;
8072       else
8073         if (unformat
8074             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8075         {
8076           path_count++;
8077           if (8 == path_count)
8078             {
8079               errmsg ("max 8 paths");
8080               return -99;
8081             }
8082         }
8083       else
8084         {
8085           clib_warning ("parse error '%U'", format_unformat_error, i);
8086           return -99;
8087         }
8088     }
8089
8090   if (!path_count)
8091     {
8092       errmsg ("specify a path; via ...");
8093       return -99;
8094     }
8095   if (prefix_set == 0)
8096     {
8097       errmsg ("missing prefix");
8098       return -99;
8099     }
8100
8101   /* Generate a pile of unique, random routes */
8102   if (random_add_del)
8103     {
8104       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8105       u32 this_random_address;
8106       uword *random_hash;
8107
8108       random_hash = hash_create (count, sizeof (uword));
8109
8110       hash_set (random_hash, i->as_u32, 1);
8111       for (j = 0; j <= count; j++)
8112         {
8113           do
8114             {
8115               this_random_address = random_u32 (&random_seed);
8116               this_random_address =
8117                 clib_host_to_net_u32 (this_random_address);
8118             }
8119           while (hash_get (random_hash, this_random_address));
8120           vec_add1 (random_vector, this_random_address);
8121           hash_set (random_hash, this_random_address, 1);
8122         }
8123       hash_free (random_hash);
8124       set_ip4_address (&pfx.address, random_vector[0]);
8125     }
8126
8127   if (count > 1)
8128     {
8129       /* Turn on async mode */
8130       vam->async_mode = 1;
8131       vam->async_errors = 0;
8132       before = vat_time_now (vam);
8133     }
8134
8135   for (j = 0; j < count; j++)
8136     {
8137       /* Construct the API message */
8138       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8139
8140       mp->is_add = is_add;
8141       mp->is_multipath = is_multipath;
8142
8143       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8144       mp->route.table_id = ntohl (vrf_id);
8145       mp->route.n_paths = path_count;
8146
8147       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8148
8149       if (random_add_del)
8150         set_ip4_address (&pfx.address, random_vector[j + 1]);
8151       else
8152         increment_address (&pfx.address);
8153       /* send it... */
8154       S (mp);
8155       /* If we receive SIGTERM, stop now... */
8156       if (vam->do_exit)
8157         break;
8158     }
8159
8160   /* When testing multiple add/del ops, use a control-ping to sync */
8161   if (count > 1)
8162     {
8163       vl_api_control_ping_t *mp_ping;
8164       f64 after;
8165       f64 timeout;
8166
8167       /* Shut off async mode */
8168       vam->async_mode = 0;
8169
8170       MPING (CONTROL_PING, mp_ping);
8171       S (mp_ping);
8172
8173       timeout = vat_time_now (vam) + 1.0;
8174       while (vat_time_now (vam) < timeout)
8175         if (vam->result_ready == 1)
8176           goto out;
8177       vam->retval = -99;
8178
8179     out:
8180       if (vam->retval == -99)
8181         errmsg ("timeout");
8182
8183       if (vam->async_errors > 0)
8184         {
8185           errmsg ("%d asynchronous errors", vam->async_errors);
8186           vam->retval = -98;
8187         }
8188       vam->async_errors = 0;
8189       after = vat_time_now (vam);
8190
8191       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8192       if (j > 0)
8193         count = j;
8194
8195       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8196              count, after - before, count / (after - before));
8197     }
8198   else
8199     {
8200       int ret;
8201
8202       /* Wait for a reply... */
8203       W (ret);
8204       return ret;
8205     }
8206
8207   /* Return the good/bad news */
8208   return (vam->retval);
8209 }
8210
8211 static int
8212 api_ip_mroute_add_del (vat_main_t * vam)
8213 {
8214   unformat_input_t *i = vam->input;
8215   u8 path_set = 0, prefix_set = 0, is_add = 1;
8216   vl_api_ip_mroute_add_del_t *mp;
8217   mfib_entry_flags_t eflags = 0;
8218   vl_api_mfib_path_t path;
8219   vl_api_mprefix_t pfx = { };
8220   u32 vrf_id = 0;
8221   int ret;
8222
8223   /* Parse args required to build the message */
8224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8225     {
8226       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8227         {
8228           prefix_set = 1;
8229           pfx.grp_address_length = htons (pfx.grp_address_length);
8230         }
8231       else if (unformat (i, "del"))
8232         is_add = 0;
8233       else if (unformat (i, "add"))
8234         is_add = 1;
8235       else if (unformat (i, "vrf %d", &vrf_id))
8236         ;
8237       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8238         path.itf_flags = htonl (path.itf_flags);
8239       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8240         ;
8241       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8242         path_set = 1;
8243       else
8244         {
8245           clib_warning ("parse error '%U'", format_unformat_error, i);
8246           return -99;
8247         }
8248     }
8249
8250   if (prefix_set == 0)
8251     {
8252       errmsg ("missing addresses\n");
8253       return -99;
8254     }
8255   if (path_set == 0)
8256     {
8257       errmsg ("missing path\n");
8258       return -99;
8259     }
8260
8261   /* Construct the API message */
8262   M (IP_MROUTE_ADD_DEL, mp);
8263
8264   mp->is_add = is_add;
8265   mp->is_multipath = 1;
8266
8267   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8268   mp->route.table_id = htonl (vrf_id);
8269   mp->route.n_paths = 1;
8270   mp->route.entry_flags = htonl (eflags);
8271
8272   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8273
8274   /* send it... */
8275   S (mp);
8276   /* Wait for a reply... */
8277   W (ret);
8278   return ret;
8279 }
8280
8281 static int
8282 api_mpls_table_add_del (vat_main_t * vam)
8283 {
8284   unformat_input_t *i = vam->input;
8285   vl_api_mpls_table_add_del_t *mp;
8286   u32 table_id = ~0;
8287   u8 is_add = 1;
8288   int ret = 0;
8289
8290   /* Parse args required to build the message */
8291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8292     {
8293       if (unformat (i, "table %d", &table_id))
8294         ;
8295       else if (unformat (i, "del"))
8296         is_add = 0;
8297       else if (unformat (i, "add"))
8298         is_add = 1;
8299       else
8300         {
8301           clib_warning ("parse error '%U'", format_unformat_error, i);
8302           return -99;
8303         }
8304     }
8305
8306   if (~0 == table_id)
8307     {
8308       errmsg ("missing table-ID");
8309       return -99;
8310     }
8311
8312   /* Construct the API message */
8313   M (MPLS_TABLE_ADD_DEL, mp);
8314
8315   mp->mt_table.mt_table_id = ntohl (table_id);
8316   mp->mt_is_add = is_add;
8317
8318   /* send it... */
8319   S (mp);
8320
8321   /* Wait for a reply... */
8322   W (ret);
8323
8324   return ret;
8325 }
8326
8327 static int
8328 api_mpls_route_add_del (vat_main_t * vam)
8329 {
8330   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8331   mpls_label_t local_label = MPLS_LABEL_INVALID;
8332   unformat_input_t *i = vam->input;
8333   vl_api_mpls_route_add_del_t *mp;
8334   vl_api_fib_path_t paths[8];
8335   int count = 1, j;
8336   f64 before = 0;
8337
8338   /* Parse args required to build the message */
8339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8340     {
8341       if (unformat (i, "%d", &local_label))
8342         ;
8343       else if (unformat (i, "eos"))
8344         is_eos = 1;
8345       else if (unformat (i, "non-eos"))
8346         is_eos = 0;
8347       else if (unformat (i, "del"))
8348         is_add = 0;
8349       else if (unformat (i, "add"))
8350         is_add = 1;
8351       else if (unformat (i, "multipath"))
8352         is_multipath = 1;
8353       else if (unformat (i, "count %d", &count))
8354         ;
8355       else
8356         if (unformat
8357             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8358         {
8359           path_count++;
8360           if (8 == path_count)
8361             {
8362               errmsg ("max 8 paths");
8363               return -99;
8364             }
8365         }
8366       else
8367         {
8368           clib_warning ("parse error '%U'", format_unformat_error, i);
8369           return -99;
8370         }
8371     }
8372
8373   if (!path_count)
8374     {
8375       errmsg ("specify a path; via ...");
8376       return -99;
8377     }
8378
8379   if (MPLS_LABEL_INVALID == local_label)
8380     {
8381       errmsg ("missing label");
8382       return -99;
8383     }
8384
8385   if (count > 1)
8386     {
8387       /* Turn on async mode */
8388       vam->async_mode = 1;
8389       vam->async_errors = 0;
8390       before = vat_time_now (vam);
8391     }
8392
8393   for (j = 0; j < count; j++)
8394     {
8395       /* Construct the API message */
8396       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8397
8398       mp->mr_is_add = is_add;
8399       mp->mr_is_multipath = is_multipath;
8400
8401       mp->mr_route.mr_label = local_label;
8402       mp->mr_route.mr_eos = is_eos;
8403       mp->mr_route.mr_table_id = 0;
8404       mp->mr_route.mr_n_paths = path_count;
8405
8406       clib_memcpy (&mp->mr_route.mr_paths, paths,
8407                    sizeof (paths[0]) * path_count);
8408
8409       local_label++;
8410
8411       /* send it... */
8412       S (mp);
8413       /* If we receive SIGTERM, stop now... */
8414       if (vam->do_exit)
8415         break;
8416     }
8417
8418   /* When testing multiple add/del ops, use a control-ping to sync */
8419   if (count > 1)
8420     {
8421       vl_api_control_ping_t *mp_ping;
8422       f64 after;
8423       f64 timeout;
8424
8425       /* Shut off async mode */
8426       vam->async_mode = 0;
8427
8428       MPING (CONTROL_PING, mp_ping);
8429       S (mp_ping);
8430
8431       timeout = vat_time_now (vam) + 1.0;
8432       while (vat_time_now (vam) < timeout)
8433         if (vam->result_ready == 1)
8434           goto out;
8435       vam->retval = -99;
8436
8437     out:
8438       if (vam->retval == -99)
8439         errmsg ("timeout");
8440
8441       if (vam->async_errors > 0)
8442         {
8443           errmsg ("%d asynchronous errors", vam->async_errors);
8444           vam->retval = -98;
8445         }
8446       vam->async_errors = 0;
8447       after = vat_time_now (vam);
8448
8449       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8450       if (j > 0)
8451         count = j;
8452
8453       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8454              count, after - before, count / (after - before));
8455     }
8456   else
8457     {
8458       int ret;
8459
8460       /* Wait for a reply... */
8461       W (ret);
8462       return ret;
8463     }
8464
8465   /* Return the good/bad news */
8466   return (vam->retval);
8467   return (0);
8468 }
8469
8470 static int
8471 api_mpls_ip_bind_unbind (vat_main_t * vam)
8472 {
8473   unformat_input_t *i = vam->input;
8474   vl_api_mpls_ip_bind_unbind_t *mp;
8475   u32 ip_table_id = 0;
8476   u8 is_bind = 1;
8477   vl_api_prefix_t pfx;
8478   u8 prefix_set = 0;
8479   mpls_label_t local_label = MPLS_LABEL_INVALID;
8480   int ret;
8481
8482   /* Parse args required to build the message */
8483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8484     {
8485       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8486         prefix_set = 1;
8487       else if (unformat (i, "%d", &local_label))
8488         ;
8489       else if (unformat (i, "table-id %d", &ip_table_id))
8490         ;
8491       else if (unformat (i, "unbind"))
8492         is_bind = 0;
8493       else if (unformat (i, "bind"))
8494         is_bind = 1;
8495       else
8496         {
8497           clib_warning ("parse error '%U'", format_unformat_error, i);
8498           return -99;
8499         }
8500     }
8501
8502   if (!prefix_set)
8503     {
8504       errmsg ("IP prefix not set");
8505       return -99;
8506     }
8507
8508   if (MPLS_LABEL_INVALID == local_label)
8509     {
8510       errmsg ("missing label");
8511       return -99;
8512     }
8513
8514   /* Construct the API message */
8515   M (MPLS_IP_BIND_UNBIND, mp);
8516
8517   mp->mb_is_bind = is_bind;
8518   mp->mb_ip_table_id = ntohl (ip_table_id);
8519   mp->mb_mpls_table_id = 0;
8520   mp->mb_label = ntohl (local_label);
8521   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8522
8523   /* send it... */
8524   S (mp);
8525
8526   /* Wait for a reply... */
8527   W (ret);
8528   return ret;
8529   return (0);
8530 }
8531
8532 static int
8533 api_sr_mpls_policy_add (vat_main_t * vam)
8534 {
8535   unformat_input_t *i = vam->input;
8536   vl_api_sr_mpls_policy_add_t *mp;
8537   u32 bsid = 0;
8538   u32 weight = 1;
8539   u8 type = 0;
8540   u8 n_segments = 0;
8541   u32 sid;
8542   u32 *segments = NULL;
8543   int ret;
8544
8545   /* Parse args required to build the message */
8546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8547     {
8548       if (unformat (i, "bsid %d", &bsid))
8549         ;
8550       else if (unformat (i, "weight %d", &weight))
8551         ;
8552       else if (unformat (i, "spray"))
8553         type = 1;
8554       else if (unformat (i, "next %d", &sid))
8555         {
8556           n_segments += 1;
8557           vec_add1 (segments, htonl (sid));
8558         }
8559       else
8560         {
8561           clib_warning ("parse error '%U'", format_unformat_error, i);
8562           return -99;
8563         }
8564     }
8565
8566   if (bsid == 0)
8567     {
8568       errmsg ("bsid not set");
8569       return -99;
8570     }
8571
8572   if (n_segments == 0)
8573     {
8574       errmsg ("no sid in segment stack");
8575       return -99;
8576     }
8577
8578   /* Construct the API message */
8579   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8580
8581   mp->bsid = htonl (bsid);
8582   mp->weight = htonl (weight);
8583   mp->is_spray = type;
8584   mp->n_segments = n_segments;
8585   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8586   vec_free (segments);
8587
8588   /* send it... */
8589   S (mp);
8590
8591   /* Wait for a reply... */
8592   W (ret);
8593   return ret;
8594 }
8595
8596 static int
8597 api_sr_mpls_policy_del (vat_main_t * vam)
8598 {
8599   unformat_input_t *i = vam->input;
8600   vl_api_sr_mpls_policy_del_t *mp;
8601   u32 bsid = 0;
8602   int ret;
8603
8604   /* Parse args required to build the message */
8605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8606     {
8607       if (unformat (i, "bsid %d", &bsid))
8608         ;
8609       else
8610         {
8611           clib_warning ("parse error '%U'", format_unformat_error, i);
8612           return -99;
8613         }
8614     }
8615
8616   if (bsid == 0)
8617     {
8618       errmsg ("bsid not set");
8619       return -99;
8620     }
8621
8622   /* Construct the API message */
8623   M (SR_MPLS_POLICY_DEL, mp);
8624
8625   mp->bsid = htonl (bsid);
8626
8627   /* send it... */
8628   S (mp);
8629
8630   /* Wait for a reply... */
8631   W (ret);
8632   return ret;
8633 }
8634
8635 static int
8636 api_bier_table_add_del (vat_main_t * vam)
8637 {
8638   unformat_input_t *i = vam->input;
8639   vl_api_bier_table_add_del_t *mp;
8640   u8 is_add = 1;
8641   u32 set = 0, sub_domain = 0, hdr_len = 3;
8642   mpls_label_t local_label = MPLS_LABEL_INVALID;
8643   int ret;
8644
8645   /* Parse args required to build the message */
8646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8647     {
8648       if (unformat (i, "sub-domain %d", &sub_domain))
8649         ;
8650       else if (unformat (i, "set %d", &set))
8651         ;
8652       else if (unformat (i, "label %d", &local_label))
8653         ;
8654       else if (unformat (i, "hdr-len %d", &hdr_len))
8655         ;
8656       else if (unformat (i, "add"))
8657         is_add = 1;
8658       else if (unformat (i, "del"))
8659         is_add = 0;
8660       else
8661         {
8662           clib_warning ("parse error '%U'", format_unformat_error, i);
8663           return -99;
8664         }
8665     }
8666
8667   if (MPLS_LABEL_INVALID == local_label)
8668     {
8669       errmsg ("missing label\n");
8670       return -99;
8671     }
8672
8673   /* Construct the API message */
8674   M (BIER_TABLE_ADD_DEL, mp);
8675
8676   mp->bt_is_add = is_add;
8677   mp->bt_label = ntohl (local_label);
8678   mp->bt_tbl_id.bt_set = set;
8679   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8680   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8681
8682   /* send it... */
8683   S (mp);
8684
8685   /* Wait for a reply... */
8686   W (ret);
8687
8688   return (ret);
8689 }
8690
8691 static int
8692 api_bier_route_add_del (vat_main_t * vam)
8693 {
8694   unformat_input_t *i = vam->input;
8695   vl_api_bier_route_add_del_t *mp;
8696   u8 is_add = 1;
8697   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8698   ip4_address_t v4_next_hop_address;
8699   ip6_address_t v6_next_hop_address;
8700   u8 next_hop_set = 0;
8701   u8 next_hop_proto_is_ip4 = 1;
8702   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8703   int ret;
8704
8705   /* Parse args required to build the message */
8706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8707     {
8708       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8709         {
8710           next_hop_proto_is_ip4 = 1;
8711           next_hop_set = 1;
8712         }
8713       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8714         {
8715           next_hop_proto_is_ip4 = 0;
8716           next_hop_set = 1;
8717         }
8718       if (unformat (i, "sub-domain %d", &sub_domain))
8719         ;
8720       else if (unformat (i, "set %d", &set))
8721         ;
8722       else if (unformat (i, "hdr-len %d", &hdr_len))
8723         ;
8724       else if (unformat (i, "bp %d", &bp))
8725         ;
8726       else if (unformat (i, "add"))
8727         is_add = 1;
8728       else if (unformat (i, "del"))
8729         is_add = 0;
8730       else if (unformat (i, "out-label %d", &next_hop_out_label))
8731         ;
8732       else
8733         {
8734           clib_warning ("parse error '%U'", format_unformat_error, i);
8735           return -99;
8736         }
8737     }
8738
8739   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8740     {
8741       errmsg ("next hop / label set\n");
8742       return -99;
8743     }
8744   if (0 == bp)
8745     {
8746       errmsg ("bit=position not set\n");
8747       return -99;
8748     }
8749
8750   /* Construct the API message */
8751   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8752
8753   mp->br_is_add = is_add;
8754   mp->br_route.br_tbl_id.bt_set = set;
8755   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8756   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8757   mp->br_route.br_bp = ntohs (bp);
8758   mp->br_route.br_n_paths = 1;
8759   mp->br_route.br_paths[0].n_labels = 1;
8760   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8761   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8762                                     FIB_API_PATH_NH_PROTO_IP4 :
8763                                     FIB_API_PATH_NH_PROTO_IP6);
8764
8765   if (next_hop_proto_is_ip4)
8766     {
8767       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8768                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8769     }
8770   else
8771     {
8772       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8773                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8774     }
8775
8776   /* send it... */
8777   S (mp);
8778
8779   /* Wait for a reply... */
8780   W (ret);
8781
8782   return (ret);
8783 }
8784
8785 static int
8786 api_mpls_tunnel_add_del (vat_main_t * vam)
8787 {
8788   unformat_input_t *i = vam->input;
8789   vl_api_mpls_tunnel_add_del_t *mp;
8790
8791   vl_api_fib_path_t paths[8];
8792   u32 sw_if_index = ~0;
8793   u8 path_count = 0;
8794   u8 l2_only = 0;
8795   u8 is_add = 1;
8796   int ret;
8797
8798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8799     {
8800       if (unformat (i, "add"))
8801         is_add = 1;
8802       else
8803         if (unformat
8804             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8805         is_add = 0;
8806       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8807         is_add = 0;
8808       else if (unformat (i, "l2-only"))
8809         l2_only = 1;
8810       else
8811         if (unformat
8812             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8813         {
8814           path_count++;
8815           if (8 == path_count)
8816             {
8817               errmsg ("max 8 paths");
8818               return -99;
8819             }
8820         }
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8829
8830   mp->mt_is_add = is_add;
8831   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8832   mp->mt_tunnel.mt_l2_only = l2_only;
8833   mp->mt_tunnel.mt_is_multicast = 0;
8834   mp->mt_tunnel.mt_n_paths = path_count;
8835
8836   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8837                sizeof (paths[0]) * path_count);
8838
8839   S (mp);
8840   W (ret);
8841   return ret;
8842 }
8843
8844 static int
8845 api_sw_interface_set_unnumbered (vat_main_t * vam)
8846 {
8847   unformat_input_t *i = vam->input;
8848   vl_api_sw_interface_set_unnumbered_t *mp;
8849   u32 sw_if_index;
8850   u32 unnum_sw_index = ~0;
8851   u8 is_add = 1;
8852   u8 sw_if_index_set = 0;
8853   int ret;
8854
8855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8856     {
8857       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8858         sw_if_index_set = 1;
8859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8860         sw_if_index_set = 1;
8861       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8862         ;
8863       else if (unformat (i, "del"))
8864         is_add = 0;
8865       else
8866         {
8867           clib_warning ("parse error '%U'", format_unformat_error, i);
8868           return -99;
8869         }
8870     }
8871
8872   if (sw_if_index_set == 0)
8873     {
8874       errmsg ("missing interface name or sw_if_index");
8875       return -99;
8876     }
8877
8878   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8879
8880   mp->sw_if_index = ntohl (sw_if_index);
8881   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8882   mp->is_add = is_add;
8883
8884   S (mp);
8885   W (ret);
8886   return ret;
8887 }
8888
8889
8890 static int
8891 api_create_vlan_subif (vat_main_t * vam)
8892 {
8893   unformat_input_t *i = vam->input;
8894   vl_api_create_vlan_subif_t *mp;
8895   u32 sw_if_index;
8896   u8 sw_if_index_set = 0;
8897   u32 vlan_id;
8898   u8 vlan_id_set = 0;
8899   int ret;
8900
8901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8902     {
8903       if (unformat (i, "sw_if_index %d", &sw_if_index))
8904         sw_if_index_set = 1;
8905       else
8906         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8907         sw_if_index_set = 1;
8908       else if (unformat (i, "vlan %d", &vlan_id))
8909         vlan_id_set = 1;
8910       else
8911         {
8912           clib_warning ("parse error '%U'", format_unformat_error, i);
8913           return -99;
8914         }
8915     }
8916
8917   if (sw_if_index_set == 0)
8918     {
8919       errmsg ("missing interface name or sw_if_index");
8920       return -99;
8921     }
8922
8923   if (vlan_id_set == 0)
8924     {
8925       errmsg ("missing vlan_id");
8926       return -99;
8927     }
8928   M (CREATE_VLAN_SUBIF, mp);
8929
8930   mp->sw_if_index = ntohl (sw_if_index);
8931   mp->vlan_id = ntohl (vlan_id);
8932
8933   S (mp);
8934   W (ret);
8935   return ret;
8936 }
8937
8938 #define foreach_create_subif_bit                \
8939 _(no_tags)                                      \
8940 _(one_tag)                                      \
8941 _(two_tags)                                     \
8942 _(dot1ad)                                       \
8943 _(exact_match)                                  \
8944 _(default_sub)                                  \
8945 _(outer_vlan_id_any)                            \
8946 _(inner_vlan_id_any)
8947
8948 #define foreach_create_subif_flag               \
8949 _(0, "no_tags")                                 \
8950 _(1, "one_tag")                                 \
8951 _(2, "two_tags")                                \
8952 _(3, "dot1ad")                                  \
8953 _(4, "exact_match")                             \
8954 _(5, "default_sub")                             \
8955 _(6, "outer_vlan_id_any")                       \
8956 _(7, "inner_vlan_id_any")
8957
8958 static int
8959 api_create_subif (vat_main_t * vam)
8960 {
8961   unformat_input_t *i = vam->input;
8962   vl_api_create_subif_t *mp;
8963   u32 sw_if_index;
8964   u8 sw_if_index_set = 0;
8965   u32 sub_id;
8966   u8 sub_id_set = 0;
8967   u32 __attribute__ ((unused)) no_tags = 0;
8968   u32 __attribute__ ((unused)) one_tag = 0;
8969   u32 __attribute__ ((unused)) two_tags = 0;
8970   u32 __attribute__ ((unused)) dot1ad = 0;
8971   u32 __attribute__ ((unused)) exact_match = 0;
8972   u32 __attribute__ ((unused)) default_sub = 0;
8973   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8974   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8975   u32 tmp;
8976   u16 outer_vlan_id = 0;
8977   u16 inner_vlan_id = 0;
8978   int ret;
8979
8980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8981     {
8982       if (unformat (i, "sw_if_index %d", &sw_if_index))
8983         sw_if_index_set = 1;
8984       else
8985         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8986         sw_if_index_set = 1;
8987       else if (unformat (i, "sub_id %d", &sub_id))
8988         sub_id_set = 1;
8989       else if (unformat (i, "outer_vlan_id %d", &tmp))
8990         outer_vlan_id = tmp;
8991       else if (unformat (i, "inner_vlan_id %d", &tmp))
8992         inner_vlan_id = tmp;
8993
8994 #define _(a) else if (unformat (i, #a)) a = 1 ;
8995       foreach_create_subif_bit
8996 #undef _
8997         else
8998         {
8999           clib_warning ("parse error '%U'", format_unformat_error, i);
9000           return -99;
9001         }
9002     }
9003
9004   if (sw_if_index_set == 0)
9005     {
9006       errmsg ("missing interface name or sw_if_index");
9007       return -99;
9008     }
9009
9010   if (sub_id_set == 0)
9011     {
9012       errmsg ("missing sub_id");
9013       return -99;
9014     }
9015   M (CREATE_SUBIF, mp);
9016
9017   mp->sw_if_index = ntohl (sw_if_index);
9018   mp->sub_id = ntohl (sub_id);
9019
9020 #define _(a,b) mp->sub_if_flags |= (1 << a);
9021   foreach_create_subif_flag;
9022 #undef _
9023
9024   mp->outer_vlan_id = ntohs (outer_vlan_id);
9025   mp->inner_vlan_id = ntohs (inner_vlan_id);
9026
9027   S (mp);
9028   W (ret);
9029   return ret;
9030 }
9031
9032 static int
9033 api_ip_table_replace_begin (vat_main_t * vam)
9034 {
9035   unformat_input_t *i = vam->input;
9036   vl_api_ip_table_replace_begin_t *mp;
9037   u32 table_id = 0;
9038   u8 is_ipv6 = 0;
9039
9040   int ret;
9041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9042     {
9043       if (unformat (i, "table %d", &table_id))
9044         ;
9045       else if (unformat (i, "ipv6"))
9046         is_ipv6 = 1;
9047       else
9048         {
9049           clib_warning ("parse error '%U'", format_unformat_error, i);
9050           return -99;
9051         }
9052     }
9053
9054   M (IP_TABLE_REPLACE_BEGIN, mp);
9055
9056   mp->table.table_id = ntohl (table_id);
9057   mp->table.is_ip6 = is_ipv6;
9058
9059   S (mp);
9060   W (ret);
9061   return ret;
9062 }
9063
9064 static int
9065 api_ip_table_flush (vat_main_t * vam)
9066 {
9067   unformat_input_t *i = vam->input;
9068   vl_api_ip_table_flush_t *mp;
9069   u32 table_id = 0;
9070   u8 is_ipv6 = 0;
9071
9072   int ret;
9073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9074     {
9075       if (unformat (i, "table %d", &table_id))
9076         ;
9077       else if (unformat (i, "ipv6"))
9078         is_ipv6 = 1;
9079       else
9080         {
9081           clib_warning ("parse error '%U'", format_unformat_error, i);
9082           return -99;
9083         }
9084     }
9085
9086   M (IP_TABLE_FLUSH, mp);
9087
9088   mp->table.table_id = ntohl (table_id);
9089   mp->table.is_ip6 = is_ipv6;
9090
9091   S (mp);
9092   W (ret);
9093   return ret;
9094 }
9095
9096 static int
9097 api_ip_table_replace_end (vat_main_t * vam)
9098 {
9099   unformat_input_t *i = vam->input;
9100   vl_api_ip_table_replace_end_t *mp;
9101   u32 table_id = 0;
9102   u8 is_ipv6 = 0;
9103
9104   int ret;
9105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9106     {
9107       if (unformat (i, "table %d", &table_id))
9108         ;
9109       else if (unformat (i, "ipv6"))
9110         is_ipv6 = 1;
9111       else
9112         {
9113           clib_warning ("parse error '%U'", format_unformat_error, i);
9114           return -99;
9115         }
9116     }
9117
9118   M (IP_TABLE_REPLACE_END, mp);
9119
9120   mp->table.table_id = ntohl (table_id);
9121   mp->table.is_ip6 = is_ipv6;
9122
9123   S (mp);
9124   W (ret);
9125   return ret;
9126 }
9127
9128 static int
9129 api_set_ip_flow_hash (vat_main_t * vam)
9130 {
9131   unformat_input_t *i = vam->input;
9132   vl_api_set_ip_flow_hash_t *mp;
9133   u32 vrf_id = 0;
9134   u8 is_ipv6 = 0;
9135   u8 vrf_id_set = 0;
9136   u8 src = 0;
9137   u8 dst = 0;
9138   u8 sport = 0;
9139   u8 dport = 0;
9140   u8 proto = 0;
9141   u8 reverse = 0;
9142   int ret;
9143
9144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9145     {
9146       if (unformat (i, "vrf %d", &vrf_id))
9147         vrf_id_set = 1;
9148       else if (unformat (i, "ipv6"))
9149         is_ipv6 = 1;
9150       else if (unformat (i, "src"))
9151         src = 1;
9152       else if (unformat (i, "dst"))
9153         dst = 1;
9154       else if (unformat (i, "sport"))
9155         sport = 1;
9156       else if (unformat (i, "dport"))
9157         dport = 1;
9158       else if (unformat (i, "proto"))
9159         proto = 1;
9160       else if (unformat (i, "reverse"))
9161         reverse = 1;
9162
9163       else
9164         {
9165           clib_warning ("parse error '%U'", format_unformat_error, i);
9166           return -99;
9167         }
9168     }
9169
9170   if (vrf_id_set == 0)
9171     {
9172       errmsg ("missing vrf id");
9173       return -99;
9174     }
9175
9176   M (SET_IP_FLOW_HASH, mp);
9177   mp->src = src;
9178   mp->dst = dst;
9179   mp->sport = sport;
9180   mp->dport = dport;
9181   mp->proto = proto;
9182   mp->reverse = reverse;
9183   mp->vrf_id = ntohl (vrf_id);
9184   mp->is_ipv6 = is_ipv6;
9185
9186   S (mp);
9187   W (ret);
9188   return ret;
9189 }
9190
9191 static int
9192 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9193 {
9194   unformat_input_t *i = vam->input;
9195   vl_api_sw_interface_ip6_enable_disable_t *mp;
9196   u32 sw_if_index;
9197   u8 sw_if_index_set = 0;
9198   u8 enable = 0;
9199   int ret;
9200
9201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9202     {
9203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9204         sw_if_index_set = 1;
9205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9206         sw_if_index_set = 1;
9207       else if (unformat (i, "enable"))
9208         enable = 1;
9209       else if (unformat (i, "disable"))
9210         enable = 0;
9211       else
9212         {
9213           clib_warning ("parse error '%U'", format_unformat_error, i);
9214           return -99;
9215         }
9216     }
9217
9218   if (sw_if_index_set == 0)
9219     {
9220       errmsg ("missing interface name or sw_if_index");
9221       return -99;
9222     }
9223
9224   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9225
9226   mp->sw_if_index = ntohl (sw_if_index);
9227   mp->enable = enable;
9228
9229   S (mp);
9230   W (ret);
9231   return ret;
9232 }
9233
9234
9235 static int
9236 api_l2_patch_add_del (vat_main_t * vam)
9237 {
9238   unformat_input_t *i = vam->input;
9239   vl_api_l2_patch_add_del_t *mp;
9240   u32 rx_sw_if_index;
9241   u8 rx_sw_if_index_set = 0;
9242   u32 tx_sw_if_index;
9243   u8 tx_sw_if_index_set = 0;
9244   u8 is_add = 1;
9245   int ret;
9246
9247   /* Parse args required to build the message */
9248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9249     {
9250       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9251         rx_sw_if_index_set = 1;
9252       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9253         tx_sw_if_index_set = 1;
9254       else if (unformat (i, "rx"))
9255         {
9256           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9257             {
9258               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9259                             &rx_sw_if_index))
9260                 rx_sw_if_index_set = 1;
9261             }
9262           else
9263             break;
9264         }
9265       else if (unformat (i, "tx"))
9266         {
9267           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9268             {
9269               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9270                             &tx_sw_if_index))
9271                 tx_sw_if_index_set = 1;
9272             }
9273           else
9274             break;
9275         }
9276       else if (unformat (i, "del"))
9277         is_add = 0;
9278       else
9279         break;
9280     }
9281
9282   if (rx_sw_if_index_set == 0)
9283     {
9284       errmsg ("missing rx interface name or rx_sw_if_index");
9285       return -99;
9286     }
9287
9288   if (tx_sw_if_index_set == 0)
9289     {
9290       errmsg ("missing tx interface name or tx_sw_if_index");
9291       return -99;
9292     }
9293
9294   M (L2_PATCH_ADD_DEL, mp);
9295
9296   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9297   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9298   mp->is_add = is_add;
9299
9300   S (mp);
9301   W (ret);
9302   return ret;
9303 }
9304
9305 u8 is_del;
9306 u8 localsid_addr[16];
9307 u8 end_psp;
9308 u8 behavior;
9309 u32 sw_if_index;
9310 u32 vlan_index;
9311 u32 fib_table;
9312 u8 nh_addr[16];
9313
9314 static int
9315 api_sr_localsid_add_del (vat_main_t * vam)
9316 {
9317   unformat_input_t *i = vam->input;
9318   vl_api_sr_localsid_add_del_t *mp;
9319
9320   u8 is_del;
9321   ip6_address_t localsid;
9322   u8 end_psp = 0;
9323   u8 behavior = ~0;
9324   u32 sw_if_index;
9325   u32 fib_table = ~(u32) 0;
9326   ip46_address_t nh_addr;
9327   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9328
9329   bool nexthop_set = 0;
9330
9331   int ret;
9332
9333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9334     {
9335       if (unformat (i, "del"))
9336         is_del = 1;
9337       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9338       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9339         nexthop_set = 1;
9340       else if (unformat (i, "behavior %u", &behavior));
9341       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9342       else if (unformat (i, "fib-table %u", &fib_table));
9343       else if (unformat (i, "end.psp %u", &behavior));
9344       else
9345         break;
9346     }
9347
9348   M (SR_LOCALSID_ADD_DEL, mp);
9349
9350   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9351
9352   if (nexthop_set)
9353     {
9354       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9355     }
9356   mp->behavior = behavior;
9357   mp->sw_if_index = ntohl (sw_if_index);
9358   mp->fib_table = ntohl (fib_table);
9359   mp->end_psp = end_psp;
9360   mp->is_del = is_del;
9361
9362   S (mp);
9363   W (ret);
9364   return ret;
9365 }
9366
9367 static int
9368 api_ioam_enable (vat_main_t * vam)
9369 {
9370   unformat_input_t *input = vam->input;
9371   vl_api_ioam_enable_t *mp;
9372   u32 id = 0;
9373   int has_trace_option = 0;
9374   int has_pot_option = 0;
9375   int has_seqno_option = 0;
9376   int has_analyse_option = 0;
9377   int ret;
9378
9379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9380     {
9381       if (unformat (input, "trace"))
9382         has_trace_option = 1;
9383       else if (unformat (input, "pot"))
9384         has_pot_option = 1;
9385       else if (unformat (input, "seqno"))
9386         has_seqno_option = 1;
9387       else if (unformat (input, "analyse"))
9388         has_analyse_option = 1;
9389       else
9390         break;
9391     }
9392   M (IOAM_ENABLE, mp);
9393   mp->id = htons (id);
9394   mp->seqno = has_seqno_option;
9395   mp->analyse = has_analyse_option;
9396   mp->pot_enable = has_pot_option;
9397   mp->trace_enable = has_trace_option;
9398
9399   S (mp);
9400   W (ret);
9401   return ret;
9402 }
9403
9404
9405 static int
9406 api_ioam_disable (vat_main_t * vam)
9407 {
9408   vl_api_ioam_disable_t *mp;
9409   int ret;
9410
9411   M (IOAM_DISABLE, mp);
9412   S (mp);
9413   W (ret);
9414   return ret;
9415 }
9416
9417 #define foreach_tcp_proto_field                 \
9418 _(src_port)                                     \
9419 _(dst_port)
9420
9421 #define foreach_udp_proto_field                 \
9422 _(src_port)                                     \
9423 _(dst_port)
9424
9425 #define foreach_ip4_proto_field                 \
9426 _(src_address)                                  \
9427 _(dst_address)                                  \
9428 _(tos)                                          \
9429 _(length)                                       \
9430 _(fragment_id)                                  \
9431 _(ttl)                                          \
9432 _(protocol)                                     \
9433 _(checksum)
9434
9435 typedef struct
9436 {
9437   u16 src_port, dst_port;
9438 } tcpudp_header_t;
9439
9440 #if VPP_API_TEST_BUILTIN == 0
9441 uword
9442 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9443 {
9444   u8 **maskp = va_arg (*args, u8 **);
9445   u8 *mask = 0;
9446   u8 found_something = 0;
9447   tcp_header_t *tcp;
9448
9449 #define _(a) u8 a=0;
9450   foreach_tcp_proto_field;
9451 #undef _
9452
9453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9454     {
9455       if (0);
9456 #define _(a) else if (unformat (input, #a)) a=1;
9457       foreach_tcp_proto_field
9458 #undef _
9459         else
9460         break;
9461     }
9462
9463 #define _(a) found_something += a;
9464   foreach_tcp_proto_field;
9465 #undef _
9466
9467   if (found_something == 0)
9468     return 0;
9469
9470   vec_validate (mask, sizeof (*tcp) - 1);
9471
9472   tcp = (tcp_header_t *) mask;
9473
9474 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9475   foreach_tcp_proto_field;
9476 #undef _
9477
9478   *maskp = mask;
9479   return 1;
9480 }
9481
9482 uword
9483 unformat_udp_mask (unformat_input_t * input, va_list * args)
9484 {
9485   u8 **maskp = va_arg (*args, u8 **);
9486   u8 *mask = 0;
9487   u8 found_something = 0;
9488   udp_header_t *udp;
9489
9490 #define _(a) u8 a=0;
9491   foreach_udp_proto_field;
9492 #undef _
9493
9494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9495     {
9496       if (0);
9497 #define _(a) else if (unformat (input, #a)) a=1;
9498       foreach_udp_proto_field
9499 #undef _
9500         else
9501         break;
9502     }
9503
9504 #define _(a) found_something += a;
9505   foreach_udp_proto_field;
9506 #undef _
9507
9508   if (found_something == 0)
9509     return 0;
9510
9511   vec_validate (mask, sizeof (*udp) - 1);
9512
9513   udp = (udp_header_t *) mask;
9514
9515 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9516   foreach_udp_proto_field;
9517 #undef _
9518
9519   *maskp = mask;
9520   return 1;
9521 }
9522
9523 uword
9524 unformat_l4_mask (unformat_input_t * input, va_list * args)
9525 {
9526   u8 **maskp = va_arg (*args, u8 **);
9527   u16 src_port = 0, dst_port = 0;
9528   tcpudp_header_t *tcpudp;
9529
9530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9531     {
9532       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9533         return 1;
9534       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9535         return 1;
9536       else if (unformat (input, "src_port"))
9537         src_port = 0xFFFF;
9538       else if (unformat (input, "dst_port"))
9539         dst_port = 0xFFFF;
9540       else
9541         return 0;
9542     }
9543
9544   if (!src_port && !dst_port)
9545     return 0;
9546
9547   u8 *mask = 0;
9548   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9549
9550   tcpudp = (tcpudp_header_t *) mask;
9551   tcpudp->src_port = src_port;
9552   tcpudp->dst_port = dst_port;
9553
9554   *maskp = mask;
9555
9556   return 1;
9557 }
9558
9559 uword
9560 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9561 {
9562   u8 **maskp = va_arg (*args, u8 **);
9563   u8 *mask = 0;
9564   u8 found_something = 0;
9565   ip4_header_t *ip;
9566
9567 #define _(a) u8 a=0;
9568   foreach_ip4_proto_field;
9569 #undef _
9570   u8 version = 0;
9571   u8 hdr_length = 0;
9572
9573
9574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (input, "version"))
9577         version = 1;
9578       else if (unformat (input, "hdr_length"))
9579         hdr_length = 1;
9580       else if (unformat (input, "src"))
9581         src_address = 1;
9582       else if (unformat (input, "dst"))
9583         dst_address = 1;
9584       else if (unformat (input, "proto"))
9585         protocol = 1;
9586
9587 #define _(a) else if (unformat (input, #a)) a=1;
9588       foreach_ip4_proto_field
9589 #undef _
9590         else
9591         break;
9592     }
9593
9594 #define _(a) found_something += a;
9595   foreach_ip4_proto_field;
9596 #undef _
9597
9598   if (found_something == 0)
9599     return 0;
9600
9601   vec_validate (mask, sizeof (*ip) - 1);
9602
9603   ip = (ip4_header_t *) mask;
9604
9605 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9606   foreach_ip4_proto_field;
9607 #undef _
9608
9609   ip->ip_version_and_header_length = 0;
9610
9611   if (version)
9612     ip->ip_version_and_header_length |= 0xF0;
9613
9614   if (hdr_length)
9615     ip->ip_version_and_header_length |= 0x0F;
9616
9617   *maskp = mask;
9618   return 1;
9619 }
9620
9621 #define foreach_ip6_proto_field                 \
9622 _(src_address)                                  \
9623 _(dst_address)                                  \
9624 _(payload_length)                               \
9625 _(hop_limit)                                    \
9626 _(protocol)
9627
9628 uword
9629 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9630 {
9631   u8 **maskp = va_arg (*args, u8 **);
9632   u8 *mask = 0;
9633   u8 found_something = 0;
9634   ip6_header_t *ip;
9635   u32 ip_version_traffic_class_and_flow_label;
9636
9637 #define _(a) u8 a=0;
9638   foreach_ip6_proto_field;
9639 #undef _
9640   u8 version = 0;
9641   u8 traffic_class = 0;
9642   u8 flow_label = 0;
9643
9644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (input, "version"))
9647         version = 1;
9648       else if (unformat (input, "traffic-class"))
9649         traffic_class = 1;
9650       else if (unformat (input, "flow-label"))
9651         flow_label = 1;
9652       else if (unformat (input, "src"))
9653         src_address = 1;
9654       else if (unformat (input, "dst"))
9655         dst_address = 1;
9656       else if (unformat (input, "proto"))
9657         protocol = 1;
9658
9659 #define _(a) else if (unformat (input, #a)) a=1;
9660       foreach_ip6_proto_field
9661 #undef _
9662         else
9663         break;
9664     }
9665
9666 #define _(a) found_something += a;
9667   foreach_ip6_proto_field;
9668 #undef _
9669
9670   if (found_something == 0)
9671     return 0;
9672
9673   vec_validate (mask, sizeof (*ip) - 1);
9674
9675   ip = (ip6_header_t *) mask;
9676
9677 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9678   foreach_ip6_proto_field;
9679 #undef _
9680
9681   ip_version_traffic_class_and_flow_label = 0;
9682
9683   if (version)
9684     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9685
9686   if (traffic_class)
9687     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9688
9689   if (flow_label)
9690     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9691
9692   ip->ip_version_traffic_class_and_flow_label =
9693     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9694
9695   *maskp = mask;
9696   return 1;
9697 }
9698
9699 uword
9700 unformat_l3_mask (unformat_input_t * input, va_list * args)
9701 {
9702   u8 **maskp = va_arg (*args, u8 **);
9703
9704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9705     {
9706       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9707         return 1;
9708       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9709         return 1;
9710       else
9711         break;
9712     }
9713   return 0;
9714 }
9715
9716 uword
9717 unformat_l2_mask (unformat_input_t * input, va_list * args)
9718 {
9719   u8 **maskp = va_arg (*args, u8 **);
9720   u8 *mask = 0;
9721   u8 src = 0;
9722   u8 dst = 0;
9723   u8 proto = 0;
9724   u8 tag1 = 0;
9725   u8 tag2 = 0;
9726   u8 ignore_tag1 = 0;
9727   u8 ignore_tag2 = 0;
9728   u8 cos1 = 0;
9729   u8 cos2 = 0;
9730   u8 dot1q = 0;
9731   u8 dot1ad = 0;
9732   int len = 14;
9733
9734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9735     {
9736       if (unformat (input, "src"))
9737         src = 1;
9738       else if (unformat (input, "dst"))
9739         dst = 1;
9740       else if (unformat (input, "proto"))
9741         proto = 1;
9742       else if (unformat (input, "tag1"))
9743         tag1 = 1;
9744       else if (unformat (input, "tag2"))
9745         tag2 = 1;
9746       else if (unformat (input, "ignore-tag1"))
9747         ignore_tag1 = 1;
9748       else if (unformat (input, "ignore-tag2"))
9749         ignore_tag2 = 1;
9750       else if (unformat (input, "cos1"))
9751         cos1 = 1;
9752       else if (unformat (input, "cos2"))
9753         cos2 = 1;
9754       else if (unformat (input, "dot1q"))
9755         dot1q = 1;
9756       else if (unformat (input, "dot1ad"))
9757         dot1ad = 1;
9758       else
9759         break;
9760     }
9761   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9762        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9763     return 0;
9764
9765   if (tag1 || ignore_tag1 || cos1 || dot1q)
9766     len = 18;
9767   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9768     len = 22;
9769
9770   vec_validate (mask, len - 1);
9771
9772   if (dst)
9773     clib_memset (mask, 0xff, 6);
9774
9775   if (src)
9776     clib_memset (mask + 6, 0xff, 6);
9777
9778   if (tag2 || dot1ad)
9779     {
9780       /* inner vlan tag */
9781       if (tag2)
9782         {
9783           mask[19] = 0xff;
9784           mask[18] = 0x0f;
9785         }
9786       if (cos2)
9787         mask[18] |= 0xe0;
9788       if (proto)
9789         mask[21] = mask[20] = 0xff;
9790       if (tag1)
9791         {
9792           mask[15] = 0xff;
9793           mask[14] = 0x0f;
9794         }
9795       if (cos1)
9796         mask[14] |= 0xe0;
9797       *maskp = mask;
9798       return 1;
9799     }
9800   if (tag1 | dot1q)
9801     {
9802       if (tag1)
9803         {
9804           mask[15] = 0xff;
9805           mask[14] = 0x0f;
9806         }
9807       if (cos1)
9808         mask[14] |= 0xe0;
9809       if (proto)
9810         mask[16] = mask[17] = 0xff;
9811
9812       *maskp = mask;
9813       return 1;
9814     }
9815   if (cos2)
9816     mask[18] |= 0xe0;
9817   if (cos1)
9818     mask[14] |= 0xe0;
9819   if (proto)
9820     mask[12] = mask[13] = 0xff;
9821
9822   *maskp = mask;
9823   return 1;
9824 }
9825
9826 uword
9827 unformat_classify_mask (unformat_input_t * input, va_list * args)
9828 {
9829   u8 **maskp = va_arg (*args, u8 **);
9830   u32 *skipp = va_arg (*args, u32 *);
9831   u32 *matchp = va_arg (*args, u32 *);
9832   u32 match;
9833   u8 *mask = 0;
9834   u8 *l2 = 0;
9835   u8 *l3 = 0;
9836   u8 *l4 = 0;
9837   int i;
9838
9839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9840     {
9841       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9842         ;
9843       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9844         ;
9845       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9846         ;
9847       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9848         ;
9849       else
9850         break;
9851     }
9852
9853   if (l4 && !l3)
9854     {
9855       vec_free (mask);
9856       vec_free (l2);
9857       vec_free (l4);
9858       return 0;
9859     }
9860
9861   if (mask || l2 || l3 || l4)
9862     {
9863       if (l2 || l3 || l4)
9864         {
9865           /* "With a free Ethernet header in every package" */
9866           if (l2 == 0)
9867             vec_validate (l2, 13);
9868           mask = l2;
9869           if (vec_len (l3))
9870             {
9871               vec_append (mask, l3);
9872               vec_free (l3);
9873             }
9874           if (vec_len (l4))
9875             {
9876               vec_append (mask, l4);
9877               vec_free (l4);
9878             }
9879         }
9880
9881       /* Scan forward looking for the first significant mask octet */
9882       for (i = 0; i < vec_len (mask); i++)
9883         if (mask[i])
9884           break;
9885
9886       /* compute (skip, match) params */
9887       *skipp = i / sizeof (u32x4);
9888       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9889
9890       /* Pad mask to an even multiple of the vector size */
9891       while (vec_len (mask) % sizeof (u32x4))
9892         vec_add1 (mask, 0);
9893
9894       match = vec_len (mask) / sizeof (u32x4);
9895
9896       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9897         {
9898           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9899           if (*tmp || *(tmp + 1))
9900             break;
9901           match--;
9902         }
9903       if (match == 0)
9904         clib_warning ("BUG: match 0");
9905
9906       _vec_len (mask) = match * sizeof (u32x4);
9907
9908       *matchp = match;
9909       *maskp = mask;
9910
9911       return 1;
9912     }
9913
9914   return 0;
9915 }
9916 #endif /* VPP_API_TEST_BUILTIN */
9917
9918 #define foreach_l2_next                         \
9919 _(drop, DROP)                                   \
9920 _(ethernet, ETHERNET_INPUT)                     \
9921 _(ip4, IP4_INPUT)                               \
9922 _(ip6, IP6_INPUT)
9923
9924 uword
9925 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9926 {
9927   u32 *miss_next_indexp = va_arg (*args, u32 *);
9928   u32 next_index = 0;
9929   u32 tmp;
9930
9931 #define _(n,N) \
9932   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9933   foreach_l2_next;
9934 #undef _
9935
9936   if (unformat (input, "%d", &tmp))
9937     {
9938       next_index = tmp;
9939       goto out;
9940     }
9941
9942   return 0;
9943
9944 out:
9945   *miss_next_indexp = next_index;
9946   return 1;
9947 }
9948
9949 #define foreach_ip_next                         \
9950 _(drop, DROP)                                   \
9951 _(local, LOCAL)                                 \
9952 _(rewrite, REWRITE)
9953
9954 uword
9955 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9956 {
9957   u32 *miss_next_indexp = va_arg (*args, u32 *);
9958   u32 next_index = 0;
9959   u32 tmp;
9960
9961 #define _(n,N) \
9962   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9963   foreach_ip_next;
9964 #undef _
9965
9966   if (unformat (input, "%d", &tmp))
9967     {
9968       next_index = tmp;
9969       goto out;
9970     }
9971
9972   return 0;
9973
9974 out:
9975   *miss_next_indexp = next_index;
9976   return 1;
9977 }
9978
9979 #define foreach_acl_next                        \
9980 _(deny, DENY)
9981
9982 uword
9983 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9984 {
9985   u32 *miss_next_indexp = va_arg (*args, u32 *);
9986   u32 next_index = 0;
9987   u32 tmp;
9988
9989 #define _(n,N) \
9990   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9991   foreach_acl_next;
9992 #undef _
9993
9994   if (unformat (input, "permit"))
9995     {
9996       next_index = ~0;
9997       goto out;
9998     }
9999   else if (unformat (input, "%d", &tmp))
10000     {
10001       next_index = tmp;
10002       goto out;
10003     }
10004
10005   return 0;
10006
10007 out:
10008   *miss_next_indexp = next_index;
10009   return 1;
10010 }
10011
10012 uword
10013 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10014 {
10015   u32 *r = va_arg (*args, u32 *);
10016
10017   if (unformat (input, "conform-color"))
10018     *r = POLICE_CONFORM;
10019   else if (unformat (input, "exceed-color"))
10020     *r = POLICE_EXCEED;
10021   else
10022     return 0;
10023
10024   return 1;
10025 }
10026
10027 static int
10028 api_classify_add_del_table (vat_main_t * vam)
10029 {
10030   unformat_input_t *i = vam->input;
10031   vl_api_classify_add_del_table_t *mp;
10032
10033   u32 nbuckets = 2;
10034   u32 skip = ~0;
10035   u32 match = ~0;
10036   int is_add = 1;
10037   int del_chain = 0;
10038   u32 table_index = ~0;
10039   u32 next_table_index = ~0;
10040   u32 miss_next_index = ~0;
10041   u32 memory_size = 32 << 20;
10042   u8 *mask = 0;
10043   u32 current_data_flag = 0;
10044   int current_data_offset = 0;
10045   int ret;
10046
10047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10048     {
10049       if (unformat (i, "del"))
10050         is_add = 0;
10051       else if (unformat (i, "del-chain"))
10052         {
10053           is_add = 0;
10054           del_chain = 1;
10055         }
10056       else if (unformat (i, "buckets %d", &nbuckets))
10057         ;
10058       else if (unformat (i, "memory_size %d", &memory_size))
10059         ;
10060       else if (unformat (i, "skip %d", &skip))
10061         ;
10062       else if (unformat (i, "match %d", &match))
10063         ;
10064       else if (unformat (i, "table %d", &table_index))
10065         ;
10066       else if (unformat (i, "mask %U", unformat_classify_mask,
10067                          &mask, &skip, &match))
10068         ;
10069       else if (unformat (i, "next-table %d", &next_table_index))
10070         ;
10071       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10072                          &miss_next_index))
10073         ;
10074       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10075                          &miss_next_index))
10076         ;
10077       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10078                          &miss_next_index))
10079         ;
10080       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10081         ;
10082       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10083         ;
10084       else
10085         break;
10086     }
10087
10088   if (is_add && mask == 0)
10089     {
10090       errmsg ("Mask required");
10091       return -99;
10092     }
10093
10094   if (is_add && skip == ~0)
10095     {
10096       errmsg ("skip count required");
10097       return -99;
10098     }
10099
10100   if (is_add && match == ~0)
10101     {
10102       errmsg ("match count required");
10103       return -99;
10104     }
10105
10106   if (!is_add && table_index == ~0)
10107     {
10108       errmsg ("table index required for delete");
10109       return -99;
10110     }
10111
10112   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10113
10114   mp->is_add = is_add;
10115   mp->del_chain = del_chain;
10116   mp->table_index = ntohl (table_index);
10117   mp->nbuckets = ntohl (nbuckets);
10118   mp->memory_size = ntohl (memory_size);
10119   mp->skip_n_vectors = ntohl (skip);
10120   mp->match_n_vectors = ntohl (match);
10121   mp->next_table_index = ntohl (next_table_index);
10122   mp->miss_next_index = ntohl (miss_next_index);
10123   mp->current_data_flag = ntohl (current_data_flag);
10124   mp->current_data_offset = ntohl (current_data_offset);
10125   mp->mask_len = ntohl (vec_len (mask));
10126   clib_memcpy (mp->mask, mask, vec_len (mask));
10127
10128   vec_free (mask);
10129
10130   S (mp);
10131   W (ret);
10132   return ret;
10133 }
10134
10135 #if VPP_API_TEST_BUILTIN == 0
10136 uword
10137 unformat_l4_match (unformat_input_t * input, va_list * args)
10138 {
10139   u8 **matchp = va_arg (*args, u8 **);
10140
10141   u8 *proto_header = 0;
10142   int src_port = 0;
10143   int dst_port = 0;
10144
10145   tcpudp_header_t h;
10146
10147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (input, "src_port %d", &src_port))
10150         ;
10151       else if (unformat (input, "dst_port %d", &dst_port))
10152         ;
10153       else
10154         return 0;
10155     }
10156
10157   h.src_port = clib_host_to_net_u16 (src_port);
10158   h.dst_port = clib_host_to_net_u16 (dst_port);
10159   vec_validate (proto_header, sizeof (h) - 1);
10160   memcpy (proto_header, &h, sizeof (h));
10161
10162   *matchp = proto_header;
10163
10164   return 1;
10165 }
10166
10167 uword
10168 unformat_ip4_match (unformat_input_t * input, va_list * args)
10169 {
10170   u8 **matchp = va_arg (*args, u8 **);
10171   u8 *match = 0;
10172   ip4_header_t *ip;
10173   int version = 0;
10174   u32 version_val;
10175   int hdr_length = 0;
10176   u32 hdr_length_val;
10177   int src = 0, dst = 0;
10178   ip4_address_t src_val, dst_val;
10179   int proto = 0;
10180   u32 proto_val;
10181   int tos = 0;
10182   u32 tos_val;
10183   int length = 0;
10184   u32 length_val;
10185   int fragment_id = 0;
10186   u32 fragment_id_val;
10187   int ttl = 0;
10188   int ttl_val;
10189   int checksum = 0;
10190   u32 checksum_val;
10191
10192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10193     {
10194       if (unformat (input, "version %d", &version_val))
10195         version = 1;
10196       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10197         hdr_length = 1;
10198       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10199         src = 1;
10200       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10201         dst = 1;
10202       else if (unformat (input, "proto %d", &proto_val))
10203         proto = 1;
10204       else if (unformat (input, "tos %d", &tos_val))
10205         tos = 1;
10206       else if (unformat (input, "length %d", &length_val))
10207         length = 1;
10208       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10209         fragment_id = 1;
10210       else if (unformat (input, "ttl %d", &ttl_val))
10211         ttl = 1;
10212       else if (unformat (input, "checksum %d", &checksum_val))
10213         checksum = 1;
10214       else
10215         break;
10216     }
10217
10218   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10219       + ttl + checksum == 0)
10220     return 0;
10221
10222   /*
10223    * Aligned because we use the real comparison functions
10224    */
10225   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10226
10227   ip = (ip4_header_t *) match;
10228
10229   /* These are realistically matched in practice */
10230   if (src)
10231     ip->src_address.as_u32 = src_val.as_u32;
10232
10233   if (dst)
10234     ip->dst_address.as_u32 = dst_val.as_u32;
10235
10236   if (proto)
10237     ip->protocol = proto_val;
10238
10239
10240   /* These are not, but they're included for completeness */
10241   if (version)
10242     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10243
10244   if (hdr_length)
10245     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10246
10247   if (tos)
10248     ip->tos = tos_val;
10249
10250   if (length)
10251     ip->length = clib_host_to_net_u16 (length_val);
10252
10253   if (ttl)
10254     ip->ttl = ttl_val;
10255
10256   if (checksum)
10257     ip->checksum = clib_host_to_net_u16 (checksum_val);
10258
10259   *matchp = match;
10260   return 1;
10261 }
10262
10263 uword
10264 unformat_ip6_match (unformat_input_t * input, va_list * args)
10265 {
10266   u8 **matchp = va_arg (*args, u8 **);
10267   u8 *match = 0;
10268   ip6_header_t *ip;
10269   int version = 0;
10270   u32 version_val;
10271   u8 traffic_class = 0;
10272   u32 traffic_class_val = 0;
10273   u8 flow_label = 0;
10274   u8 flow_label_val;
10275   int src = 0, dst = 0;
10276   ip6_address_t src_val, dst_val;
10277   int proto = 0;
10278   u32 proto_val;
10279   int payload_length = 0;
10280   u32 payload_length_val;
10281   int hop_limit = 0;
10282   int hop_limit_val;
10283   u32 ip_version_traffic_class_and_flow_label;
10284
10285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10286     {
10287       if (unformat (input, "version %d", &version_val))
10288         version = 1;
10289       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10290         traffic_class = 1;
10291       else if (unformat (input, "flow_label %d", &flow_label_val))
10292         flow_label = 1;
10293       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10294         src = 1;
10295       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10296         dst = 1;
10297       else if (unformat (input, "proto %d", &proto_val))
10298         proto = 1;
10299       else if (unformat (input, "payload_length %d", &payload_length_val))
10300         payload_length = 1;
10301       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10302         hop_limit = 1;
10303       else
10304         break;
10305     }
10306
10307   if (version + traffic_class + flow_label + src + dst + proto +
10308       payload_length + hop_limit == 0)
10309     return 0;
10310
10311   /*
10312    * Aligned because we use the real comparison functions
10313    */
10314   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10315
10316   ip = (ip6_header_t *) match;
10317
10318   if (src)
10319     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10320
10321   if (dst)
10322     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10323
10324   if (proto)
10325     ip->protocol = proto_val;
10326
10327   ip_version_traffic_class_and_flow_label = 0;
10328
10329   if (version)
10330     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10331
10332   if (traffic_class)
10333     ip_version_traffic_class_and_flow_label |=
10334       (traffic_class_val & 0xFF) << 20;
10335
10336   if (flow_label)
10337     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10338
10339   ip->ip_version_traffic_class_and_flow_label =
10340     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10341
10342   if (payload_length)
10343     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10344
10345   if (hop_limit)
10346     ip->hop_limit = hop_limit_val;
10347
10348   *matchp = match;
10349   return 1;
10350 }
10351
10352 uword
10353 unformat_l3_match (unformat_input_t * input, va_list * args)
10354 {
10355   u8 **matchp = va_arg (*args, u8 **);
10356
10357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10358     {
10359       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10360         return 1;
10361       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10362         return 1;
10363       else
10364         break;
10365     }
10366   return 0;
10367 }
10368
10369 uword
10370 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10371 {
10372   u8 *tagp = va_arg (*args, u8 *);
10373   u32 tag;
10374
10375   if (unformat (input, "%d", &tag))
10376     {
10377       tagp[0] = (tag >> 8) & 0x0F;
10378       tagp[1] = tag & 0xFF;
10379       return 1;
10380     }
10381
10382   return 0;
10383 }
10384
10385 uword
10386 unformat_l2_match (unformat_input_t * input, va_list * args)
10387 {
10388   u8 **matchp = va_arg (*args, u8 **);
10389   u8 *match = 0;
10390   u8 src = 0;
10391   u8 src_val[6];
10392   u8 dst = 0;
10393   u8 dst_val[6];
10394   u8 proto = 0;
10395   u16 proto_val;
10396   u8 tag1 = 0;
10397   u8 tag1_val[2];
10398   u8 tag2 = 0;
10399   u8 tag2_val[2];
10400   int len = 14;
10401   u8 ignore_tag1 = 0;
10402   u8 ignore_tag2 = 0;
10403   u8 cos1 = 0;
10404   u8 cos2 = 0;
10405   u32 cos1_val = 0;
10406   u32 cos2_val = 0;
10407
10408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10409     {
10410       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10411         src = 1;
10412       else
10413         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10414         dst = 1;
10415       else if (unformat (input, "proto %U",
10416                          unformat_ethernet_type_host_byte_order, &proto_val))
10417         proto = 1;
10418       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10419         tag1 = 1;
10420       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10421         tag2 = 1;
10422       else if (unformat (input, "ignore-tag1"))
10423         ignore_tag1 = 1;
10424       else if (unformat (input, "ignore-tag2"))
10425         ignore_tag2 = 1;
10426       else if (unformat (input, "cos1 %d", &cos1_val))
10427         cos1 = 1;
10428       else if (unformat (input, "cos2 %d", &cos2_val))
10429         cos2 = 1;
10430       else
10431         break;
10432     }
10433   if ((src + dst + proto + tag1 + tag2 +
10434        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10435     return 0;
10436
10437   if (tag1 || ignore_tag1 || cos1)
10438     len = 18;
10439   if (tag2 || ignore_tag2 || cos2)
10440     len = 22;
10441
10442   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10443
10444   if (dst)
10445     clib_memcpy (match, dst_val, 6);
10446
10447   if (src)
10448     clib_memcpy (match + 6, src_val, 6);
10449
10450   if (tag2)
10451     {
10452       /* inner vlan tag */
10453       match[19] = tag2_val[1];
10454       match[18] = tag2_val[0];
10455       if (cos2)
10456         match[18] |= (cos2_val & 0x7) << 5;
10457       if (proto)
10458         {
10459           match[21] = proto_val & 0xff;
10460           match[20] = proto_val >> 8;
10461         }
10462       if (tag1)
10463         {
10464           match[15] = tag1_val[1];
10465           match[14] = tag1_val[0];
10466         }
10467       if (cos1)
10468         match[14] |= (cos1_val & 0x7) << 5;
10469       *matchp = match;
10470       return 1;
10471     }
10472   if (tag1)
10473     {
10474       match[15] = tag1_val[1];
10475       match[14] = tag1_val[0];
10476       if (proto)
10477         {
10478           match[17] = proto_val & 0xff;
10479           match[16] = proto_val >> 8;
10480         }
10481       if (cos1)
10482         match[14] |= (cos1_val & 0x7) << 5;
10483
10484       *matchp = match;
10485       return 1;
10486     }
10487   if (cos2)
10488     match[18] |= (cos2_val & 0x7) << 5;
10489   if (cos1)
10490     match[14] |= (cos1_val & 0x7) << 5;
10491   if (proto)
10492     {
10493       match[13] = proto_val & 0xff;
10494       match[12] = proto_val >> 8;
10495     }
10496
10497   *matchp = match;
10498   return 1;
10499 }
10500
10501 uword
10502 unformat_qos_source (unformat_input_t * input, va_list * args)
10503 {
10504   int *qs = va_arg (*args, int *);
10505
10506   if (unformat (input, "ip"))
10507     *qs = QOS_SOURCE_IP;
10508   else if (unformat (input, "mpls"))
10509     *qs = QOS_SOURCE_MPLS;
10510   else if (unformat (input, "ext"))
10511     *qs = QOS_SOURCE_EXT;
10512   else if (unformat (input, "vlan"))
10513     *qs = QOS_SOURCE_VLAN;
10514   else
10515     return 0;
10516
10517   return 1;
10518 }
10519 #endif
10520
10521 uword
10522 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10523 {
10524   u8 **matchp = va_arg (*args, u8 **);
10525   u32 skip_n_vectors = va_arg (*args, u32);
10526   u32 match_n_vectors = va_arg (*args, u32);
10527
10528   u8 *match = 0;
10529   u8 *l2 = 0;
10530   u8 *l3 = 0;
10531   u8 *l4 = 0;
10532
10533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10534     {
10535       if (unformat (input, "hex %U", unformat_hex_string, &match))
10536         ;
10537       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10538         ;
10539       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10540         ;
10541       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10542         ;
10543       else
10544         break;
10545     }
10546
10547   if (l4 && !l3)
10548     {
10549       vec_free (match);
10550       vec_free (l2);
10551       vec_free (l4);
10552       return 0;
10553     }
10554
10555   if (match || l2 || l3 || l4)
10556     {
10557       if (l2 || l3 || l4)
10558         {
10559           /* "Win a free Ethernet header in every packet" */
10560           if (l2 == 0)
10561             vec_validate_aligned (l2, 13, sizeof (u32x4));
10562           match = l2;
10563           if (vec_len (l3))
10564             {
10565               vec_append_aligned (match, l3, sizeof (u32x4));
10566               vec_free (l3);
10567             }
10568           if (vec_len (l4))
10569             {
10570               vec_append_aligned (match, l4, sizeof (u32x4));
10571               vec_free (l4);
10572             }
10573         }
10574
10575       /* Make sure the vector is big enough even if key is all 0's */
10576       vec_validate_aligned
10577         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10578          sizeof (u32x4));
10579
10580       /* Set size, include skipped vectors */
10581       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10582
10583       *matchp = match;
10584
10585       return 1;
10586     }
10587
10588   return 0;
10589 }
10590
10591 static int
10592 api_classify_add_del_session (vat_main_t * vam)
10593 {
10594   unformat_input_t *i = vam->input;
10595   vl_api_classify_add_del_session_t *mp;
10596   int is_add = 1;
10597   u32 table_index = ~0;
10598   u32 hit_next_index = ~0;
10599   u32 opaque_index = ~0;
10600   u8 *match = 0;
10601   i32 advance = 0;
10602   u32 skip_n_vectors = 0;
10603   u32 match_n_vectors = 0;
10604   u32 action = 0;
10605   u32 metadata = 0;
10606   int ret;
10607
10608   /*
10609    * Warning: you have to supply skip_n and match_n
10610    * because the API client cant simply look at the classify
10611    * table object.
10612    */
10613
10614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10615     {
10616       if (unformat (i, "del"))
10617         is_add = 0;
10618       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10619                          &hit_next_index))
10620         ;
10621       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10622                          &hit_next_index))
10623         ;
10624       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10625                          &hit_next_index))
10626         ;
10627       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10628         ;
10629       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10630         ;
10631       else if (unformat (i, "opaque-index %d", &opaque_index))
10632         ;
10633       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10634         ;
10635       else if (unformat (i, "match_n %d", &match_n_vectors))
10636         ;
10637       else if (unformat (i, "match %U", api_unformat_classify_match,
10638                          &match, skip_n_vectors, match_n_vectors))
10639         ;
10640       else if (unformat (i, "advance %d", &advance))
10641         ;
10642       else if (unformat (i, "table-index %d", &table_index))
10643         ;
10644       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10645         action = 1;
10646       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10647         action = 2;
10648       else if (unformat (i, "action %d", &action))
10649         ;
10650       else if (unformat (i, "metadata %d", &metadata))
10651         ;
10652       else
10653         break;
10654     }
10655
10656   if (table_index == ~0)
10657     {
10658       errmsg ("Table index required");
10659       return -99;
10660     }
10661
10662   if (is_add && match == 0)
10663     {
10664       errmsg ("Match value required");
10665       return -99;
10666     }
10667
10668   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10669
10670   mp->is_add = is_add;
10671   mp->table_index = ntohl (table_index);
10672   mp->hit_next_index = ntohl (hit_next_index);
10673   mp->opaque_index = ntohl (opaque_index);
10674   mp->advance = ntohl (advance);
10675   mp->action = action;
10676   mp->metadata = ntohl (metadata);
10677   mp->match_len = ntohl (vec_len (match));
10678   clib_memcpy (mp->match, match, vec_len (match));
10679   vec_free (match);
10680
10681   S (mp);
10682   W (ret);
10683   return ret;
10684 }
10685
10686 static int
10687 api_classify_set_interface_ip_table (vat_main_t * vam)
10688 {
10689   unformat_input_t *i = vam->input;
10690   vl_api_classify_set_interface_ip_table_t *mp;
10691   u32 sw_if_index;
10692   int sw_if_index_set;
10693   u32 table_index = ~0;
10694   u8 is_ipv6 = 0;
10695   int ret;
10696
10697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10700         sw_if_index_set = 1;
10701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10702         sw_if_index_set = 1;
10703       else if (unformat (i, "table %d", &table_index))
10704         ;
10705       else
10706         {
10707           clib_warning ("parse error '%U'", format_unformat_error, i);
10708           return -99;
10709         }
10710     }
10711
10712   if (sw_if_index_set == 0)
10713     {
10714       errmsg ("missing interface name or sw_if_index");
10715       return -99;
10716     }
10717
10718
10719   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10720
10721   mp->sw_if_index = ntohl (sw_if_index);
10722   mp->table_index = ntohl (table_index);
10723   mp->is_ipv6 = is_ipv6;
10724
10725   S (mp);
10726   W (ret);
10727   return ret;
10728 }
10729
10730 static int
10731 api_classify_set_interface_l2_tables (vat_main_t * vam)
10732 {
10733   unformat_input_t *i = vam->input;
10734   vl_api_classify_set_interface_l2_tables_t *mp;
10735   u32 sw_if_index;
10736   int sw_if_index_set;
10737   u32 ip4_table_index = ~0;
10738   u32 ip6_table_index = ~0;
10739   u32 other_table_index = ~0;
10740   u32 is_input = 1;
10741   int ret;
10742
10743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10744     {
10745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10746         sw_if_index_set = 1;
10747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10748         sw_if_index_set = 1;
10749       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10750         ;
10751       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10752         ;
10753       else if (unformat (i, "other-table %d", &other_table_index))
10754         ;
10755       else if (unformat (i, "is-input %d", &is_input))
10756         ;
10757       else
10758         {
10759           clib_warning ("parse error '%U'", format_unformat_error, i);
10760           return -99;
10761         }
10762     }
10763
10764   if (sw_if_index_set == 0)
10765     {
10766       errmsg ("missing interface name or sw_if_index");
10767       return -99;
10768     }
10769
10770
10771   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10772
10773   mp->sw_if_index = ntohl (sw_if_index);
10774   mp->ip4_table_index = ntohl (ip4_table_index);
10775   mp->ip6_table_index = ntohl (ip6_table_index);
10776   mp->other_table_index = ntohl (other_table_index);
10777   mp->is_input = (u8) is_input;
10778
10779   S (mp);
10780   W (ret);
10781   return ret;
10782 }
10783
10784 static int
10785 api_set_ipfix_exporter (vat_main_t * vam)
10786 {
10787   unformat_input_t *i = vam->input;
10788   vl_api_set_ipfix_exporter_t *mp;
10789   ip4_address_t collector_address;
10790   u8 collector_address_set = 0;
10791   u32 collector_port = ~0;
10792   ip4_address_t src_address;
10793   u8 src_address_set = 0;
10794   u32 vrf_id = ~0;
10795   u32 path_mtu = ~0;
10796   u32 template_interval = ~0;
10797   u8 udp_checksum = 0;
10798   int ret;
10799
10800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10801     {
10802       if (unformat (i, "collector_address %U", unformat_ip4_address,
10803                     &collector_address))
10804         collector_address_set = 1;
10805       else if (unformat (i, "collector_port %d", &collector_port))
10806         ;
10807       else if (unformat (i, "src_address %U", unformat_ip4_address,
10808                          &src_address))
10809         src_address_set = 1;
10810       else if (unformat (i, "vrf_id %d", &vrf_id))
10811         ;
10812       else if (unformat (i, "path_mtu %d", &path_mtu))
10813         ;
10814       else if (unformat (i, "template_interval %d", &template_interval))
10815         ;
10816       else if (unformat (i, "udp_checksum"))
10817         udp_checksum = 1;
10818       else
10819         break;
10820     }
10821
10822   if (collector_address_set == 0)
10823     {
10824       errmsg ("collector_address required");
10825       return -99;
10826     }
10827
10828   if (src_address_set == 0)
10829     {
10830       errmsg ("src_address required");
10831       return -99;
10832     }
10833
10834   M (SET_IPFIX_EXPORTER, mp);
10835
10836   memcpy (mp->collector_address.un.ip4, collector_address.data,
10837           sizeof (collector_address.data));
10838   mp->collector_port = htons ((u16) collector_port);
10839   memcpy (mp->src_address.un.ip4, src_address.data,
10840           sizeof (src_address.data));
10841   mp->vrf_id = htonl (vrf_id);
10842   mp->path_mtu = htonl (path_mtu);
10843   mp->template_interval = htonl (template_interval);
10844   mp->udp_checksum = udp_checksum;
10845
10846   S (mp);
10847   W (ret);
10848   return ret;
10849 }
10850
10851 static int
10852 api_set_ipfix_classify_stream (vat_main_t * vam)
10853 {
10854   unformat_input_t *i = vam->input;
10855   vl_api_set_ipfix_classify_stream_t *mp;
10856   u32 domain_id = 0;
10857   u32 src_port = UDP_DST_PORT_ipfix;
10858   int ret;
10859
10860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10861     {
10862       if (unformat (i, "domain %d", &domain_id))
10863         ;
10864       else if (unformat (i, "src_port %d", &src_port))
10865         ;
10866       else
10867         {
10868           errmsg ("unknown input `%U'", format_unformat_error, i);
10869           return -99;
10870         }
10871     }
10872
10873   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10874
10875   mp->domain_id = htonl (domain_id);
10876   mp->src_port = htons ((u16) src_port);
10877
10878   S (mp);
10879   W (ret);
10880   return ret;
10881 }
10882
10883 static int
10884 api_ipfix_classify_table_add_del (vat_main_t * vam)
10885 {
10886   unformat_input_t *i = vam->input;
10887   vl_api_ipfix_classify_table_add_del_t *mp;
10888   int is_add = -1;
10889   u32 classify_table_index = ~0;
10890   u8 ip_version = 0;
10891   u8 transport_protocol = 255;
10892   int ret;
10893
10894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10895     {
10896       if (unformat (i, "add"))
10897         is_add = 1;
10898       else if (unformat (i, "del"))
10899         is_add = 0;
10900       else if (unformat (i, "table %d", &classify_table_index))
10901         ;
10902       else if (unformat (i, "ip4"))
10903         ip_version = 4;
10904       else if (unformat (i, "ip6"))
10905         ip_version = 6;
10906       else if (unformat (i, "tcp"))
10907         transport_protocol = 6;
10908       else if (unformat (i, "udp"))
10909         transport_protocol = 17;
10910       else
10911         {
10912           errmsg ("unknown input `%U'", format_unformat_error, i);
10913           return -99;
10914         }
10915     }
10916
10917   if (is_add == -1)
10918     {
10919       errmsg ("expecting: add|del");
10920       return -99;
10921     }
10922   if (classify_table_index == ~0)
10923     {
10924       errmsg ("classifier table not specified");
10925       return -99;
10926     }
10927   if (ip_version == 0)
10928     {
10929       errmsg ("IP version not specified");
10930       return -99;
10931     }
10932
10933   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10934
10935   mp->is_add = is_add;
10936   mp->table_id = htonl (classify_table_index);
10937   mp->ip_version = ip_version;
10938   mp->transport_protocol = transport_protocol;
10939
10940   S (mp);
10941   W (ret);
10942   return ret;
10943 }
10944
10945 static int
10946 api_get_node_index (vat_main_t * vam)
10947 {
10948   unformat_input_t *i = vam->input;
10949   vl_api_get_node_index_t *mp;
10950   u8 *name = 0;
10951   int ret;
10952
10953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10954     {
10955       if (unformat (i, "node %s", &name))
10956         ;
10957       else
10958         break;
10959     }
10960   if (name == 0)
10961     {
10962       errmsg ("node name required");
10963       return -99;
10964     }
10965   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10966     {
10967       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10968       return -99;
10969     }
10970
10971   M (GET_NODE_INDEX, mp);
10972   clib_memcpy (mp->node_name, name, vec_len (name));
10973   vec_free (name);
10974
10975   S (mp);
10976   W (ret);
10977   return ret;
10978 }
10979
10980 static int
10981 api_get_next_index (vat_main_t * vam)
10982 {
10983   unformat_input_t *i = vam->input;
10984   vl_api_get_next_index_t *mp;
10985   u8 *node_name = 0, *next_node_name = 0;
10986   int ret;
10987
10988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10989     {
10990       if (unformat (i, "node-name %s", &node_name))
10991         ;
10992       else if (unformat (i, "next-node-name %s", &next_node_name))
10993         break;
10994     }
10995
10996   if (node_name == 0)
10997     {
10998       errmsg ("node name required");
10999       return -99;
11000     }
11001   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11002     {
11003       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11004       return -99;
11005     }
11006
11007   if (next_node_name == 0)
11008     {
11009       errmsg ("next node name required");
11010       return -99;
11011     }
11012   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11013     {
11014       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11015       return -99;
11016     }
11017
11018   M (GET_NEXT_INDEX, mp);
11019   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11020   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11021   vec_free (node_name);
11022   vec_free (next_node_name);
11023
11024   S (mp);
11025   W (ret);
11026   return ret;
11027 }
11028
11029 static int
11030 api_add_node_next (vat_main_t * vam)
11031 {
11032   unformat_input_t *i = vam->input;
11033   vl_api_add_node_next_t *mp;
11034   u8 *name = 0;
11035   u8 *next = 0;
11036   int ret;
11037
11038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11039     {
11040       if (unformat (i, "node %s", &name))
11041         ;
11042       else if (unformat (i, "next %s", &next))
11043         ;
11044       else
11045         break;
11046     }
11047   if (name == 0)
11048     {
11049       errmsg ("node name required");
11050       return -99;
11051     }
11052   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11053     {
11054       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11055       return -99;
11056     }
11057   if (next == 0)
11058     {
11059       errmsg ("next node required");
11060       return -99;
11061     }
11062   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11063     {
11064       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11065       return -99;
11066     }
11067
11068   M (ADD_NODE_NEXT, mp);
11069   clib_memcpy (mp->node_name, name, vec_len (name));
11070   clib_memcpy (mp->next_name, next, vec_len (next));
11071   vec_free (name);
11072   vec_free (next);
11073
11074   S (mp);
11075   W (ret);
11076   return ret;
11077 }
11078
11079 static int
11080 api_l2tpv3_create_tunnel (vat_main_t * vam)
11081 {
11082   unformat_input_t *i = vam->input;
11083   ip6_address_t client_address, our_address;
11084   int client_address_set = 0;
11085   int our_address_set = 0;
11086   u32 local_session_id = 0;
11087   u32 remote_session_id = 0;
11088   u64 local_cookie = 0;
11089   u64 remote_cookie = 0;
11090   u8 l2_sublayer_present = 0;
11091   vl_api_l2tpv3_create_tunnel_t *mp;
11092   int ret;
11093
11094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11095     {
11096       if (unformat (i, "client_address %U", unformat_ip6_address,
11097                     &client_address))
11098         client_address_set = 1;
11099       else if (unformat (i, "our_address %U", unformat_ip6_address,
11100                          &our_address))
11101         our_address_set = 1;
11102       else if (unformat (i, "local_session_id %d", &local_session_id))
11103         ;
11104       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11105         ;
11106       else if (unformat (i, "local_cookie %lld", &local_cookie))
11107         ;
11108       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11109         ;
11110       else if (unformat (i, "l2-sublayer-present"))
11111         l2_sublayer_present = 1;
11112       else
11113         break;
11114     }
11115
11116   if (client_address_set == 0)
11117     {
11118       errmsg ("client_address required");
11119       return -99;
11120     }
11121
11122   if (our_address_set == 0)
11123     {
11124       errmsg ("our_address required");
11125       return -99;
11126     }
11127
11128   M (L2TPV3_CREATE_TUNNEL, mp);
11129
11130   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11131                sizeof (ip6_address_t));
11132
11133   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11134                sizeof (ip6_address_t));
11135
11136   mp->local_session_id = ntohl (local_session_id);
11137   mp->remote_session_id = ntohl (remote_session_id);
11138   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11139   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11140   mp->l2_sublayer_present = l2_sublayer_present;
11141
11142   S (mp);
11143   W (ret);
11144   return ret;
11145 }
11146
11147 static int
11148 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11149 {
11150   unformat_input_t *i = vam->input;
11151   u32 sw_if_index;
11152   u8 sw_if_index_set = 0;
11153   u64 new_local_cookie = 0;
11154   u64 new_remote_cookie = 0;
11155   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11156   int ret;
11157
11158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11159     {
11160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11161         sw_if_index_set = 1;
11162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11163         sw_if_index_set = 1;
11164       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11165         ;
11166       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11167         ;
11168       else
11169         break;
11170     }
11171
11172   if (sw_if_index_set == 0)
11173     {
11174       errmsg ("missing interface name or sw_if_index");
11175       return -99;
11176     }
11177
11178   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11179
11180   mp->sw_if_index = ntohl (sw_if_index);
11181   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11182   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11183
11184   S (mp);
11185   W (ret);
11186   return ret;
11187 }
11188
11189 static int
11190 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11191 {
11192   unformat_input_t *i = vam->input;
11193   vl_api_l2tpv3_interface_enable_disable_t *mp;
11194   u32 sw_if_index;
11195   u8 sw_if_index_set = 0;
11196   u8 enable_disable = 1;
11197   int ret;
11198
11199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11200     {
11201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11202         sw_if_index_set = 1;
11203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11204         sw_if_index_set = 1;
11205       else if (unformat (i, "enable"))
11206         enable_disable = 1;
11207       else if (unformat (i, "disable"))
11208         enable_disable = 0;
11209       else
11210         break;
11211     }
11212
11213   if (sw_if_index_set == 0)
11214     {
11215       errmsg ("missing interface name or sw_if_index");
11216       return -99;
11217     }
11218
11219   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11220
11221   mp->sw_if_index = ntohl (sw_if_index);
11222   mp->enable_disable = enable_disable;
11223
11224   S (mp);
11225   W (ret);
11226   return ret;
11227 }
11228
11229 static int
11230 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11231 {
11232   unformat_input_t *i = vam->input;
11233   vl_api_l2tpv3_set_lookup_key_t *mp;
11234   u8 key = ~0;
11235   int ret;
11236
11237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (i, "lookup_v6_src"))
11240         key = L2T_LOOKUP_SRC_ADDRESS;
11241       else if (unformat (i, "lookup_v6_dst"))
11242         key = L2T_LOOKUP_DST_ADDRESS;
11243       else if (unformat (i, "lookup_session_id"))
11244         key = L2T_LOOKUP_SESSION_ID;
11245       else
11246         break;
11247     }
11248
11249   if (key == (u8) ~ 0)
11250     {
11251       errmsg ("l2tp session lookup key unset");
11252       return -99;
11253     }
11254
11255   M (L2TPV3_SET_LOOKUP_KEY, mp);
11256
11257   mp->key = key;
11258
11259   S (mp);
11260   W (ret);
11261   return ret;
11262 }
11263
11264 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11265   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11266 {
11267   vat_main_t *vam = &vat_main;
11268
11269   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11270          format_ip6_address, mp->our_address,
11271          format_ip6_address, mp->client_address,
11272          clib_net_to_host_u32 (mp->sw_if_index));
11273
11274   print (vam->ofp,
11275          "   local cookies %016llx %016llx remote cookie %016llx",
11276          clib_net_to_host_u64 (mp->local_cookie[0]),
11277          clib_net_to_host_u64 (mp->local_cookie[1]),
11278          clib_net_to_host_u64 (mp->remote_cookie));
11279
11280   print (vam->ofp, "   local session-id %d remote session-id %d",
11281          clib_net_to_host_u32 (mp->local_session_id),
11282          clib_net_to_host_u32 (mp->remote_session_id));
11283
11284   print (vam->ofp, "   l2 specific sublayer %s\n",
11285          mp->l2_sublayer_present ? "preset" : "absent");
11286
11287 }
11288
11289 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11290   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11291 {
11292   vat_main_t *vam = &vat_main;
11293   vat_json_node_t *node = NULL;
11294   struct in6_addr addr;
11295
11296   if (VAT_JSON_ARRAY != vam->json_tree.type)
11297     {
11298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11299       vat_json_init_array (&vam->json_tree);
11300     }
11301   node = vat_json_array_add (&vam->json_tree);
11302
11303   vat_json_init_object (node);
11304
11305   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11306   vat_json_object_add_ip6 (node, "our_address", addr);
11307   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11308   vat_json_object_add_ip6 (node, "client_address", addr);
11309
11310   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11311   vat_json_init_array (lc);
11312   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11313   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11314   vat_json_object_add_uint (node, "remote_cookie",
11315                             clib_net_to_host_u64 (mp->remote_cookie));
11316
11317   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11318   vat_json_object_add_uint (node, "local_session_id",
11319                             clib_net_to_host_u32 (mp->local_session_id));
11320   vat_json_object_add_uint (node, "remote_session_id",
11321                             clib_net_to_host_u32 (mp->remote_session_id));
11322   vat_json_object_add_string_copy (node, "l2_sublayer",
11323                                    mp->l2_sublayer_present ? (u8 *) "present"
11324                                    : (u8 *) "absent");
11325 }
11326
11327 static int
11328 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11329 {
11330   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11331   vl_api_control_ping_t *mp_ping;
11332   int ret;
11333
11334   /* Get list of l2tpv3-tunnel interfaces */
11335   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11336   S (mp);
11337
11338   /* Use a control ping for synchronization */
11339   MPING (CONTROL_PING, mp_ping);
11340   S (mp_ping);
11341
11342   W (ret);
11343   return ret;
11344 }
11345
11346
11347 static void vl_api_sw_interface_tap_v2_details_t_handler
11348   (vl_api_sw_interface_tap_v2_details_t * mp)
11349 {
11350   vat_main_t *vam = &vat_main;
11351
11352   u8 *ip4 =
11353     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11354             mp->host_ip4_prefix.len);
11355   u8 *ip6 =
11356     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11357             mp->host_ip6_prefix.len);
11358
11359   print (vam->ofp,
11360          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11361          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11362          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11363          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11364          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11365
11366   vec_free (ip4);
11367   vec_free (ip6);
11368 }
11369
11370 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11371   (vl_api_sw_interface_tap_v2_details_t * mp)
11372 {
11373   vat_main_t *vam = &vat_main;
11374   vat_json_node_t *node = NULL;
11375
11376   if (VAT_JSON_ARRAY != vam->json_tree.type)
11377     {
11378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11379       vat_json_init_array (&vam->json_tree);
11380     }
11381   node = vat_json_array_add (&vam->json_tree);
11382
11383   vat_json_init_object (node);
11384   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11385   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11386   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11387   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11388   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11389   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11390   vat_json_object_add_string_copy (node, "host_mac_addr",
11391                                    format (0, "%U", format_ethernet_address,
11392                                            &mp->host_mac_addr));
11393   vat_json_object_add_string_copy (node, "host_namespace",
11394                                    mp->host_namespace);
11395   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11396   vat_json_object_add_string_copy (node, "host_ip4_addr",
11397                                    format (0, "%U/%d", format_ip4_address,
11398                                            mp->host_ip4_prefix.address,
11399                                            mp->host_ip4_prefix.len));
11400   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11401                                    format (0, "%U/%d", format_ip6_address,
11402                                            mp->host_ip6_prefix.address,
11403                                            mp->host_ip6_prefix.len));
11404
11405 }
11406
11407 static int
11408 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11409 {
11410   vl_api_sw_interface_tap_v2_dump_t *mp;
11411   vl_api_control_ping_t *mp_ping;
11412   int ret;
11413
11414   print (vam->ofp,
11415          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11416          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11417          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11418          "host_ip6_addr");
11419
11420   /* Get list of tap interfaces */
11421   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11422   S (mp);
11423
11424   /* Use a control ping for synchronization */
11425   MPING (CONTROL_PING, mp_ping);
11426   S (mp_ping);
11427
11428   W (ret);
11429   return ret;
11430 }
11431
11432 static void vl_api_sw_interface_virtio_pci_details_t_handler
11433   (vl_api_sw_interface_virtio_pci_details_t * mp)
11434 {
11435   vat_main_t *vam = &vat_main;
11436
11437   typedef union
11438   {
11439     struct
11440     {
11441       u16 domain;
11442       u8 bus;
11443       u8 slot:5;
11444       u8 function:3;
11445     };
11446     u32 as_u32;
11447   } pci_addr_t;
11448   pci_addr_t addr;
11449
11450   addr.domain = ntohs (mp->pci_addr.domain);
11451   addr.bus = mp->pci_addr.bus;
11452   addr.slot = mp->pci_addr.slot;
11453   addr.function = mp->pci_addr.function;
11454
11455   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11456                          addr.slot, addr.function);
11457
11458   print (vam->ofp,
11459          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11460          pci_addr, ntohl (mp->sw_if_index),
11461          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11462          format_ethernet_address, mp->mac_addr,
11463          clib_net_to_host_u64 (mp->features));
11464   vec_free (pci_addr);
11465 }
11466
11467 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11468   (vl_api_sw_interface_virtio_pci_details_t * mp)
11469 {
11470   vat_main_t *vam = &vat_main;
11471   vat_json_node_t *node = NULL;
11472   vlib_pci_addr_t pci_addr;
11473
11474   if (VAT_JSON_ARRAY != vam->json_tree.type)
11475     {
11476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11477       vat_json_init_array (&vam->json_tree);
11478     }
11479   node = vat_json_array_add (&vam->json_tree);
11480
11481   pci_addr.domain = ntohs (mp->pci_addr.domain);
11482   pci_addr.bus = mp->pci_addr.bus;
11483   pci_addr.slot = mp->pci_addr.slot;
11484   pci_addr.function = mp->pci_addr.function;
11485
11486   vat_json_init_object (node);
11487   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11488   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11489   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11490   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11491   vat_json_object_add_uint (node, "features",
11492                             clib_net_to_host_u64 (mp->features));
11493   vat_json_object_add_string_copy (node, "mac_addr",
11494                                    format (0, "%U", format_ethernet_address,
11495                                            &mp->mac_addr));
11496 }
11497
11498 static int
11499 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11500 {
11501   vl_api_sw_interface_virtio_pci_dump_t *mp;
11502   vl_api_control_ping_t *mp_ping;
11503   int ret;
11504
11505   print (vam->ofp,
11506          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11507          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11508          "mac_addr", "features");
11509
11510   /* Get list of tap interfaces */
11511   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11512   S (mp);
11513
11514   /* Use a control ping for synchronization */
11515   MPING (CONTROL_PING, mp_ping);
11516   S (mp_ping);
11517
11518   W (ret);
11519   return ret;
11520 }
11521
11522 static int
11523 api_vxlan_offload_rx (vat_main_t * vam)
11524 {
11525   unformat_input_t *line_input = vam->input;
11526   vl_api_vxlan_offload_rx_t *mp;
11527   u32 hw_if_index = ~0, rx_if_index = ~0;
11528   u8 is_add = 1;
11529   int ret;
11530
11531   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11532     {
11533       if (unformat (line_input, "del"))
11534         is_add = 0;
11535       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11536                          &hw_if_index))
11537         ;
11538       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11539         ;
11540       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11541                          &rx_if_index))
11542         ;
11543       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11544         ;
11545       else
11546         {
11547           errmsg ("parse error '%U'", format_unformat_error, line_input);
11548           return -99;
11549         }
11550     }
11551
11552   if (hw_if_index == ~0)
11553     {
11554       errmsg ("no hw interface");
11555       return -99;
11556     }
11557
11558   if (rx_if_index == ~0)
11559     {
11560       errmsg ("no rx tunnel");
11561       return -99;
11562     }
11563
11564   M (VXLAN_OFFLOAD_RX, mp);
11565
11566   mp->hw_if_index = ntohl (hw_if_index);
11567   mp->sw_if_index = ntohl (rx_if_index);
11568   mp->enable = is_add;
11569
11570   S (mp);
11571   W (ret);
11572   return ret;
11573 }
11574
11575 static uword unformat_vxlan_decap_next
11576   (unformat_input_t * input, va_list * args)
11577 {
11578   u32 *result = va_arg (*args, u32 *);
11579   u32 tmp;
11580
11581   if (unformat (input, "l2"))
11582     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11583   else if (unformat (input, "%d", &tmp))
11584     *result = tmp;
11585   else
11586     return 0;
11587   return 1;
11588 }
11589
11590 static int
11591 api_vxlan_add_del_tunnel (vat_main_t * vam)
11592 {
11593   unformat_input_t *line_input = vam->input;
11594   vl_api_vxlan_add_del_tunnel_t *mp;
11595   ip46_address_t src, dst;
11596   u8 is_add = 1;
11597   u8 ipv4_set = 0, ipv6_set = 0;
11598   u8 src_set = 0;
11599   u8 dst_set = 0;
11600   u8 grp_set = 0;
11601   u32 instance = ~0;
11602   u32 mcast_sw_if_index = ~0;
11603   u32 encap_vrf_id = 0;
11604   u32 decap_next_index = ~0;
11605   u32 vni = 0;
11606   int ret;
11607
11608   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11609   clib_memset (&src, 0, sizeof src);
11610   clib_memset (&dst, 0, sizeof dst);
11611
11612   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11613     {
11614       if (unformat (line_input, "del"))
11615         is_add = 0;
11616       else if (unformat (line_input, "instance %d", &instance))
11617         ;
11618       else
11619         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11620         {
11621           ipv4_set = 1;
11622           src_set = 1;
11623         }
11624       else
11625         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11626         {
11627           ipv4_set = 1;
11628           dst_set = 1;
11629         }
11630       else
11631         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11632         {
11633           ipv6_set = 1;
11634           src_set = 1;
11635         }
11636       else
11637         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11638         {
11639           ipv6_set = 1;
11640           dst_set = 1;
11641         }
11642       else if (unformat (line_input, "group %U %U",
11643                          unformat_ip4_address, &dst.ip4,
11644                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11645         {
11646           grp_set = dst_set = 1;
11647           ipv4_set = 1;
11648         }
11649       else if (unformat (line_input, "group %U",
11650                          unformat_ip4_address, &dst.ip4))
11651         {
11652           grp_set = dst_set = 1;
11653           ipv4_set = 1;
11654         }
11655       else if (unformat (line_input, "group %U %U",
11656                          unformat_ip6_address, &dst.ip6,
11657                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11658         {
11659           grp_set = dst_set = 1;
11660           ipv6_set = 1;
11661         }
11662       else if (unformat (line_input, "group %U",
11663                          unformat_ip6_address, &dst.ip6))
11664         {
11665           grp_set = dst_set = 1;
11666           ipv6_set = 1;
11667         }
11668       else
11669         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11670         ;
11671       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11672         ;
11673       else if (unformat (line_input, "decap-next %U",
11674                          unformat_vxlan_decap_next, &decap_next_index))
11675         ;
11676       else if (unformat (line_input, "vni %d", &vni))
11677         ;
11678       else
11679         {
11680           errmsg ("parse error '%U'", format_unformat_error, line_input);
11681           return -99;
11682         }
11683     }
11684
11685   if (src_set == 0)
11686     {
11687       errmsg ("tunnel src address not specified");
11688       return -99;
11689     }
11690   if (dst_set == 0)
11691     {
11692       errmsg ("tunnel dst address not specified");
11693       return -99;
11694     }
11695
11696   if (grp_set && !ip46_address_is_multicast (&dst))
11697     {
11698       errmsg ("tunnel group address not multicast");
11699       return -99;
11700     }
11701   if (grp_set && mcast_sw_if_index == ~0)
11702     {
11703       errmsg ("tunnel nonexistent multicast device");
11704       return -99;
11705     }
11706   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11707     {
11708       errmsg ("tunnel dst address must be unicast");
11709       return -99;
11710     }
11711
11712
11713   if (ipv4_set && ipv6_set)
11714     {
11715       errmsg ("both IPv4 and IPv6 addresses specified");
11716       return -99;
11717     }
11718
11719   if ((vni == 0) || (vni >> 24))
11720     {
11721       errmsg ("vni not specified or out of range");
11722       return -99;
11723     }
11724
11725   M (VXLAN_ADD_DEL_TUNNEL, mp);
11726
11727   if (ipv6_set)
11728     {
11729       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11730       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11731     }
11732   else
11733     {
11734       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11735       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11736     }
11737   mp->src_address.af = ipv6_set;
11738   mp->dst_address.af = ipv6_set;
11739
11740   mp->instance = htonl (instance);
11741   mp->encap_vrf_id = ntohl (encap_vrf_id);
11742   mp->decap_next_index = ntohl (decap_next_index);
11743   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11744   mp->vni = ntohl (vni);
11745   mp->is_add = is_add;
11746
11747   S (mp);
11748   W (ret);
11749   return ret;
11750 }
11751
11752 static void vl_api_vxlan_tunnel_details_t_handler
11753   (vl_api_vxlan_tunnel_details_t * mp)
11754 {
11755   vat_main_t *vam = &vat_main;
11756   ip46_address_t src =
11757     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11758   ip46_address_t dst =
11759     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11760
11761   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11762          ntohl (mp->sw_if_index),
11763          ntohl (mp->instance),
11764          format_ip46_address, &src, IP46_TYPE_ANY,
11765          format_ip46_address, &dst, IP46_TYPE_ANY,
11766          ntohl (mp->encap_vrf_id),
11767          ntohl (mp->decap_next_index), ntohl (mp->vni),
11768          ntohl (mp->mcast_sw_if_index));
11769 }
11770
11771 static void vl_api_vxlan_tunnel_details_t_handler_json
11772   (vl_api_vxlan_tunnel_details_t * mp)
11773 {
11774   vat_main_t *vam = &vat_main;
11775   vat_json_node_t *node = NULL;
11776
11777   if (VAT_JSON_ARRAY != vam->json_tree.type)
11778     {
11779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11780       vat_json_init_array (&vam->json_tree);
11781     }
11782   node = vat_json_array_add (&vam->json_tree);
11783
11784   vat_json_init_object (node);
11785   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11786
11787   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11788
11789   if (mp->src_address.af)
11790     {
11791       struct in6_addr ip6;
11792
11793       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11794       vat_json_object_add_ip6 (node, "src_address", ip6);
11795       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11796       vat_json_object_add_ip6 (node, "dst_address", ip6);
11797     }
11798   else
11799     {
11800       struct in_addr ip4;
11801
11802       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11803       vat_json_object_add_ip4 (node, "src_address", ip4);
11804       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11805       vat_json_object_add_ip4 (node, "dst_address", ip4);
11806     }
11807   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11808   vat_json_object_add_uint (node, "decap_next_index",
11809                             ntohl (mp->decap_next_index));
11810   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11811   vat_json_object_add_uint (node, "mcast_sw_if_index",
11812                             ntohl (mp->mcast_sw_if_index));
11813 }
11814
11815 static int
11816 api_vxlan_tunnel_dump (vat_main_t * vam)
11817 {
11818   unformat_input_t *i = vam->input;
11819   vl_api_vxlan_tunnel_dump_t *mp;
11820   vl_api_control_ping_t *mp_ping;
11821   u32 sw_if_index;
11822   u8 sw_if_index_set = 0;
11823   int ret;
11824
11825   /* Parse args required to build the message */
11826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11827     {
11828       if (unformat (i, "sw_if_index %d", &sw_if_index))
11829         sw_if_index_set = 1;
11830       else
11831         break;
11832     }
11833
11834   if (sw_if_index_set == 0)
11835     {
11836       sw_if_index = ~0;
11837     }
11838
11839   if (!vam->json_output)
11840     {
11841       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11842              "sw_if_index", "instance", "src_address", "dst_address",
11843              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11844     }
11845
11846   /* Get list of vxlan-tunnel interfaces */
11847   M (VXLAN_TUNNEL_DUMP, mp);
11848
11849   mp->sw_if_index = htonl (sw_if_index);
11850
11851   S (mp);
11852
11853   /* Use a control ping for synchronization */
11854   MPING (CONTROL_PING, mp_ping);
11855   S (mp_ping);
11856
11857   W (ret);
11858   return ret;
11859 }
11860
11861 static uword unformat_geneve_decap_next
11862   (unformat_input_t * input, va_list * args)
11863 {
11864   u32 *result = va_arg (*args, u32 *);
11865   u32 tmp;
11866
11867   if (unformat (input, "l2"))
11868     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11869   else if (unformat (input, "%d", &tmp))
11870     *result = tmp;
11871   else
11872     return 0;
11873   return 1;
11874 }
11875
11876 static int
11877 api_geneve_add_del_tunnel (vat_main_t * vam)
11878 {
11879   unformat_input_t *line_input = vam->input;
11880   vl_api_geneve_add_del_tunnel_t *mp;
11881   ip46_address_t src, dst;
11882   u8 is_add = 1;
11883   u8 ipv4_set = 0, ipv6_set = 0;
11884   u8 src_set = 0;
11885   u8 dst_set = 0;
11886   u8 grp_set = 0;
11887   u32 mcast_sw_if_index = ~0;
11888   u32 encap_vrf_id = 0;
11889   u32 decap_next_index = ~0;
11890   u32 vni = 0;
11891   int ret;
11892
11893   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11894   clib_memset (&src, 0, sizeof src);
11895   clib_memset (&dst, 0, sizeof dst);
11896
11897   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11898     {
11899       if (unformat (line_input, "del"))
11900         is_add = 0;
11901       else
11902         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11903         {
11904           ipv4_set = 1;
11905           src_set = 1;
11906         }
11907       else
11908         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11909         {
11910           ipv4_set = 1;
11911           dst_set = 1;
11912         }
11913       else
11914         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11915         {
11916           ipv6_set = 1;
11917           src_set = 1;
11918         }
11919       else
11920         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11921         {
11922           ipv6_set = 1;
11923           dst_set = 1;
11924         }
11925       else if (unformat (line_input, "group %U %U",
11926                          unformat_ip4_address, &dst.ip4,
11927                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11928         {
11929           grp_set = dst_set = 1;
11930           ipv4_set = 1;
11931         }
11932       else if (unformat (line_input, "group %U",
11933                          unformat_ip4_address, &dst.ip4))
11934         {
11935           grp_set = dst_set = 1;
11936           ipv4_set = 1;
11937         }
11938       else if (unformat (line_input, "group %U %U",
11939                          unformat_ip6_address, &dst.ip6,
11940                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11941         {
11942           grp_set = dst_set = 1;
11943           ipv6_set = 1;
11944         }
11945       else if (unformat (line_input, "group %U",
11946                          unformat_ip6_address, &dst.ip6))
11947         {
11948           grp_set = dst_set = 1;
11949           ipv6_set = 1;
11950         }
11951       else
11952         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11953         ;
11954       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11955         ;
11956       else if (unformat (line_input, "decap-next %U",
11957                          unformat_geneve_decap_next, &decap_next_index))
11958         ;
11959       else if (unformat (line_input, "vni %d", &vni))
11960         ;
11961       else
11962         {
11963           errmsg ("parse error '%U'", format_unformat_error, line_input);
11964           return -99;
11965         }
11966     }
11967
11968   if (src_set == 0)
11969     {
11970       errmsg ("tunnel src address not specified");
11971       return -99;
11972     }
11973   if (dst_set == 0)
11974     {
11975       errmsg ("tunnel dst address not specified");
11976       return -99;
11977     }
11978
11979   if (grp_set && !ip46_address_is_multicast (&dst))
11980     {
11981       errmsg ("tunnel group address not multicast");
11982       return -99;
11983     }
11984   if (grp_set && mcast_sw_if_index == ~0)
11985     {
11986       errmsg ("tunnel nonexistent multicast device");
11987       return -99;
11988     }
11989   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11990     {
11991       errmsg ("tunnel dst address must be unicast");
11992       return -99;
11993     }
11994
11995
11996   if (ipv4_set && ipv6_set)
11997     {
11998       errmsg ("both IPv4 and IPv6 addresses specified");
11999       return -99;
12000     }
12001
12002   if ((vni == 0) || (vni >> 24))
12003     {
12004       errmsg ("vni not specified or out of range");
12005       return -99;
12006     }
12007
12008   M (GENEVE_ADD_DEL_TUNNEL, mp);
12009
12010   if (ipv6_set)
12011     {
12012       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12013       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12014     }
12015   else
12016     {
12017       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12018       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12019     }
12020   mp->encap_vrf_id = ntohl (encap_vrf_id);
12021   mp->decap_next_index = ntohl (decap_next_index);
12022   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12023   mp->vni = ntohl (vni);
12024   mp->is_add = is_add;
12025
12026   S (mp);
12027   W (ret);
12028   return ret;
12029 }
12030
12031 static void vl_api_geneve_tunnel_details_t_handler
12032   (vl_api_geneve_tunnel_details_t * mp)
12033 {
12034   vat_main_t *vam = &vat_main;
12035   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12036   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12037
12038   if (mp->src_address.af == ADDRESS_IP6)
12039     {
12040       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12041       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12042     }
12043   else
12044     {
12045       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12046       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12047     }
12048
12049   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12050          ntohl (mp->sw_if_index),
12051          format_ip46_address, &src, IP46_TYPE_ANY,
12052          format_ip46_address, &dst, IP46_TYPE_ANY,
12053          ntohl (mp->encap_vrf_id),
12054          ntohl (mp->decap_next_index), ntohl (mp->vni),
12055          ntohl (mp->mcast_sw_if_index));
12056 }
12057
12058 static void vl_api_geneve_tunnel_details_t_handler_json
12059   (vl_api_geneve_tunnel_details_t * mp)
12060 {
12061   vat_main_t *vam = &vat_main;
12062   vat_json_node_t *node = NULL;
12063   bool is_ipv6;
12064
12065   if (VAT_JSON_ARRAY != vam->json_tree.type)
12066     {
12067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12068       vat_json_init_array (&vam->json_tree);
12069     }
12070   node = vat_json_array_add (&vam->json_tree);
12071
12072   vat_json_init_object (node);
12073   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12074   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12075   if (is_ipv6)
12076     {
12077       struct in6_addr ip6;
12078
12079       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12080       vat_json_object_add_ip6 (node, "src_address", ip6);
12081       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12082       vat_json_object_add_ip6 (node, "dst_address", ip6);
12083     }
12084   else
12085     {
12086       struct in_addr ip4;
12087
12088       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12089       vat_json_object_add_ip4 (node, "src_address", ip4);
12090       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12091       vat_json_object_add_ip4 (node, "dst_address", ip4);
12092     }
12093   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12094   vat_json_object_add_uint (node, "decap_next_index",
12095                             ntohl (mp->decap_next_index));
12096   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12097   vat_json_object_add_uint (node, "mcast_sw_if_index",
12098                             ntohl (mp->mcast_sw_if_index));
12099 }
12100
12101 static int
12102 api_geneve_tunnel_dump (vat_main_t * vam)
12103 {
12104   unformat_input_t *i = vam->input;
12105   vl_api_geneve_tunnel_dump_t *mp;
12106   vl_api_control_ping_t *mp_ping;
12107   u32 sw_if_index;
12108   u8 sw_if_index_set = 0;
12109   int ret;
12110
12111   /* Parse args required to build the message */
12112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12113     {
12114       if (unformat (i, "sw_if_index %d", &sw_if_index))
12115         sw_if_index_set = 1;
12116       else
12117         break;
12118     }
12119
12120   if (sw_if_index_set == 0)
12121     {
12122       sw_if_index = ~0;
12123     }
12124
12125   if (!vam->json_output)
12126     {
12127       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12128              "sw_if_index", "local_address", "remote_address",
12129              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12130     }
12131
12132   /* Get list of geneve-tunnel interfaces */
12133   M (GENEVE_TUNNEL_DUMP, mp);
12134
12135   mp->sw_if_index = htonl (sw_if_index);
12136
12137   S (mp);
12138
12139   /* Use a control ping for synchronization */
12140   M (CONTROL_PING, mp_ping);
12141   S (mp_ping);
12142
12143   W (ret);
12144   return ret;
12145 }
12146
12147 static int
12148 api_gre_tunnel_add_del (vat_main_t * vam)
12149 {
12150   unformat_input_t *line_input = vam->input;
12151   vl_api_address_t src = { }, dst =
12152   {
12153   };
12154   vl_api_gre_tunnel_add_del_t *mp;
12155   vl_api_gre_tunnel_type_t t_type;
12156   u8 is_add = 1;
12157   u8 src_set = 0;
12158   u8 dst_set = 0;
12159   u32 outer_table_id = 0;
12160   u32 session_id = 0;
12161   u32 instance = ~0;
12162   int ret;
12163
12164   t_type = GRE_API_TUNNEL_TYPE_L3;
12165
12166   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12167     {
12168       if (unformat (line_input, "del"))
12169         is_add = 0;
12170       else if (unformat (line_input, "instance %d", &instance))
12171         ;
12172       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12173         {
12174           src_set = 1;
12175         }
12176       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12177         {
12178           dst_set = 1;
12179         }
12180       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12181         ;
12182       else if (unformat (line_input, "teb"))
12183         t_type = GRE_API_TUNNEL_TYPE_TEB;
12184       else if (unformat (line_input, "erspan %d", &session_id))
12185         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12186       else
12187         {
12188           errmsg ("parse error '%U'", format_unformat_error, line_input);
12189           return -99;
12190         }
12191     }
12192
12193   if (src_set == 0)
12194     {
12195       errmsg ("tunnel src address not specified");
12196       return -99;
12197     }
12198   if (dst_set == 0)
12199     {
12200       errmsg ("tunnel dst address not specified");
12201       return -99;
12202     }
12203
12204   M (GRE_TUNNEL_ADD_DEL, mp);
12205
12206   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12207   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12208
12209   mp->tunnel.instance = htonl (instance);
12210   mp->tunnel.outer_table_id = htonl (outer_table_id);
12211   mp->is_add = is_add;
12212   mp->tunnel.session_id = htons ((u16) session_id);
12213   mp->tunnel.type = htonl (t_type);
12214
12215   S (mp);
12216   W (ret);
12217   return ret;
12218 }
12219
12220 static void vl_api_gre_tunnel_details_t_handler
12221   (vl_api_gre_tunnel_details_t * mp)
12222 {
12223   vat_main_t *vam = &vat_main;
12224
12225   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12226          ntohl (mp->tunnel.sw_if_index),
12227          ntohl (mp->tunnel.instance),
12228          format_vl_api_address, &mp->tunnel.src,
12229          format_vl_api_address, &mp->tunnel.dst,
12230          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12231          ntohl (mp->tunnel.session_id));
12232 }
12233
12234 static void vl_api_gre_tunnel_details_t_handler_json
12235   (vl_api_gre_tunnel_details_t * mp)
12236 {
12237   vat_main_t *vam = &vat_main;
12238   vat_json_node_t *node = NULL;
12239
12240   if (VAT_JSON_ARRAY != vam->json_tree.type)
12241     {
12242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12243       vat_json_init_array (&vam->json_tree);
12244     }
12245   node = vat_json_array_add (&vam->json_tree);
12246
12247   vat_json_init_object (node);
12248   vat_json_object_add_uint (node, "sw_if_index",
12249                             ntohl (mp->tunnel.sw_if_index));
12250   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12251
12252   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12253   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12254   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12255   vat_json_object_add_uint (node, "outer_table_id",
12256                             ntohl (mp->tunnel.outer_table_id));
12257   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12258 }
12259
12260 static int
12261 api_gre_tunnel_dump (vat_main_t * vam)
12262 {
12263   unformat_input_t *i = vam->input;
12264   vl_api_gre_tunnel_dump_t *mp;
12265   vl_api_control_ping_t *mp_ping;
12266   u32 sw_if_index;
12267   u8 sw_if_index_set = 0;
12268   int ret;
12269
12270   /* Parse args required to build the message */
12271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12272     {
12273       if (unformat (i, "sw_if_index %d", &sw_if_index))
12274         sw_if_index_set = 1;
12275       else
12276         break;
12277     }
12278
12279   if (sw_if_index_set == 0)
12280     {
12281       sw_if_index = ~0;
12282     }
12283
12284   if (!vam->json_output)
12285     {
12286       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12287              "sw_if_index", "instance", "src_address", "dst_address",
12288              "tunnel_type", "outer_fib_id", "session_id");
12289     }
12290
12291   /* Get list of gre-tunnel interfaces */
12292   M (GRE_TUNNEL_DUMP, mp);
12293
12294   mp->sw_if_index = htonl (sw_if_index);
12295
12296   S (mp);
12297
12298   /* Use a control ping for synchronization */
12299   MPING (CONTROL_PING, mp_ping);
12300   S (mp_ping);
12301
12302   W (ret);
12303   return ret;
12304 }
12305
12306 static int
12307 api_l2_fib_clear_table (vat_main_t * vam)
12308 {
12309 //  unformat_input_t * i = vam->input;
12310   vl_api_l2_fib_clear_table_t *mp;
12311   int ret;
12312
12313   M (L2_FIB_CLEAR_TABLE, mp);
12314
12315   S (mp);
12316   W (ret);
12317   return ret;
12318 }
12319
12320 static int
12321 api_l2_interface_efp_filter (vat_main_t * vam)
12322 {
12323   unformat_input_t *i = vam->input;
12324   vl_api_l2_interface_efp_filter_t *mp;
12325   u32 sw_if_index;
12326   u8 enable = 1;
12327   u8 sw_if_index_set = 0;
12328   int ret;
12329
12330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12333         sw_if_index_set = 1;
12334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12335         sw_if_index_set = 1;
12336       else if (unformat (i, "enable"))
12337         enable = 1;
12338       else if (unformat (i, "disable"))
12339         enable = 0;
12340       else
12341         {
12342           clib_warning ("parse error '%U'", format_unformat_error, i);
12343           return -99;
12344         }
12345     }
12346
12347   if (sw_if_index_set == 0)
12348     {
12349       errmsg ("missing sw_if_index");
12350       return -99;
12351     }
12352
12353   M (L2_INTERFACE_EFP_FILTER, mp);
12354
12355   mp->sw_if_index = ntohl (sw_if_index);
12356   mp->enable_disable = enable;
12357
12358   S (mp);
12359   W (ret);
12360   return ret;
12361 }
12362
12363 #define foreach_vtr_op                          \
12364 _("disable",  L2_VTR_DISABLED)                  \
12365 _("push-1",  L2_VTR_PUSH_1)                     \
12366 _("push-2",  L2_VTR_PUSH_2)                     \
12367 _("pop-1",  L2_VTR_POP_1)                       \
12368 _("pop-2",  L2_VTR_POP_2)                       \
12369 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12370 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12371 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12372 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12373
12374 static int
12375 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12376 {
12377   unformat_input_t *i = vam->input;
12378   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12379   u32 sw_if_index;
12380   u8 sw_if_index_set = 0;
12381   u8 vtr_op_set = 0;
12382   u32 vtr_op = 0;
12383   u32 push_dot1q = 1;
12384   u32 tag1 = ~0;
12385   u32 tag2 = ~0;
12386   int ret;
12387
12388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12389     {
12390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12391         sw_if_index_set = 1;
12392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12393         sw_if_index_set = 1;
12394       else if (unformat (i, "vtr_op %d", &vtr_op))
12395         vtr_op_set = 1;
12396 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12397       foreach_vtr_op
12398 #undef _
12399         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12400         ;
12401       else if (unformat (i, "tag1 %d", &tag1))
12402         ;
12403       else if (unformat (i, "tag2 %d", &tag2))
12404         ;
12405       else
12406         {
12407           clib_warning ("parse error '%U'", format_unformat_error, i);
12408           return -99;
12409         }
12410     }
12411
12412   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12413     {
12414       errmsg ("missing vtr operation or sw_if_index");
12415       return -99;
12416     }
12417
12418   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12419   mp->sw_if_index = ntohl (sw_if_index);
12420   mp->vtr_op = ntohl (vtr_op);
12421   mp->push_dot1q = ntohl (push_dot1q);
12422   mp->tag1 = ntohl (tag1);
12423   mp->tag2 = ntohl (tag2);
12424
12425   S (mp);
12426   W (ret);
12427   return ret;
12428 }
12429
12430 static int
12431 api_create_vhost_user_if (vat_main_t * vam)
12432 {
12433   unformat_input_t *i = vam->input;
12434   vl_api_create_vhost_user_if_t *mp;
12435   u8 *file_name;
12436   u8 is_server = 0;
12437   u8 file_name_set = 0;
12438   u32 custom_dev_instance = ~0;
12439   u8 hwaddr[6];
12440   u8 use_custom_mac = 0;
12441   u8 disable_mrg_rxbuf = 0;
12442   u8 disable_indirect_desc = 0;
12443   u8 *tag = 0;
12444   u8 enable_gso = 0;
12445   u8 enable_packed = 0;
12446   int ret;
12447
12448   /* Shut up coverity */
12449   clib_memset (hwaddr, 0, sizeof (hwaddr));
12450
12451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12452     {
12453       if (unformat (i, "socket %s", &file_name))
12454         {
12455           file_name_set = 1;
12456         }
12457       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12458         ;
12459       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12460         use_custom_mac = 1;
12461       else if (unformat (i, "server"))
12462         is_server = 1;
12463       else if (unformat (i, "disable_mrg_rxbuf"))
12464         disable_mrg_rxbuf = 1;
12465       else if (unformat (i, "disable_indirect_desc"))
12466         disable_indirect_desc = 1;
12467       else if (unformat (i, "gso"))
12468         enable_gso = 1;
12469       else if (unformat (i, "packed"))
12470         enable_packed = 1;
12471       else if (unformat (i, "tag %s", &tag))
12472         ;
12473       else
12474         break;
12475     }
12476
12477   if (file_name_set == 0)
12478     {
12479       errmsg ("missing socket file name");
12480       return -99;
12481     }
12482
12483   if (vec_len (file_name) > 255)
12484     {
12485       errmsg ("socket file name too long");
12486       return -99;
12487     }
12488   vec_add1 (file_name, 0);
12489
12490   M (CREATE_VHOST_USER_IF, mp);
12491
12492   mp->is_server = is_server;
12493   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12494   mp->disable_indirect_desc = disable_indirect_desc;
12495   mp->enable_gso = enable_gso;
12496   mp->enable_packed = enable_packed;
12497   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12498   vec_free (file_name);
12499   if (custom_dev_instance != ~0)
12500     {
12501       mp->renumber = 1;
12502       mp->custom_dev_instance = ntohl (custom_dev_instance);
12503     }
12504
12505   mp->use_custom_mac = use_custom_mac;
12506   clib_memcpy (mp->mac_address, hwaddr, 6);
12507   if (tag)
12508     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12509   vec_free (tag);
12510
12511   S (mp);
12512   W (ret);
12513   return ret;
12514 }
12515
12516 static int
12517 api_modify_vhost_user_if (vat_main_t * vam)
12518 {
12519   unformat_input_t *i = vam->input;
12520   vl_api_modify_vhost_user_if_t *mp;
12521   u8 *file_name;
12522   u8 is_server = 0;
12523   u8 file_name_set = 0;
12524   u32 custom_dev_instance = ~0;
12525   u8 sw_if_index_set = 0;
12526   u32 sw_if_index = (u32) ~ 0;
12527   u8 enable_gso = 0;
12528   u8 enable_packed = 0;
12529   int ret;
12530
12531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12532     {
12533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12534         sw_if_index_set = 1;
12535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12536         sw_if_index_set = 1;
12537       else if (unformat (i, "socket %s", &file_name))
12538         {
12539           file_name_set = 1;
12540         }
12541       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12542         ;
12543       else if (unformat (i, "server"))
12544         is_server = 1;
12545       else if (unformat (i, "gso"))
12546         enable_gso = 1;
12547       else if (unformat (i, "packed"))
12548         enable_packed = 1;
12549       else
12550         break;
12551     }
12552
12553   if (sw_if_index_set == 0)
12554     {
12555       errmsg ("missing sw_if_index or interface name");
12556       return -99;
12557     }
12558
12559   if (file_name_set == 0)
12560     {
12561       errmsg ("missing socket file name");
12562       return -99;
12563     }
12564
12565   if (vec_len (file_name) > 255)
12566     {
12567       errmsg ("socket file name too long");
12568       return -99;
12569     }
12570   vec_add1 (file_name, 0);
12571
12572   M (MODIFY_VHOST_USER_IF, mp);
12573
12574   mp->sw_if_index = ntohl (sw_if_index);
12575   mp->is_server = is_server;
12576   mp->enable_gso = enable_gso;
12577   mp->enable_packed = enable_packed;
12578   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12579   vec_free (file_name);
12580   if (custom_dev_instance != ~0)
12581     {
12582       mp->renumber = 1;
12583       mp->custom_dev_instance = ntohl (custom_dev_instance);
12584     }
12585
12586   S (mp);
12587   W (ret);
12588   return ret;
12589 }
12590
12591 static int
12592 api_delete_vhost_user_if (vat_main_t * vam)
12593 {
12594   unformat_input_t *i = vam->input;
12595   vl_api_delete_vhost_user_if_t *mp;
12596   u32 sw_if_index = ~0;
12597   u8 sw_if_index_set = 0;
12598   int ret;
12599
12600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12601     {
12602       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12603         sw_if_index_set = 1;
12604       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12605         sw_if_index_set = 1;
12606       else
12607         break;
12608     }
12609
12610   if (sw_if_index_set == 0)
12611     {
12612       errmsg ("missing sw_if_index or interface name");
12613       return -99;
12614     }
12615
12616
12617   M (DELETE_VHOST_USER_IF, mp);
12618
12619   mp->sw_if_index = ntohl (sw_if_index);
12620
12621   S (mp);
12622   W (ret);
12623   return ret;
12624 }
12625
12626 static void vl_api_sw_interface_vhost_user_details_t_handler
12627   (vl_api_sw_interface_vhost_user_details_t * mp)
12628 {
12629   vat_main_t *vam = &vat_main;
12630   u64 features;
12631
12632   features =
12633     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12634                                                     clib_net_to_host_u32
12635                                                     (mp->features_last_32) <<
12636                                                     32);
12637
12638   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12639          (char *) mp->interface_name,
12640          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12641          features, mp->is_server,
12642          ntohl (mp->num_regions), (char *) mp->sock_filename);
12643   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12644 }
12645
12646 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12647   (vl_api_sw_interface_vhost_user_details_t * mp)
12648 {
12649   vat_main_t *vam = &vat_main;
12650   vat_json_node_t *node = NULL;
12651
12652   if (VAT_JSON_ARRAY != vam->json_tree.type)
12653     {
12654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12655       vat_json_init_array (&vam->json_tree);
12656     }
12657   node = vat_json_array_add (&vam->json_tree);
12658
12659   vat_json_init_object (node);
12660   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12661   vat_json_object_add_string_copy (node, "interface_name",
12662                                    mp->interface_name);
12663   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12664                             ntohl (mp->virtio_net_hdr_sz));
12665   vat_json_object_add_uint (node, "features_first_32",
12666                             clib_net_to_host_u32 (mp->features_first_32));
12667   vat_json_object_add_uint (node, "features_last_32",
12668                             clib_net_to_host_u32 (mp->features_last_32));
12669   vat_json_object_add_uint (node, "is_server", mp->is_server);
12670   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12671   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12672   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12673 }
12674
12675 static int
12676 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12677 {
12678   unformat_input_t *i = vam->input;
12679   vl_api_sw_interface_vhost_user_dump_t *mp;
12680   vl_api_control_ping_t *mp_ping;
12681   int ret;
12682   u32 sw_if_index = ~0;
12683
12684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12685     {
12686       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12687         ;
12688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12689         ;
12690       else
12691         break;
12692     }
12693
12694   print (vam->ofp,
12695          "Interface name            idx hdr_sz features server regions filename");
12696
12697   /* Get list of vhost-user interfaces */
12698   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12699   mp->sw_if_index = ntohl (sw_if_index);
12700   S (mp);
12701
12702   /* Use a control ping for synchronization */
12703   MPING (CONTROL_PING, mp_ping);
12704   S (mp_ping);
12705
12706   W (ret);
12707   return ret;
12708 }
12709
12710 static int
12711 api_show_version (vat_main_t * vam)
12712 {
12713   vl_api_show_version_t *mp;
12714   int ret;
12715
12716   M (SHOW_VERSION, mp);
12717
12718   S (mp);
12719   W (ret);
12720   return ret;
12721 }
12722
12723
12724 static int
12725 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12726 {
12727   unformat_input_t *line_input = vam->input;
12728   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12729   ip46_address_t local, remote;
12730   u8 is_add = 1;
12731   u8 local_set = 0;
12732   u8 remote_set = 0;
12733   u8 grp_set = 0;
12734   u32 mcast_sw_if_index = ~0;
12735   u32 encap_vrf_id = 0;
12736   u32 decap_vrf_id = 0;
12737   u8 protocol = ~0;
12738   u32 vni;
12739   u8 vni_set = 0;
12740   int ret;
12741
12742   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12743     {
12744       if (unformat (line_input, "del"))
12745         is_add = 0;
12746       else if (unformat (line_input, "local %U",
12747                          unformat_ip46_address, &local))
12748         {
12749           local_set = 1;
12750         }
12751       else if (unformat (line_input, "remote %U",
12752                          unformat_ip46_address, &remote))
12753         {
12754           remote_set = 1;
12755         }
12756       else if (unformat (line_input, "group %U %U",
12757                          unformat_ip46_address, &remote,
12758                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12759         {
12760           grp_set = remote_set = 1;
12761         }
12762       else if (unformat (line_input, "group %U",
12763                          unformat_ip46_address, &remote))
12764         {
12765           grp_set = remote_set = 1;
12766         }
12767       else
12768         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12769         ;
12770       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12771         ;
12772       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12773         ;
12774       else if (unformat (line_input, "vni %d", &vni))
12775         vni_set = 1;
12776       else if (unformat (line_input, "next-ip4"))
12777         protocol = 1;
12778       else if (unformat (line_input, "next-ip6"))
12779         protocol = 2;
12780       else if (unformat (line_input, "next-ethernet"))
12781         protocol = 3;
12782       else if (unformat (line_input, "next-nsh"))
12783         protocol = 4;
12784       else
12785         {
12786           errmsg ("parse error '%U'", format_unformat_error, line_input);
12787           return -99;
12788         }
12789     }
12790
12791   if (local_set == 0)
12792     {
12793       errmsg ("tunnel local address not specified");
12794       return -99;
12795     }
12796   if (remote_set == 0)
12797     {
12798       errmsg ("tunnel remote address not specified");
12799       return -99;
12800     }
12801   if (grp_set && mcast_sw_if_index == ~0)
12802     {
12803       errmsg ("tunnel nonexistent multicast device");
12804       return -99;
12805     }
12806   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12807     {
12808       errmsg ("both IPv4 and IPv6 addresses specified");
12809       return -99;
12810     }
12811
12812   if (vni_set == 0)
12813     {
12814       errmsg ("vni not specified");
12815       return -99;
12816     }
12817
12818   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12819
12820   ip_address_encode (&local,
12821                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12822                      IP46_TYPE_IP6, &mp->local);
12823   ip_address_encode (&remote,
12824                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12825                      IP46_TYPE_IP6, &mp->remote);
12826
12827   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12828   mp->encap_vrf_id = ntohl (encap_vrf_id);
12829   mp->decap_vrf_id = ntohl (decap_vrf_id);
12830   mp->protocol = protocol;
12831   mp->vni = ntohl (vni);
12832   mp->is_add = is_add;
12833
12834   S (mp);
12835   W (ret);
12836   return ret;
12837 }
12838
12839 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12840   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12841 {
12842   vat_main_t *vam = &vat_main;
12843   ip46_address_t local, remote;
12844
12845   ip_address_decode (&mp->local, &local);
12846   ip_address_decode (&mp->remote, &remote);
12847
12848   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12849          ntohl (mp->sw_if_index),
12850          format_ip46_address, &local, IP46_TYPE_ANY,
12851          format_ip46_address, &remote, IP46_TYPE_ANY,
12852          ntohl (mp->vni), mp->protocol,
12853          ntohl (mp->mcast_sw_if_index),
12854          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12855 }
12856
12857
12858 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12859   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12860 {
12861   vat_main_t *vam = &vat_main;
12862   vat_json_node_t *node = NULL;
12863   struct in_addr ip4;
12864   struct in6_addr ip6;
12865   ip46_address_t local, remote;
12866
12867   ip_address_decode (&mp->local, &local);
12868   ip_address_decode (&mp->remote, &remote);
12869
12870   if (VAT_JSON_ARRAY != vam->json_tree.type)
12871     {
12872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12873       vat_json_init_array (&vam->json_tree);
12874     }
12875   node = vat_json_array_add (&vam->json_tree);
12876
12877   vat_json_init_object (node);
12878   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12879   if (ip46_address_is_ip4 (&local))
12880     {
12881       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12882       vat_json_object_add_ip4 (node, "local", ip4);
12883       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12884       vat_json_object_add_ip4 (node, "remote", ip4);
12885     }
12886   else
12887     {
12888       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12889       vat_json_object_add_ip6 (node, "local", ip6);
12890       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12891       vat_json_object_add_ip6 (node, "remote", ip6);
12892     }
12893   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12894   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12895   vat_json_object_add_uint (node, "mcast_sw_if_index",
12896                             ntohl (mp->mcast_sw_if_index));
12897   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12898   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12899   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12900 }
12901
12902 static int
12903 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12904 {
12905   unformat_input_t *i = vam->input;
12906   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12907   vl_api_control_ping_t *mp_ping;
12908   u32 sw_if_index;
12909   u8 sw_if_index_set = 0;
12910   int ret;
12911
12912   /* Parse args required to build the message */
12913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12914     {
12915       if (unformat (i, "sw_if_index %d", &sw_if_index))
12916         sw_if_index_set = 1;
12917       else
12918         break;
12919     }
12920
12921   if (sw_if_index_set == 0)
12922     {
12923       sw_if_index = ~0;
12924     }
12925
12926   if (!vam->json_output)
12927     {
12928       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12929              "sw_if_index", "local", "remote", "vni",
12930              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12931     }
12932
12933   /* Get list of vxlan-tunnel interfaces */
12934   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12935
12936   mp->sw_if_index = htonl (sw_if_index);
12937
12938   S (mp);
12939
12940   /* Use a control ping for synchronization */
12941   MPING (CONTROL_PING, mp_ping);
12942   S (mp_ping);
12943
12944   W (ret);
12945   return ret;
12946 }
12947
12948 static void vl_api_l2_fib_table_details_t_handler
12949   (vl_api_l2_fib_table_details_t * mp)
12950 {
12951   vat_main_t *vam = &vat_main;
12952
12953   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12954          "       %d       %d     %d",
12955          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12956          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12957          mp->bvi_mac);
12958 }
12959
12960 static void vl_api_l2_fib_table_details_t_handler_json
12961   (vl_api_l2_fib_table_details_t * mp)
12962 {
12963   vat_main_t *vam = &vat_main;
12964   vat_json_node_t *node = NULL;
12965
12966   if (VAT_JSON_ARRAY != vam->json_tree.type)
12967     {
12968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12969       vat_json_init_array (&vam->json_tree);
12970     }
12971   node = vat_json_array_add (&vam->json_tree);
12972
12973   vat_json_init_object (node);
12974   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12975   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12976   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12977   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12978   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12979   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12980 }
12981
12982 static int
12983 api_l2_fib_table_dump (vat_main_t * vam)
12984 {
12985   unformat_input_t *i = vam->input;
12986   vl_api_l2_fib_table_dump_t *mp;
12987   vl_api_control_ping_t *mp_ping;
12988   u32 bd_id;
12989   u8 bd_id_set = 0;
12990   int ret;
12991
12992   /* Parse args required to build the message */
12993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12994     {
12995       if (unformat (i, "bd_id %d", &bd_id))
12996         bd_id_set = 1;
12997       else
12998         break;
12999     }
13000
13001   if (bd_id_set == 0)
13002     {
13003       errmsg ("missing bridge domain");
13004       return -99;
13005     }
13006
13007   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13008
13009   /* Get list of l2 fib entries */
13010   M (L2_FIB_TABLE_DUMP, mp);
13011
13012   mp->bd_id = ntohl (bd_id);
13013   S (mp);
13014
13015   /* Use a control ping for synchronization */
13016   MPING (CONTROL_PING, mp_ping);
13017   S (mp_ping);
13018
13019   W (ret);
13020   return ret;
13021 }
13022
13023
13024 static int
13025 api_interface_name_renumber (vat_main_t * vam)
13026 {
13027   unformat_input_t *line_input = vam->input;
13028   vl_api_interface_name_renumber_t *mp;
13029   u32 sw_if_index = ~0;
13030   u32 new_show_dev_instance = ~0;
13031   int ret;
13032
13033   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13034     {
13035       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13036                     &sw_if_index))
13037         ;
13038       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13039         ;
13040       else if (unformat (line_input, "new_show_dev_instance %d",
13041                          &new_show_dev_instance))
13042         ;
13043       else
13044         break;
13045     }
13046
13047   if (sw_if_index == ~0)
13048     {
13049       errmsg ("missing interface name or sw_if_index");
13050       return -99;
13051     }
13052
13053   if (new_show_dev_instance == ~0)
13054     {
13055       errmsg ("missing new_show_dev_instance");
13056       return -99;
13057     }
13058
13059   M (INTERFACE_NAME_RENUMBER, mp);
13060
13061   mp->sw_if_index = ntohl (sw_if_index);
13062   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13063
13064   S (mp);
13065   W (ret);
13066   return ret;
13067 }
13068
13069 static int
13070 api_want_l2_macs_events (vat_main_t * vam)
13071 {
13072   unformat_input_t *line_input = vam->input;
13073   vl_api_want_l2_macs_events_t *mp;
13074   u8 enable_disable = 1;
13075   u32 scan_delay = 0;
13076   u32 max_macs_in_event = 0;
13077   u32 learn_limit = 0;
13078   int ret;
13079
13080   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13081     {
13082       if (unformat (line_input, "learn-limit %d", &learn_limit))
13083         ;
13084       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13085         ;
13086       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13087         ;
13088       else if (unformat (line_input, "disable"))
13089         enable_disable = 0;
13090       else
13091         break;
13092     }
13093
13094   M (WANT_L2_MACS_EVENTS, mp);
13095   mp->enable_disable = enable_disable;
13096   mp->pid = htonl (getpid ());
13097   mp->learn_limit = htonl (learn_limit);
13098   mp->scan_delay = (u8) scan_delay;
13099   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13100   S (mp);
13101   W (ret);
13102   return ret;
13103 }
13104
13105 static int
13106 api_input_acl_set_interface (vat_main_t * vam)
13107 {
13108   unformat_input_t *i = vam->input;
13109   vl_api_input_acl_set_interface_t *mp;
13110   u32 sw_if_index;
13111   int sw_if_index_set;
13112   u32 ip4_table_index = ~0;
13113   u32 ip6_table_index = ~0;
13114   u32 l2_table_index = ~0;
13115   u8 is_add = 1;
13116   int ret;
13117
13118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13119     {
13120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13121         sw_if_index_set = 1;
13122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13123         sw_if_index_set = 1;
13124       else if (unformat (i, "del"))
13125         is_add = 0;
13126       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13127         ;
13128       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13129         ;
13130       else if (unformat (i, "l2-table %d", &l2_table_index))
13131         ;
13132       else
13133         {
13134           clib_warning ("parse error '%U'", format_unformat_error, i);
13135           return -99;
13136         }
13137     }
13138
13139   if (sw_if_index_set == 0)
13140     {
13141       errmsg ("missing interface name or sw_if_index");
13142       return -99;
13143     }
13144
13145   M (INPUT_ACL_SET_INTERFACE, mp);
13146
13147   mp->sw_if_index = ntohl (sw_if_index);
13148   mp->ip4_table_index = ntohl (ip4_table_index);
13149   mp->ip6_table_index = ntohl (ip6_table_index);
13150   mp->l2_table_index = ntohl (l2_table_index);
13151   mp->is_add = is_add;
13152
13153   S (mp);
13154   W (ret);
13155   return ret;
13156 }
13157
13158 static int
13159 api_output_acl_set_interface (vat_main_t * vam)
13160 {
13161   unformat_input_t *i = vam->input;
13162   vl_api_output_acl_set_interface_t *mp;
13163   u32 sw_if_index;
13164   int sw_if_index_set;
13165   u32 ip4_table_index = ~0;
13166   u32 ip6_table_index = ~0;
13167   u32 l2_table_index = ~0;
13168   u8 is_add = 1;
13169   int ret;
13170
13171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13172     {
13173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13174         sw_if_index_set = 1;
13175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13176         sw_if_index_set = 1;
13177       else if (unformat (i, "del"))
13178         is_add = 0;
13179       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13180         ;
13181       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13182         ;
13183       else if (unformat (i, "l2-table %d", &l2_table_index))
13184         ;
13185       else
13186         {
13187           clib_warning ("parse error '%U'", format_unformat_error, i);
13188           return -99;
13189         }
13190     }
13191
13192   if (sw_if_index_set == 0)
13193     {
13194       errmsg ("missing interface name or sw_if_index");
13195       return -99;
13196     }
13197
13198   M (OUTPUT_ACL_SET_INTERFACE, mp);
13199
13200   mp->sw_if_index = ntohl (sw_if_index);
13201   mp->ip4_table_index = ntohl (ip4_table_index);
13202   mp->ip6_table_index = ntohl (ip6_table_index);
13203   mp->l2_table_index = ntohl (l2_table_index);
13204   mp->is_add = is_add;
13205
13206   S (mp);
13207   W (ret);
13208   return ret;
13209 }
13210
13211 static int
13212 api_ip_address_dump (vat_main_t * vam)
13213 {
13214   unformat_input_t *i = vam->input;
13215   vl_api_ip_address_dump_t *mp;
13216   vl_api_control_ping_t *mp_ping;
13217   u32 sw_if_index = ~0;
13218   u8 sw_if_index_set = 0;
13219   u8 ipv4_set = 0;
13220   u8 ipv6_set = 0;
13221   int ret;
13222
13223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13224     {
13225       if (unformat (i, "sw_if_index %d", &sw_if_index))
13226         sw_if_index_set = 1;
13227       else
13228         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13229         sw_if_index_set = 1;
13230       else if (unformat (i, "ipv4"))
13231         ipv4_set = 1;
13232       else if (unformat (i, "ipv6"))
13233         ipv6_set = 1;
13234       else
13235         break;
13236     }
13237
13238   if (ipv4_set && ipv6_set)
13239     {
13240       errmsg ("ipv4 and ipv6 flags cannot be both set");
13241       return -99;
13242     }
13243
13244   if ((!ipv4_set) && (!ipv6_set))
13245     {
13246       errmsg ("no ipv4 nor ipv6 flag set");
13247       return -99;
13248     }
13249
13250   if (sw_if_index_set == 0)
13251     {
13252       errmsg ("missing interface name or sw_if_index");
13253       return -99;
13254     }
13255
13256   vam->current_sw_if_index = sw_if_index;
13257   vam->is_ipv6 = ipv6_set;
13258
13259   M (IP_ADDRESS_DUMP, mp);
13260   mp->sw_if_index = ntohl (sw_if_index);
13261   mp->is_ipv6 = ipv6_set;
13262   S (mp);
13263
13264   /* Use a control ping for synchronization */
13265   MPING (CONTROL_PING, mp_ping);
13266   S (mp_ping);
13267
13268   W (ret);
13269   return ret;
13270 }
13271
13272 static int
13273 api_ip_dump (vat_main_t * vam)
13274 {
13275   vl_api_ip_dump_t *mp;
13276   vl_api_control_ping_t *mp_ping;
13277   unformat_input_t *in = vam->input;
13278   int ipv4_set = 0;
13279   int ipv6_set = 0;
13280   int is_ipv6;
13281   int i;
13282   int ret;
13283
13284   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13285     {
13286       if (unformat (in, "ipv4"))
13287         ipv4_set = 1;
13288       else if (unformat (in, "ipv6"))
13289         ipv6_set = 1;
13290       else
13291         break;
13292     }
13293
13294   if (ipv4_set && ipv6_set)
13295     {
13296       errmsg ("ipv4 and ipv6 flags cannot be both set");
13297       return -99;
13298     }
13299
13300   if ((!ipv4_set) && (!ipv6_set))
13301     {
13302       errmsg ("no ipv4 nor ipv6 flag set");
13303       return -99;
13304     }
13305
13306   is_ipv6 = ipv6_set;
13307   vam->is_ipv6 = is_ipv6;
13308
13309   /* free old data */
13310   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13311     {
13312       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13313     }
13314   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13315
13316   M (IP_DUMP, mp);
13317   mp->is_ipv6 = ipv6_set;
13318   S (mp);
13319
13320   /* Use a control ping for synchronization */
13321   MPING (CONTROL_PING, mp_ping);
13322   S (mp_ping);
13323
13324   W (ret);
13325   return ret;
13326 }
13327
13328 static int
13329 api_ipsec_spd_add_del (vat_main_t * vam)
13330 {
13331   unformat_input_t *i = vam->input;
13332   vl_api_ipsec_spd_add_del_t *mp;
13333   u32 spd_id = ~0;
13334   u8 is_add = 1;
13335   int ret;
13336
13337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13338     {
13339       if (unformat (i, "spd_id %d", &spd_id))
13340         ;
13341       else if (unformat (i, "del"))
13342         is_add = 0;
13343       else
13344         {
13345           clib_warning ("parse error '%U'", format_unformat_error, i);
13346           return -99;
13347         }
13348     }
13349   if (spd_id == ~0)
13350     {
13351       errmsg ("spd_id must be set");
13352       return -99;
13353     }
13354
13355   M (IPSEC_SPD_ADD_DEL, mp);
13356
13357   mp->spd_id = ntohl (spd_id);
13358   mp->is_add = is_add;
13359
13360   S (mp);
13361   W (ret);
13362   return ret;
13363 }
13364
13365 static int
13366 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13367 {
13368   unformat_input_t *i = vam->input;
13369   vl_api_ipsec_interface_add_del_spd_t *mp;
13370   u32 sw_if_index;
13371   u8 sw_if_index_set = 0;
13372   u32 spd_id = (u32) ~ 0;
13373   u8 is_add = 1;
13374   int ret;
13375
13376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13377     {
13378       if (unformat (i, "del"))
13379         is_add = 0;
13380       else if (unformat (i, "spd_id %d", &spd_id))
13381         ;
13382       else
13383         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13384         sw_if_index_set = 1;
13385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13386         sw_if_index_set = 1;
13387       else
13388         {
13389           clib_warning ("parse error '%U'", format_unformat_error, i);
13390           return -99;
13391         }
13392
13393     }
13394
13395   if (spd_id == (u32) ~ 0)
13396     {
13397       errmsg ("spd_id must be set");
13398       return -99;
13399     }
13400
13401   if (sw_if_index_set == 0)
13402     {
13403       errmsg ("missing interface name or sw_if_index");
13404       return -99;
13405     }
13406
13407   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13408
13409   mp->spd_id = ntohl (spd_id);
13410   mp->sw_if_index = ntohl (sw_if_index);
13411   mp->is_add = is_add;
13412
13413   S (mp);
13414   W (ret);
13415   return ret;
13416 }
13417
13418 static int
13419 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13420 {
13421   unformat_input_t *i = vam->input;
13422   vl_api_ipsec_spd_entry_add_del_t *mp;
13423   u8 is_add = 1, is_outbound = 0;
13424   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13425   i32 priority = 0;
13426   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13427   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13428   vl_api_address_t laddr_start = { }, laddr_stop =
13429   {
13430   }, raddr_start =
13431   {
13432   }, raddr_stop =
13433   {
13434   };
13435   int ret;
13436
13437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13438     {
13439       if (unformat (i, "del"))
13440         is_add = 0;
13441       if (unformat (i, "outbound"))
13442         is_outbound = 1;
13443       if (unformat (i, "inbound"))
13444         is_outbound = 0;
13445       else if (unformat (i, "spd_id %d", &spd_id))
13446         ;
13447       else if (unformat (i, "sa_id %d", &sa_id))
13448         ;
13449       else if (unformat (i, "priority %d", &priority))
13450         ;
13451       else if (unformat (i, "protocol %d", &protocol))
13452         ;
13453       else if (unformat (i, "lport_start %d", &lport_start))
13454         ;
13455       else if (unformat (i, "lport_stop %d", &lport_stop))
13456         ;
13457       else if (unformat (i, "rport_start %d", &rport_start))
13458         ;
13459       else if (unformat (i, "rport_stop %d", &rport_stop))
13460         ;
13461       else if (unformat (i, "laddr_start %U",
13462                          unformat_vl_api_address, &laddr_start))
13463         ;
13464       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13465                          &laddr_stop))
13466         ;
13467       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13468                          &raddr_start))
13469         ;
13470       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13471                          &raddr_stop))
13472         ;
13473       else
13474         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13475         {
13476           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13477             {
13478               clib_warning ("unsupported action: 'resolve'");
13479               return -99;
13480             }
13481         }
13482       else
13483         {
13484           clib_warning ("parse error '%U'", format_unformat_error, i);
13485           return -99;
13486         }
13487
13488     }
13489
13490   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13491
13492   mp->is_add = is_add;
13493
13494   mp->entry.spd_id = ntohl (spd_id);
13495   mp->entry.priority = ntohl (priority);
13496   mp->entry.is_outbound = is_outbound;
13497
13498   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13499                sizeof (vl_api_address_t));
13500   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13501                sizeof (vl_api_address_t));
13502   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13503                sizeof (vl_api_address_t));
13504   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13505                sizeof (vl_api_address_t));
13506
13507   mp->entry.protocol = (u8) protocol;
13508   mp->entry.local_port_start = ntohs ((u16) lport_start);
13509   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13510   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13511   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13512   mp->entry.policy = (u8) policy;
13513   mp->entry.sa_id = ntohl (sa_id);
13514
13515   S (mp);
13516   W (ret);
13517   return ret;
13518 }
13519
13520 static int
13521 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13522 {
13523   unformat_input_t *i = vam->input;
13524   vl_api_ipsec_sad_entry_add_del_t *mp;
13525   u32 sad_id = 0, spi = 0;
13526   u8 *ck = 0, *ik = 0;
13527   u8 is_add = 1;
13528
13529   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13530   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13531   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13532   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13533   vl_api_address_t tun_src, tun_dst;
13534   int ret;
13535
13536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13537     {
13538       if (unformat (i, "del"))
13539         is_add = 0;
13540       else if (unformat (i, "sad_id %d", &sad_id))
13541         ;
13542       else if (unformat (i, "spi %d", &spi))
13543         ;
13544       else if (unformat (i, "esp"))
13545         protocol = IPSEC_API_PROTO_ESP;
13546       else
13547         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13548         {
13549           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13550           if (ADDRESS_IP6 == tun_src.af)
13551             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13552         }
13553       else
13554         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13555         {
13556           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13557           if (ADDRESS_IP6 == tun_src.af)
13558             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13559         }
13560       else
13561         if (unformat (i, "crypto_alg %U",
13562                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13563         ;
13564       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13565         ;
13566       else if (unformat (i, "integ_alg %U",
13567                          unformat_ipsec_api_integ_alg, &integ_alg))
13568         ;
13569       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13570         ;
13571       else
13572         {
13573           clib_warning ("parse error '%U'", format_unformat_error, i);
13574           return -99;
13575         }
13576
13577     }
13578
13579   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13580
13581   mp->is_add = is_add;
13582   mp->entry.sad_id = ntohl (sad_id);
13583   mp->entry.protocol = protocol;
13584   mp->entry.spi = ntohl (spi);
13585   mp->entry.flags = flags;
13586
13587   mp->entry.crypto_algorithm = crypto_alg;
13588   mp->entry.integrity_algorithm = integ_alg;
13589   mp->entry.crypto_key.length = vec_len (ck);
13590   mp->entry.integrity_key.length = vec_len (ik);
13591
13592   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13593     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13594
13595   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13596     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13597
13598   if (ck)
13599     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13600   if (ik)
13601     clib_memcpy (mp->entry.integrity_key.data, ik,
13602                  mp->entry.integrity_key.length);
13603
13604   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13605     {
13606       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13607                    sizeof (mp->entry.tunnel_src));
13608       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13609                    sizeof (mp->entry.tunnel_dst));
13610     }
13611
13612   S (mp);
13613   W (ret);
13614   return ret;
13615 }
13616
13617 static int
13618 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13619 {
13620   unformat_input_t *i = vam->input;
13621   vl_api_ipsec_tunnel_if_add_del_t *mp;
13622   u32 local_spi = 0, remote_spi = 0;
13623   u32 crypto_alg = 0, integ_alg = 0;
13624   u8 *lck = NULL, *rck = NULL;
13625   u8 *lik = NULL, *rik = NULL;
13626   vl_api_address_t local_ip = { 0 };
13627   vl_api_address_t remote_ip = { 0 };
13628   f64 before = 0;
13629   u8 is_add = 1;
13630   u8 esn = 0;
13631   u8 anti_replay = 0;
13632   u8 renumber = 0;
13633   u32 instance = ~0;
13634   u32 count = 1, jj;
13635   int ret = -1;
13636
13637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13638     {
13639       if (unformat (i, "del"))
13640         is_add = 0;
13641       else if (unformat (i, "esn"))
13642         esn = 1;
13643       else if (unformat (i, "anti-replay"))
13644         anti_replay = 1;
13645       else if (unformat (i, "count %d", &count))
13646         ;
13647       else if (unformat (i, "local_spi %d", &local_spi))
13648         ;
13649       else if (unformat (i, "remote_spi %d", &remote_spi))
13650         ;
13651       else
13652         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13653         ;
13654       else
13655         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13656         ;
13657       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13658         ;
13659       else
13660         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13661         ;
13662       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13663         ;
13664       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13665         ;
13666       else
13667         if (unformat
13668             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13669         {
13670           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13671             {
13672               errmsg ("unsupported crypto-alg: '%U'\n",
13673                       format_ipsec_crypto_alg, crypto_alg);
13674               return -99;
13675             }
13676         }
13677       else
13678         if (unformat
13679             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13680         {
13681           if (integ_alg >= IPSEC_INTEG_N_ALG)
13682             {
13683               errmsg ("unsupported integ-alg: '%U'\n",
13684                       format_ipsec_integ_alg, integ_alg);
13685               return -99;
13686             }
13687         }
13688       else if (unformat (i, "instance %u", &instance))
13689         renumber = 1;
13690       else
13691         {
13692           errmsg ("parse error '%U'\n", format_unformat_error, i);
13693           return -99;
13694         }
13695     }
13696
13697   if (count > 1)
13698     {
13699       /* Turn on async mode */
13700       vam->async_mode = 1;
13701       vam->async_errors = 0;
13702       before = vat_time_now (vam);
13703     }
13704
13705   for (jj = 0; jj < count; jj++)
13706     {
13707       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13708
13709       mp->is_add = is_add;
13710       mp->esn = esn;
13711       mp->anti_replay = anti_replay;
13712
13713       if (jj > 0)
13714         increment_address (&remote_ip);
13715
13716       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13717       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13718
13719       mp->local_spi = htonl (local_spi + jj);
13720       mp->remote_spi = htonl (remote_spi + jj);
13721       mp->crypto_alg = (u8) crypto_alg;
13722
13723       mp->local_crypto_key_len = 0;
13724       if (lck)
13725         {
13726           mp->local_crypto_key_len = vec_len (lck);
13727           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13728             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13729           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13730         }
13731
13732       mp->remote_crypto_key_len = 0;
13733       if (rck)
13734         {
13735           mp->remote_crypto_key_len = vec_len (rck);
13736           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13737             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13738           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13739         }
13740
13741       mp->integ_alg = (u8) integ_alg;
13742
13743       mp->local_integ_key_len = 0;
13744       if (lik)
13745         {
13746           mp->local_integ_key_len = vec_len (lik);
13747           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13748             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13749           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13750         }
13751
13752       mp->remote_integ_key_len = 0;
13753       if (rik)
13754         {
13755           mp->remote_integ_key_len = vec_len (rik);
13756           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13757             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13758           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13759         }
13760
13761       if (renumber)
13762         {
13763           mp->renumber = renumber;
13764           mp->show_instance = ntohl (instance);
13765         }
13766       S (mp);
13767     }
13768
13769   /* When testing multiple add/del ops, use a control-ping to sync */
13770   if (count > 1)
13771     {
13772       vl_api_control_ping_t *mp_ping;
13773       f64 after;
13774       f64 timeout;
13775
13776       /* Shut off async mode */
13777       vam->async_mode = 0;
13778
13779       MPING (CONTROL_PING, mp_ping);
13780       S (mp_ping);
13781
13782       timeout = vat_time_now (vam) + 1.0;
13783       while (vat_time_now (vam) < timeout)
13784         if (vam->result_ready == 1)
13785           goto out;
13786       vam->retval = -99;
13787
13788     out:
13789       if (vam->retval == -99)
13790         errmsg ("timeout");
13791
13792       if (vam->async_errors > 0)
13793         {
13794           errmsg ("%d asynchronous errors", vam->async_errors);
13795           vam->retval = -98;
13796         }
13797       vam->async_errors = 0;
13798       after = vat_time_now (vam);
13799
13800       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13801       if (jj > 0)
13802         count = jj;
13803
13804       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13805              count, after - before, count / (after - before));
13806     }
13807   else
13808     {
13809       /* Wait for a reply... */
13810       W (ret);
13811       return ret;
13812     }
13813
13814   return ret;
13815 }
13816
13817 static void
13818 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13819 {
13820   vat_main_t *vam = &vat_main;
13821
13822   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13823          "crypto_key %U integ_alg %u integ_key %U flags %x "
13824          "tunnel_src_addr %U tunnel_dst_addr %U "
13825          "salt %u seq_outbound %lu last_seq_inbound %lu "
13826          "replay_window %lu stat_index %u\n",
13827          ntohl (mp->entry.sad_id),
13828          ntohl (mp->sw_if_index),
13829          ntohl (mp->entry.spi),
13830          ntohl (mp->entry.protocol),
13831          ntohl (mp->entry.crypto_algorithm),
13832          format_hex_bytes, mp->entry.crypto_key.data,
13833          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13834          format_hex_bytes, mp->entry.integrity_key.data,
13835          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13836          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13837          &mp->entry.tunnel_dst, ntohl (mp->salt),
13838          clib_net_to_host_u64 (mp->seq_outbound),
13839          clib_net_to_host_u64 (mp->last_seq_inbound),
13840          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13841 }
13842
13843 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13844 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13845
13846 static void vl_api_ipsec_sa_details_t_handler_json
13847   (vl_api_ipsec_sa_details_t * mp)
13848 {
13849   vat_main_t *vam = &vat_main;
13850   vat_json_node_t *node = NULL;
13851   vl_api_ipsec_sad_flags_t flags;
13852
13853   if (VAT_JSON_ARRAY != vam->json_tree.type)
13854     {
13855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13856       vat_json_init_array (&vam->json_tree);
13857     }
13858   node = vat_json_array_add (&vam->json_tree);
13859
13860   vat_json_init_object (node);
13861   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13863   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13864   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13865   vat_json_object_add_uint (node, "crypto_alg",
13866                             ntohl (mp->entry.crypto_algorithm));
13867   vat_json_object_add_uint (node, "integ_alg",
13868                             ntohl (mp->entry.integrity_algorithm));
13869   flags = ntohl (mp->entry.flags);
13870   vat_json_object_add_uint (node, "use_esn",
13871                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13872   vat_json_object_add_uint (node, "use_anti_replay",
13873                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13874   vat_json_object_add_uint (node, "is_tunnel",
13875                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13876   vat_json_object_add_uint (node, "is_tunnel_ip6",
13877                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13878   vat_json_object_add_uint (node, "udp_encap",
13879                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13880   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13881                              mp->entry.crypto_key.length);
13882   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13883                              mp->entry.integrity_key.length);
13884   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13885   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13886   vat_json_object_add_uint (node, "replay_window",
13887                             clib_net_to_host_u64 (mp->replay_window));
13888   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13889 }
13890
13891 static int
13892 api_ipsec_sa_dump (vat_main_t * vam)
13893 {
13894   unformat_input_t *i = vam->input;
13895   vl_api_ipsec_sa_dump_t *mp;
13896   vl_api_control_ping_t *mp_ping;
13897   u32 sa_id = ~0;
13898   int ret;
13899
13900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13901     {
13902       if (unformat (i, "sa_id %d", &sa_id))
13903         ;
13904       else
13905         {
13906           clib_warning ("parse error '%U'", format_unformat_error, i);
13907           return -99;
13908         }
13909     }
13910
13911   M (IPSEC_SA_DUMP, mp);
13912
13913   mp->sa_id = ntohl (sa_id);
13914
13915   S (mp);
13916
13917   /* Use a control ping for synchronization */
13918   M (CONTROL_PING, mp_ping);
13919   S (mp_ping);
13920
13921   W (ret);
13922   return ret;
13923 }
13924
13925 static int
13926 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13927 {
13928   unformat_input_t *i = vam->input;
13929   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13930   u32 sw_if_index = ~0;
13931   u32 sa_id = ~0;
13932   u8 is_outbound = (u8) ~ 0;
13933   int ret;
13934
13935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13936     {
13937       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13938         ;
13939       else if (unformat (i, "sa_id %d", &sa_id))
13940         ;
13941       else if (unformat (i, "outbound"))
13942         is_outbound = 1;
13943       else if (unformat (i, "inbound"))
13944         is_outbound = 0;
13945       else
13946         {
13947           clib_warning ("parse error '%U'", format_unformat_error, i);
13948           return -99;
13949         }
13950     }
13951
13952   if (sw_if_index == ~0)
13953     {
13954       errmsg ("interface must be specified");
13955       return -99;
13956     }
13957
13958   if (sa_id == ~0)
13959     {
13960       errmsg ("SA ID must be specified");
13961       return -99;
13962     }
13963
13964   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13965
13966   mp->sw_if_index = htonl (sw_if_index);
13967   mp->sa_id = htonl (sa_id);
13968   mp->is_outbound = is_outbound;
13969
13970   S (mp);
13971   W (ret);
13972
13973   return ret;
13974 }
13975
13976 static int
13977 api_get_first_msg_id (vat_main_t * vam)
13978 {
13979   vl_api_get_first_msg_id_t *mp;
13980   unformat_input_t *i = vam->input;
13981   u8 *name;
13982   u8 name_set = 0;
13983   int ret;
13984
13985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13986     {
13987       if (unformat (i, "client %s", &name))
13988         name_set = 1;
13989       else
13990         break;
13991     }
13992
13993   if (name_set == 0)
13994     {
13995       errmsg ("missing client name");
13996       return -99;
13997     }
13998   vec_add1 (name, 0);
13999
14000   if (vec_len (name) > 63)
14001     {
14002       errmsg ("client name too long");
14003       return -99;
14004     }
14005
14006   M (GET_FIRST_MSG_ID, mp);
14007   clib_memcpy (mp->name, name, vec_len (name));
14008   S (mp);
14009   W (ret);
14010   return ret;
14011 }
14012
14013 static int
14014 api_cop_interface_enable_disable (vat_main_t * vam)
14015 {
14016   unformat_input_t *line_input = vam->input;
14017   vl_api_cop_interface_enable_disable_t *mp;
14018   u32 sw_if_index = ~0;
14019   u8 enable_disable = 1;
14020   int ret;
14021
14022   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14023     {
14024       if (unformat (line_input, "disable"))
14025         enable_disable = 0;
14026       if (unformat (line_input, "enable"))
14027         enable_disable = 1;
14028       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14029                          vam, &sw_if_index))
14030         ;
14031       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14032         ;
14033       else
14034         break;
14035     }
14036
14037   if (sw_if_index == ~0)
14038     {
14039       errmsg ("missing interface name or sw_if_index");
14040       return -99;
14041     }
14042
14043   /* Construct the API message */
14044   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14045   mp->sw_if_index = ntohl (sw_if_index);
14046   mp->enable_disable = enable_disable;
14047
14048   /* send it... */
14049   S (mp);
14050   /* Wait for the reply */
14051   W (ret);
14052   return ret;
14053 }
14054
14055 static int
14056 api_cop_whitelist_enable_disable (vat_main_t * vam)
14057 {
14058   unformat_input_t *line_input = vam->input;
14059   vl_api_cop_whitelist_enable_disable_t *mp;
14060   u32 sw_if_index = ~0;
14061   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14062   u32 fib_id = 0;
14063   int ret;
14064
14065   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14066     {
14067       if (unformat (line_input, "ip4"))
14068         ip4 = 1;
14069       else if (unformat (line_input, "ip6"))
14070         ip6 = 1;
14071       else if (unformat (line_input, "default"))
14072         default_cop = 1;
14073       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14074                          vam, &sw_if_index))
14075         ;
14076       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14077         ;
14078       else if (unformat (line_input, "fib-id %d", &fib_id))
14079         ;
14080       else
14081         break;
14082     }
14083
14084   if (sw_if_index == ~0)
14085     {
14086       errmsg ("missing interface name or sw_if_index");
14087       return -99;
14088     }
14089
14090   /* Construct the API message */
14091   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14092   mp->sw_if_index = ntohl (sw_if_index);
14093   mp->fib_id = ntohl (fib_id);
14094   mp->ip4 = ip4;
14095   mp->ip6 = ip6;
14096   mp->default_cop = default_cop;
14097
14098   /* send it... */
14099   S (mp);
14100   /* Wait for the reply */
14101   W (ret);
14102   return ret;
14103 }
14104
14105 static int
14106 api_get_node_graph (vat_main_t * vam)
14107 {
14108   vl_api_get_node_graph_t *mp;
14109   int ret;
14110
14111   M (GET_NODE_GRAPH, mp);
14112
14113   /* send it... */
14114   S (mp);
14115   /* Wait for the reply */
14116   W (ret);
14117   return ret;
14118 }
14119
14120 /* *INDENT-OFF* */
14121 /** Used for parsing LISP eids */
14122 typedef CLIB_PACKED(struct{
14123   union {
14124           ip46_address_t ip;
14125           mac_address_t mac;
14126           lisp_nsh_api_t nsh;
14127   } addr;
14128   u32 len;       /**< prefix length if IP */
14129   u8 type;      /**< type of eid */
14130 }) lisp_eid_vat_t;
14131 /* *INDENT-ON* */
14132
14133 static uword
14134 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14135 {
14136   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14137
14138   clib_memset (a, 0, sizeof (a[0]));
14139
14140   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14141     {
14142       a->type = 0;              /* ip prefix type */
14143     }
14144   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14145     {
14146       a->type = 1;              /* mac type */
14147     }
14148   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14149     {
14150       a->type = 2;              /* NSH type */
14151       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14152     }
14153   else
14154     {
14155       return 0;
14156     }
14157
14158   if (a->type == 0)
14159     {
14160       if (ip46_address_is_ip4 (&a->addr.ip))
14161         return a->len > 32 ? 1 : 0;
14162       else
14163         return a->len > 128 ? 1 : 0;
14164     }
14165
14166   return 1;
14167 }
14168
14169 static void
14170 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14171 {
14172   eid->type = vat_eid->type;
14173   switch (eid->type)
14174     {
14175     case EID_TYPE_API_PREFIX:
14176       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14177         {
14178           clib_memcpy (&eid->address.prefix.address.un.ip4,
14179                        &vat_eid->addr.ip.ip4, 4);
14180           eid->address.prefix.address.af = ADDRESS_IP4;
14181           eid->address.prefix.len = vat_eid->len;
14182         }
14183       else
14184         {
14185           clib_memcpy (&eid->address.prefix.address.un.ip6,
14186                        &vat_eid->addr.ip.ip6, 16);
14187           eid->address.prefix.address.af = ADDRESS_IP6;
14188           eid->address.prefix.len = vat_eid->len;
14189         }
14190       return;
14191     case EID_TYPE_API_MAC:
14192       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14193                    sizeof (eid->address.mac));
14194       return;
14195     case EID_TYPE_API_NSH:
14196       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14197                    sizeof (eid->address.nsh));
14198       return;
14199     default:
14200       ASSERT (0);
14201       return;
14202     }
14203 }
14204
14205 static int
14206 api_one_add_del_locator_set (vat_main_t * vam)
14207 {
14208   unformat_input_t *input = vam->input;
14209   vl_api_one_add_del_locator_set_t *mp;
14210   u8 is_add = 1;
14211   u8 *locator_set_name = NULL;
14212   u8 locator_set_name_set = 0;
14213   vl_api_local_locator_t locator, *locators = 0;
14214   u32 sw_if_index, priority, weight;
14215   u32 data_len = 0;
14216
14217   int ret;
14218   /* Parse args required to build the message */
14219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14220     {
14221       if (unformat (input, "del"))
14222         {
14223           is_add = 0;
14224         }
14225       else if (unformat (input, "locator-set %s", &locator_set_name))
14226         {
14227           locator_set_name_set = 1;
14228         }
14229       else if (unformat (input, "sw_if_index %u p %u w %u",
14230                          &sw_if_index, &priority, &weight))
14231         {
14232           locator.sw_if_index = htonl (sw_if_index);
14233           locator.priority = priority;
14234           locator.weight = weight;
14235           vec_add1 (locators, locator);
14236         }
14237       else
14238         if (unformat
14239             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14240              &sw_if_index, &priority, &weight))
14241         {
14242           locator.sw_if_index = htonl (sw_if_index);
14243           locator.priority = priority;
14244           locator.weight = weight;
14245           vec_add1 (locators, locator);
14246         }
14247       else
14248         break;
14249     }
14250
14251   if (locator_set_name_set == 0)
14252     {
14253       errmsg ("missing locator-set name");
14254       vec_free (locators);
14255       return -99;
14256     }
14257
14258   if (vec_len (locator_set_name) > 64)
14259     {
14260       errmsg ("locator-set name too long");
14261       vec_free (locator_set_name);
14262       vec_free (locators);
14263       return -99;
14264     }
14265   vec_add1 (locator_set_name, 0);
14266
14267   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14268
14269   /* Construct the API message */
14270   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14271
14272   mp->is_add = is_add;
14273   clib_memcpy (mp->locator_set_name, locator_set_name,
14274                vec_len (locator_set_name));
14275   vec_free (locator_set_name);
14276
14277   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14278   if (locators)
14279     clib_memcpy (mp->locators, locators, data_len);
14280   vec_free (locators);
14281
14282   /* send it... */
14283   S (mp);
14284
14285   /* Wait for a reply... */
14286   W (ret);
14287   return ret;
14288 }
14289
14290 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14291
14292 static int
14293 api_one_add_del_locator (vat_main_t * vam)
14294 {
14295   unformat_input_t *input = vam->input;
14296   vl_api_one_add_del_locator_t *mp;
14297   u32 tmp_if_index = ~0;
14298   u32 sw_if_index = ~0;
14299   u8 sw_if_index_set = 0;
14300   u8 sw_if_index_if_name_set = 0;
14301   u32 priority = ~0;
14302   u8 priority_set = 0;
14303   u32 weight = ~0;
14304   u8 weight_set = 0;
14305   u8 is_add = 1;
14306   u8 *locator_set_name = NULL;
14307   u8 locator_set_name_set = 0;
14308   int ret;
14309
14310   /* Parse args required to build the message */
14311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14312     {
14313       if (unformat (input, "del"))
14314         {
14315           is_add = 0;
14316         }
14317       else if (unformat (input, "locator-set %s", &locator_set_name))
14318         {
14319           locator_set_name_set = 1;
14320         }
14321       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14322                          &tmp_if_index))
14323         {
14324           sw_if_index_if_name_set = 1;
14325           sw_if_index = tmp_if_index;
14326         }
14327       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14328         {
14329           sw_if_index_set = 1;
14330           sw_if_index = tmp_if_index;
14331         }
14332       else if (unformat (input, "p %d", &priority))
14333         {
14334           priority_set = 1;
14335         }
14336       else if (unformat (input, "w %d", &weight))
14337         {
14338           weight_set = 1;
14339         }
14340       else
14341         break;
14342     }
14343
14344   if (locator_set_name_set == 0)
14345     {
14346       errmsg ("missing locator-set name");
14347       return -99;
14348     }
14349
14350   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14351     {
14352       errmsg ("missing sw_if_index");
14353       vec_free (locator_set_name);
14354       return -99;
14355     }
14356
14357   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14358     {
14359       errmsg ("cannot use both params interface name and sw_if_index");
14360       vec_free (locator_set_name);
14361       return -99;
14362     }
14363
14364   if (priority_set == 0)
14365     {
14366       errmsg ("missing locator-set priority");
14367       vec_free (locator_set_name);
14368       return -99;
14369     }
14370
14371   if (weight_set == 0)
14372     {
14373       errmsg ("missing locator-set weight");
14374       vec_free (locator_set_name);
14375       return -99;
14376     }
14377
14378   if (vec_len (locator_set_name) > 64)
14379     {
14380       errmsg ("locator-set name too long");
14381       vec_free (locator_set_name);
14382       return -99;
14383     }
14384   vec_add1 (locator_set_name, 0);
14385
14386   /* Construct the API message */
14387   M (ONE_ADD_DEL_LOCATOR, mp);
14388
14389   mp->is_add = is_add;
14390   mp->sw_if_index = ntohl (sw_if_index);
14391   mp->priority = priority;
14392   mp->weight = weight;
14393   clib_memcpy (mp->locator_set_name, locator_set_name,
14394                vec_len (locator_set_name));
14395   vec_free (locator_set_name);
14396
14397   /* send it... */
14398   S (mp);
14399
14400   /* Wait for a reply... */
14401   W (ret);
14402   return ret;
14403 }
14404
14405 #define api_lisp_add_del_locator api_one_add_del_locator
14406
14407 uword
14408 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14409 {
14410   u32 *key_id = va_arg (*args, u32 *);
14411   u8 *s = 0;
14412
14413   if (unformat (input, "%s", &s))
14414     {
14415       if (!strcmp ((char *) s, "sha1"))
14416         key_id[0] = HMAC_SHA_1_96;
14417       else if (!strcmp ((char *) s, "sha256"))
14418         key_id[0] = HMAC_SHA_256_128;
14419       else
14420         {
14421           clib_warning ("invalid key_id: '%s'", s);
14422           key_id[0] = HMAC_NO_KEY;
14423         }
14424     }
14425   else
14426     return 0;
14427
14428   vec_free (s);
14429   return 1;
14430 }
14431
14432 static int
14433 api_one_add_del_local_eid (vat_main_t * vam)
14434 {
14435   unformat_input_t *input = vam->input;
14436   vl_api_one_add_del_local_eid_t *mp;
14437   u8 is_add = 1;
14438   u8 eid_set = 0;
14439   lisp_eid_vat_t _eid, *eid = &_eid;
14440   u8 *locator_set_name = 0;
14441   u8 locator_set_name_set = 0;
14442   u32 vni = 0;
14443   u16 key_id = 0;
14444   u8 *key = 0;
14445   int ret;
14446
14447   /* Parse args required to build the message */
14448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14449     {
14450       if (unformat (input, "del"))
14451         {
14452           is_add = 0;
14453         }
14454       else if (unformat (input, "vni %d", &vni))
14455         {
14456           ;
14457         }
14458       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14459         {
14460           eid_set = 1;
14461         }
14462       else if (unformat (input, "locator-set %s", &locator_set_name))
14463         {
14464           locator_set_name_set = 1;
14465         }
14466       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14467         ;
14468       else if (unformat (input, "secret-key %_%v%_", &key))
14469         ;
14470       else
14471         break;
14472     }
14473
14474   if (locator_set_name_set == 0)
14475     {
14476       errmsg ("missing locator-set name");
14477       return -99;
14478     }
14479
14480   if (0 == eid_set)
14481     {
14482       errmsg ("EID address not set!");
14483       vec_free (locator_set_name);
14484       return -99;
14485     }
14486
14487   if (key && (0 == key_id))
14488     {
14489       errmsg ("invalid key_id!");
14490       return -99;
14491     }
14492
14493   if (vec_len (key) > 64)
14494     {
14495       errmsg ("key too long");
14496       vec_free (key);
14497       return -99;
14498     }
14499
14500   if (vec_len (locator_set_name) > 64)
14501     {
14502       errmsg ("locator-set name too long");
14503       vec_free (locator_set_name);
14504       return -99;
14505     }
14506   vec_add1 (locator_set_name, 0);
14507
14508   /* Construct the API message */
14509   M (ONE_ADD_DEL_LOCAL_EID, mp);
14510
14511   mp->is_add = is_add;
14512   lisp_eid_put_vat (&mp->eid, eid);
14513   mp->vni = clib_host_to_net_u32 (vni);
14514   mp->key.id = key_id;
14515   clib_memcpy (mp->locator_set_name, locator_set_name,
14516                vec_len (locator_set_name));
14517   clib_memcpy (mp->key.key, key, vec_len (key));
14518
14519   vec_free (locator_set_name);
14520   vec_free (key);
14521
14522   /* send it... */
14523   S (mp);
14524
14525   /* Wait for a reply... */
14526   W (ret);
14527   return ret;
14528 }
14529
14530 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14531
14532 static int
14533 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14534 {
14535   u32 dp_table = 0, vni = 0;;
14536   unformat_input_t *input = vam->input;
14537   vl_api_gpe_add_del_fwd_entry_t *mp;
14538   u8 is_add = 1;
14539   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14540   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14541   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14542   u32 action = ~0, w;
14543   ip4_address_t rmt_rloc4, lcl_rloc4;
14544   ip6_address_t rmt_rloc6, lcl_rloc6;
14545   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14546   int ret;
14547
14548   clib_memset (&rloc, 0, sizeof (rloc));
14549
14550   /* Parse args required to build the message */
14551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14552     {
14553       if (unformat (input, "del"))
14554         is_add = 0;
14555       else if (unformat (input, "add"))
14556         is_add = 1;
14557       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14558         {
14559           rmt_eid_set = 1;
14560         }
14561       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14562         {
14563           lcl_eid_set = 1;
14564         }
14565       else if (unformat (input, "vrf %d", &dp_table))
14566         ;
14567       else if (unformat (input, "bd %d", &dp_table))
14568         ;
14569       else if (unformat (input, "vni %d", &vni))
14570         ;
14571       else if (unformat (input, "w %d", &w))
14572         {
14573           if (!curr_rloc)
14574             {
14575               errmsg ("No RLOC configured for setting priority/weight!");
14576               return -99;
14577             }
14578           curr_rloc->weight = w;
14579         }
14580       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14581                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14582         {
14583           rloc.addr.af = 0;
14584           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14585           rloc.weight = 0;
14586           vec_add1 (lcl_locs, rloc);
14587
14588           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14589           vec_add1 (rmt_locs, rloc);
14590           /* weight saved in rmt loc */
14591           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14592         }
14593       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14594                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14595         {
14596           rloc.addr.af = 1;
14597           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14598           rloc.weight = 0;
14599           vec_add1 (lcl_locs, rloc);
14600
14601           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14602           vec_add1 (rmt_locs, rloc);
14603           /* weight saved in rmt loc */
14604           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14605         }
14606       else if (unformat (input, "action %d", &action))
14607         {
14608           ;
14609         }
14610       else
14611         {
14612           clib_warning ("parse error '%U'", format_unformat_error, input);
14613           return -99;
14614         }
14615     }
14616
14617   if (!rmt_eid_set)
14618     {
14619       errmsg ("remote eid addresses not set");
14620       return -99;
14621     }
14622
14623   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14624     {
14625       errmsg ("eid types don't match");
14626       return -99;
14627     }
14628
14629   if (0 == rmt_locs && (u32) ~ 0 == action)
14630     {
14631       errmsg ("action not set for negative mapping");
14632       return -99;
14633     }
14634
14635   /* Construct the API message */
14636   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14637       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14638
14639   mp->is_add = is_add;
14640   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14641   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14642   mp->dp_table = clib_host_to_net_u32 (dp_table);
14643   mp->vni = clib_host_to_net_u32 (vni);
14644   mp->action = action;
14645
14646   if (0 != rmt_locs && 0 != lcl_locs)
14647     {
14648       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14649       clib_memcpy (mp->locs, lcl_locs,
14650                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14651
14652       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14653       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14654                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14655     }
14656   vec_free (lcl_locs);
14657   vec_free (rmt_locs);
14658
14659   /* send it... */
14660   S (mp);
14661
14662   /* Wait for a reply... */
14663   W (ret);
14664   return ret;
14665 }
14666
14667 static int
14668 api_one_add_del_map_server (vat_main_t * vam)
14669 {
14670   unformat_input_t *input = vam->input;
14671   vl_api_one_add_del_map_server_t *mp;
14672   u8 is_add = 1;
14673   u8 ipv4_set = 0;
14674   u8 ipv6_set = 0;
14675   ip4_address_t ipv4;
14676   ip6_address_t ipv6;
14677   int ret;
14678
14679   /* Parse args required to build the message */
14680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14681     {
14682       if (unformat (input, "del"))
14683         {
14684           is_add = 0;
14685         }
14686       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14687         {
14688           ipv4_set = 1;
14689         }
14690       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14691         {
14692           ipv6_set = 1;
14693         }
14694       else
14695         break;
14696     }
14697
14698   if (ipv4_set && ipv6_set)
14699     {
14700       errmsg ("both eid v4 and v6 addresses set");
14701       return -99;
14702     }
14703
14704   if (!ipv4_set && !ipv6_set)
14705     {
14706       errmsg ("eid addresses not set");
14707       return -99;
14708     }
14709
14710   /* Construct the API message */
14711   M (ONE_ADD_DEL_MAP_SERVER, mp);
14712
14713   mp->is_add = is_add;
14714   if (ipv6_set)
14715     {
14716       mp->ip_address.af = 1;
14717       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14718     }
14719   else
14720     {
14721       mp->ip_address.af = 0;
14722       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14723     }
14724
14725   /* send it... */
14726   S (mp);
14727
14728   /* Wait for a reply... */
14729   W (ret);
14730   return ret;
14731 }
14732
14733 #define api_lisp_add_del_map_server api_one_add_del_map_server
14734
14735 static int
14736 api_one_add_del_map_resolver (vat_main_t * vam)
14737 {
14738   unformat_input_t *input = vam->input;
14739   vl_api_one_add_del_map_resolver_t *mp;
14740   u8 is_add = 1;
14741   u8 ipv4_set = 0;
14742   u8 ipv6_set = 0;
14743   ip4_address_t ipv4;
14744   ip6_address_t ipv6;
14745   int ret;
14746
14747   /* Parse args required to build the message */
14748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14749     {
14750       if (unformat (input, "del"))
14751         {
14752           is_add = 0;
14753         }
14754       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14755         {
14756           ipv4_set = 1;
14757         }
14758       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14759         {
14760           ipv6_set = 1;
14761         }
14762       else
14763         break;
14764     }
14765
14766   if (ipv4_set && ipv6_set)
14767     {
14768       errmsg ("both eid v4 and v6 addresses set");
14769       return -99;
14770     }
14771
14772   if (!ipv4_set && !ipv6_set)
14773     {
14774       errmsg ("eid addresses not set");
14775       return -99;
14776     }
14777
14778   /* Construct the API message */
14779   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14780
14781   mp->is_add = is_add;
14782   if (ipv6_set)
14783     {
14784       mp->ip_address.af = 1;
14785       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14786     }
14787   else
14788     {
14789       mp->ip_address.af = 0;
14790       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14791     }
14792
14793   /* send it... */
14794   S (mp);
14795
14796   /* Wait for a reply... */
14797   W (ret);
14798   return ret;
14799 }
14800
14801 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14802
14803 static int
14804 api_lisp_gpe_enable_disable (vat_main_t * vam)
14805 {
14806   unformat_input_t *input = vam->input;
14807   vl_api_gpe_enable_disable_t *mp;
14808   u8 is_set = 0;
14809   u8 is_enable = 1;
14810   int ret;
14811
14812   /* Parse args required to build the message */
14813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14814     {
14815       if (unformat (input, "enable"))
14816         {
14817           is_set = 1;
14818           is_enable = 1;
14819         }
14820       else if (unformat (input, "disable"))
14821         {
14822           is_set = 1;
14823           is_enable = 0;
14824         }
14825       else
14826         break;
14827     }
14828
14829   if (is_set == 0)
14830     {
14831       errmsg ("Value not set");
14832       return -99;
14833     }
14834
14835   /* Construct the API message */
14836   M (GPE_ENABLE_DISABLE, mp);
14837
14838   mp->is_enable = is_enable;
14839
14840   /* send it... */
14841   S (mp);
14842
14843   /* Wait for a reply... */
14844   W (ret);
14845   return ret;
14846 }
14847
14848 static int
14849 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14850 {
14851   unformat_input_t *input = vam->input;
14852   vl_api_one_rloc_probe_enable_disable_t *mp;
14853   u8 is_set = 0;
14854   u8 is_enable = 0;
14855   int ret;
14856
14857   /* Parse args required to build the message */
14858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14859     {
14860       if (unformat (input, "enable"))
14861         {
14862           is_set = 1;
14863           is_enable = 1;
14864         }
14865       else if (unformat (input, "disable"))
14866         is_set = 1;
14867       else
14868         break;
14869     }
14870
14871   if (!is_set)
14872     {
14873       errmsg ("Value not set");
14874       return -99;
14875     }
14876
14877   /* Construct the API message */
14878   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14879
14880   mp->is_enable = is_enable;
14881
14882   /* send it... */
14883   S (mp);
14884
14885   /* Wait for a reply... */
14886   W (ret);
14887   return ret;
14888 }
14889
14890 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14891
14892 static int
14893 api_one_map_register_enable_disable (vat_main_t * vam)
14894 {
14895   unformat_input_t *input = vam->input;
14896   vl_api_one_map_register_enable_disable_t *mp;
14897   u8 is_set = 0;
14898   u8 is_enable = 0;
14899   int ret;
14900
14901   /* Parse args required to build the message */
14902   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14903     {
14904       if (unformat (input, "enable"))
14905         {
14906           is_set = 1;
14907           is_enable = 1;
14908         }
14909       else if (unformat (input, "disable"))
14910         is_set = 1;
14911       else
14912         break;
14913     }
14914
14915   if (!is_set)
14916     {
14917       errmsg ("Value not set");
14918       return -99;
14919     }
14920
14921   /* Construct the API message */
14922   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14923
14924   mp->is_enable = is_enable;
14925
14926   /* send it... */
14927   S (mp);
14928
14929   /* Wait for a reply... */
14930   W (ret);
14931   return ret;
14932 }
14933
14934 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14935
14936 static int
14937 api_one_enable_disable (vat_main_t * vam)
14938 {
14939   unformat_input_t *input = vam->input;
14940   vl_api_one_enable_disable_t *mp;
14941   u8 is_set = 0;
14942   u8 is_enable = 0;
14943   int ret;
14944
14945   /* Parse args required to build the message */
14946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14947     {
14948       if (unformat (input, "enable"))
14949         {
14950           is_set = 1;
14951           is_enable = 1;
14952         }
14953       else if (unformat (input, "disable"))
14954         {
14955           is_set = 1;
14956         }
14957       else
14958         break;
14959     }
14960
14961   if (!is_set)
14962     {
14963       errmsg ("Value not set");
14964       return -99;
14965     }
14966
14967   /* Construct the API message */
14968   M (ONE_ENABLE_DISABLE, mp);
14969
14970   mp->is_enable = is_enable;
14971
14972   /* send it... */
14973   S (mp);
14974
14975   /* Wait for a reply... */
14976   W (ret);
14977   return ret;
14978 }
14979
14980 #define api_lisp_enable_disable api_one_enable_disable
14981
14982 static int
14983 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14984 {
14985   unformat_input_t *input = vam->input;
14986   vl_api_one_enable_disable_xtr_mode_t *mp;
14987   u8 is_set = 0;
14988   u8 is_enable = 0;
14989   int ret;
14990
14991   /* Parse args required to build the message */
14992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14993     {
14994       if (unformat (input, "enable"))
14995         {
14996           is_set = 1;
14997           is_enable = 1;
14998         }
14999       else if (unformat (input, "disable"))
15000         {
15001           is_set = 1;
15002         }
15003       else
15004         break;
15005     }
15006
15007   if (!is_set)
15008     {
15009       errmsg ("Value not set");
15010       return -99;
15011     }
15012
15013   /* Construct the API message */
15014   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15015
15016   mp->is_enable = is_enable;
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_show_xtr_mode (vat_main_t * vam)
15028 {
15029   vl_api_one_show_xtr_mode_t *mp;
15030   int ret;
15031
15032   /* Construct the API message */
15033   M (ONE_SHOW_XTR_MODE, mp);
15034
15035   /* send it... */
15036   S (mp);
15037
15038   /* Wait for a reply... */
15039   W (ret);
15040   return ret;
15041 }
15042
15043 static int
15044 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15045 {
15046   unformat_input_t *input = vam->input;
15047   vl_api_one_enable_disable_pitr_mode_t *mp;
15048   u8 is_set = 0;
15049   u8 is_enable = 0;
15050   int ret;
15051
15052   /* Parse args required to build the message */
15053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15054     {
15055       if (unformat (input, "enable"))
15056         {
15057           is_set = 1;
15058           is_enable = 1;
15059         }
15060       else if (unformat (input, "disable"))
15061         {
15062           is_set = 1;
15063         }
15064       else
15065         break;
15066     }
15067
15068   if (!is_set)
15069     {
15070       errmsg ("Value not set");
15071       return -99;
15072     }
15073
15074   /* Construct the API message */
15075   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15076
15077   mp->is_enable = is_enable;
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_show_pitr_mode (vat_main_t * vam)
15089 {
15090   vl_api_one_show_pitr_mode_t *mp;
15091   int ret;
15092
15093   /* Construct the API message */
15094   M (ONE_SHOW_PITR_MODE, mp);
15095
15096   /* send it... */
15097   S (mp);
15098
15099   /* Wait for a reply... */
15100   W (ret);
15101   return ret;
15102 }
15103
15104 static int
15105 api_one_enable_disable_petr_mode (vat_main_t * vam)
15106 {
15107   unformat_input_t *input = vam->input;
15108   vl_api_one_enable_disable_petr_mode_t *mp;
15109   u8 is_set = 0;
15110   u8 is_enable = 0;
15111   int ret;
15112
15113   /* Parse args required to build the message */
15114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15115     {
15116       if (unformat (input, "enable"))
15117         {
15118           is_set = 1;
15119           is_enable = 1;
15120         }
15121       else if (unformat (input, "disable"))
15122         {
15123           is_set = 1;
15124         }
15125       else
15126         break;
15127     }
15128
15129   if (!is_set)
15130     {
15131       errmsg ("Value not set");
15132       return -99;
15133     }
15134
15135   /* Construct the API message */
15136   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15137
15138   mp->is_enable = is_enable;
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_one_show_petr_mode (vat_main_t * vam)
15150 {
15151   vl_api_one_show_petr_mode_t *mp;
15152   int ret;
15153
15154   /* Construct the API message */
15155   M (ONE_SHOW_PETR_MODE, mp);
15156
15157   /* send it... */
15158   S (mp);
15159
15160   /* Wait for a reply... */
15161   W (ret);
15162   return ret;
15163 }
15164
15165 static int
15166 api_show_one_map_register_state (vat_main_t * vam)
15167 {
15168   vl_api_show_one_map_register_state_t *mp;
15169   int ret;
15170
15171   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15172
15173   /* send */
15174   S (mp);
15175
15176   /* wait for reply */
15177   W (ret);
15178   return ret;
15179 }
15180
15181 #define api_show_lisp_map_register_state api_show_one_map_register_state
15182
15183 static int
15184 api_show_one_rloc_probe_state (vat_main_t * vam)
15185 {
15186   vl_api_show_one_rloc_probe_state_t *mp;
15187   int ret;
15188
15189   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15190
15191   /* send */
15192   S (mp);
15193
15194   /* wait for reply */
15195   W (ret);
15196   return ret;
15197 }
15198
15199 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15200
15201 static int
15202 api_one_add_del_ndp_entry (vat_main_t * vam)
15203 {
15204   vl_api_one_add_del_ndp_entry_t *mp;
15205   unformat_input_t *input = vam->input;
15206   u8 is_add = 1;
15207   u8 mac_set = 0;
15208   u8 bd_set = 0;
15209   u8 ip_set = 0;
15210   u8 mac[6] = { 0, };
15211   u8 ip6[16] = { 0, };
15212   u32 bd = ~0;
15213   int ret;
15214
15215   /* Parse args required to build the message */
15216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15217     {
15218       if (unformat (input, "del"))
15219         is_add = 0;
15220       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15221         mac_set = 1;
15222       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15223         ip_set = 1;
15224       else if (unformat (input, "bd %d", &bd))
15225         bd_set = 1;
15226       else
15227         {
15228           errmsg ("parse error '%U'", format_unformat_error, input);
15229           return -99;
15230         }
15231     }
15232
15233   if (!bd_set || !ip_set || (!mac_set && is_add))
15234     {
15235       errmsg ("Missing BD, IP or MAC!");
15236       return -99;
15237     }
15238
15239   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15240   mp->is_add = is_add;
15241   clib_memcpy (&mp->entry.mac, mac, 6);
15242   mp->bd = clib_host_to_net_u32 (bd);
15243   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15244
15245   /* send */
15246   S (mp);
15247
15248   /* wait for reply */
15249   W (ret);
15250   return ret;
15251 }
15252
15253 static int
15254 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15255 {
15256   vl_api_one_add_del_l2_arp_entry_t *mp;
15257   unformat_input_t *input = vam->input;
15258   u8 is_add = 1;
15259   u8 mac_set = 0;
15260   u8 bd_set = 0;
15261   u8 ip_set = 0;
15262   u8 mac[6] = { 0, };
15263   u32 ip4 = 0, bd = ~0;
15264   int ret;
15265
15266   /* Parse args required to build the message */
15267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15268     {
15269       if (unformat (input, "del"))
15270         is_add = 0;
15271       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15272         mac_set = 1;
15273       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15274         ip_set = 1;
15275       else if (unformat (input, "bd %d", &bd))
15276         bd_set = 1;
15277       else
15278         {
15279           errmsg ("parse error '%U'", format_unformat_error, input);
15280           return -99;
15281         }
15282     }
15283
15284   if (!bd_set || !ip_set || (!mac_set && is_add))
15285     {
15286       errmsg ("Missing BD, IP or MAC!");
15287       return -99;
15288     }
15289
15290   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15291   mp->is_add = is_add;
15292   clib_memcpy (&mp->entry.mac, mac, 6);
15293   mp->bd = clib_host_to_net_u32 (bd);
15294   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15295
15296   /* send */
15297   S (mp);
15298
15299   /* wait for reply */
15300   W (ret);
15301   return ret;
15302 }
15303
15304 static int
15305 api_one_ndp_bd_get (vat_main_t * vam)
15306 {
15307   vl_api_one_ndp_bd_get_t *mp;
15308   int ret;
15309
15310   M (ONE_NDP_BD_GET, mp);
15311
15312   /* send */
15313   S (mp);
15314
15315   /* wait for reply */
15316   W (ret);
15317   return ret;
15318 }
15319
15320 static int
15321 api_one_ndp_entries_get (vat_main_t * vam)
15322 {
15323   vl_api_one_ndp_entries_get_t *mp;
15324   unformat_input_t *input = vam->input;
15325   u8 bd_set = 0;
15326   u32 bd = ~0;
15327   int ret;
15328
15329   /* Parse args required to build the message */
15330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15331     {
15332       if (unformat (input, "bd %d", &bd))
15333         bd_set = 1;
15334       else
15335         {
15336           errmsg ("parse error '%U'", format_unformat_error, input);
15337           return -99;
15338         }
15339     }
15340
15341   if (!bd_set)
15342     {
15343       errmsg ("Expected bridge domain!");
15344       return -99;
15345     }
15346
15347   M (ONE_NDP_ENTRIES_GET, mp);
15348   mp->bd = clib_host_to_net_u32 (bd);
15349
15350   /* send */
15351   S (mp);
15352
15353   /* wait for reply */
15354   W (ret);
15355   return ret;
15356 }
15357
15358 static int
15359 api_one_l2_arp_bd_get (vat_main_t * vam)
15360 {
15361   vl_api_one_l2_arp_bd_get_t *mp;
15362   int ret;
15363
15364   M (ONE_L2_ARP_BD_GET, mp);
15365
15366   /* send */
15367   S (mp);
15368
15369   /* wait for reply */
15370   W (ret);
15371   return ret;
15372 }
15373
15374 static int
15375 api_one_l2_arp_entries_get (vat_main_t * vam)
15376 {
15377   vl_api_one_l2_arp_entries_get_t *mp;
15378   unformat_input_t *input = vam->input;
15379   u8 bd_set = 0;
15380   u32 bd = ~0;
15381   int ret;
15382
15383   /* Parse args required to build the message */
15384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15385     {
15386       if (unformat (input, "bd %d", &bd))
15387         bd_set = 1;
15388       else
15389         {
15390           errmsg ("parse error '%U'", format_unformat_error, input);
15391           return -99;
15392         }
15393     }
15394
15395   if (!bd_set)
15396     {
15397       errmsg ("Expected bridge domain!");
15398       return -99;
15399     }
15400
15401   M (ONE_L2_ARP_ENTRIES_GET, mp);
15402   mp->bd = clib_host_to_net_u32 (bd);
15403
15404   /* send */
15405   S (mp);
15406
15407   /* wait for reply */
15408   W (ret);
15409   return ret;
15410 }
15411
15412 static int
15413 api_one_stats_enable_disable (vat_main_t * vam)
15414 {
15415   vl_api_one_stats_enable_disable_t *mp;
15416   unformat_input_t *input = vam->input;
15417   u8 is_set = 0;
15418   u8 is_enable = 0;
15419   int ret;
15420
15421   /* Parse args required to build the message */
15422   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15423     {
15424       if (unformat (input, "enable"))
15425         {
15426           is_set = 1;
15427           is_enable = 1;
15428         }
15429       else if (unformat (input, "disable"))
15430         {
15431           is_set = 1;
15432         }
15433       else
15434         break;
15435     }
15436
15437   if (!is_set)
15438     {
15439       errmsg ("Value not set");
15440       return -99;
15441     }
15442
15443   M (ONE_STATS_ENABLE_DISABLE, mp);
15444   mp->is_enable = is_enable;
15445
15446   /* send */
15447   S (mp);
15448
15449   /* wait for reply */
15450   W (ret);
15451   return ret;
15452 }
15453
15454 static int
15455 api_show_one_stats_enable_disable (vat_main_t * vam)
15456 {
15457   vl_api_show_one_stats_enable_disable_t *mp;
15458   int ret;
15459
15460   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15461
15462   /* send */
15463   S (mp);
15464
15465   /* wait for reply */
15466   W (ret);
15467   return ret;
15468 }
15469
15470 static int
15471 api_show_one_map_request_mode (vat_main_t * vam)
15472 {
15473   vl_api_show_one_map_request_mode_t *mp;
15474   int ret;
15475
15476   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15477
15478   /* send */
15479   S (mp);
15480
15481   /* wait for reply */
15482   W (ret);
15483   return ret;
15484 }
15485
15486 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15487
15488 static int
15489 api_one_map_request_mode (vat_main_t * vam)
15490 {
15491   unformat_input_t *input = vam->input;
15492   vl_api_one_map_request_mode_t *mp;
15493   u8 mode = 0;
15494   int ret;
15495
15496   /* Parse args required to build the message */
15497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15498     {
15499       if (unformat (input, "dst-only"))
15500         mode = 0;
15501       else if (unformat (input, "src-dst"))
15502         mode = 1;
15503       else
15504         {
15505           errmsg ("parse error '%U'", format_unformat_error, input);
15506           return -99;
15507         }
15508     }
15509
15510   M (ONE_MAP_REQUEST_MODE, mp);
15511
15512   mp->mode = mode;
15513
15514   /* send */
15515   S (mp);
15516
15517   /* wait for reply */
15518   W (ret);
15519   return ret;
15520 }
15521
15522 #define api_lisp_map_request_mode api_one_map_request_mode
15523
15524 /**
15525  * Enable/disable ONE proxy ITR.
15526  *
15527  * @param vam vpp API test context
15528  * @return return code
15529  */
15530 static int
15531 api_one_pitr_set_locator_set (vat_main_t * vam)
15532 {
15533   u8 ls_name_set = 0;
15534   unformat_input_t *input = vam->input;
15535   vl_api_one_pitr_set_locator_set_t *mp;
15536   u8 is_add = 1;
15537   u8 *ls_name = 0;
15538   int ret;
15539
15540   /* Parse args required to build the message */
15541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15542     {
15543       if (unformat (input, "del"))
15544         is_add = 0;
15545       else if (unformat (input, "locator-set %s", &ls_name))
15546         ls_name_set = 1;
15547       else
15548         {
15549           errmsg ("parse error '%U'", format_unformat_error, input);
15550           return -99;
15551         }
15552     }
15553
15554   if (!ls_name_set)
15555     {
15556       errmsg ("locator-set name not set!");
15557       return -99;
15558     }
15559
15560   M (ONE_PITR_SET_LOCATOR_SET, mp);
15561
15562   mp->is_add = is_add;
15563   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15564   vec_free (ls_name);
15565
15566   /* send */
15567   S (mp);
15568
15569   /* wait for reply */
15570   W (ret);
15571   return ret;
15572 }
15573
15574 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15575
15576 static int
15577 api_one_nsh_set_locator_set (vat_main_t * vam)
15578 {
15579   u8 ls_name_set = 0;
15580   unformat_input_t *input = vam->input;
15581   vl_api_one_nsh_set_locator_set_t *mp;
15582   u8 is_add = 1;
15583   u8 *ls_name = 0;
15584   int ret;
15585
15586   /* Parse args required to build the message */
15587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15588     {
15589       if (unformat (input, "del"))
15590         is_add = 0;
15591       else if (unformat (input, "ls %s", &ls_name))
15592         ls_name_set = 1;
15593       else
15594         {
15595           errmsg ("parse error '%U'", format_unformat_error, input);
15596           return -99;
15597         }
15598     }
15599
15600   if (!ls_name_set && is_add)
15601     {
15602       errmsg ("locator-set name not set!");
15603       return -99;
15604     }
15605
15606   M (ONE_NSH_SET_LOCATOR_SET, mp);
15607
15608   mp->is_add = is_add;
15609   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15610   vec_free (ls_name);
15611
15612   /* send */
15613   S (mp);
15614
15615   /* wait for reply */
15616   W (ret);
15617   return ret;
15618 }
15619
15620 static int
15621 api_show_one_pitr (vat_main_t * vam)
15622 {
15623   vl_api_show_one_pitr_t *mp;
15624   int ret;
15625
15626   if (!vam->json_output)
15627     {
15628       print (vam->ofp, "%=20s", "lisp status:");
15629     }
15630
15631   M (SHOW_ONE_PITR, mp);
15632   /* send it... */
15633   S (mp);
15634
15635   /* Wait for a reply... */
15636   W (ret);
15637   return ret;
15638 }
15639
15640 #define api_show_lisp_pitr api_show_one_pitr
15641
15642 static int
15643 api_one_use_petr (vat_main_t * vam)
15644 {
15645   unformat_input_t *input = vam->input;
15646   vl_api_one_use_petr_t *mp;
15647   u8 is_add = 0;
15648   ip_address_t ip;
15649   int ret;
15650
15651   clib_memset (&ip, 0, sizeof (ip));
15652
15653   /* Parse args required to build the message */
15654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15655     {
15656       if (unformat (input, "disable"))
15657         is_add = 0;
15658       else
15659         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15660         {
15661           is_add = 1;
15662           ip_addr_version (&ip) = AF_IP4;
15663         }
15664       else
15665         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15666         {
15667           is_add = 1;
15668           ip_addr_version (&ip) = AF_IP6;
15669         }
15670       else
15671         {
15672           errmsg ("parse error '%U'", format_unformat_error, input);
15673           return -99;
15674         }
15675     }
15676
15677   M (ONE_USE_PETR, mp);
15678
15679   mp->is_add = is_add;
15680   if (is_add)
15681     {
15682       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15683       if (mp->ip_address.af)
15684         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15685       else
15686         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15687     }
15688
15689   /* send */
15690   S (mp);
15691
15692   /* wait for reply */
15693   W (ret);
15694   return ret;
15695 }
15696
15697 #define api_lisp_use_petr api_one_use_petr
15698
15699 static int
15700 api_show_one_nsh_mapping (vat_main_t * vam)
15701 {
15702   vl_api_show_one_use_petr_t *mp;
15703   int ret;
15704
15705   if (!vam->json_output)
15706     {
15707       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15708     }
15709
15710   M (SHOW_ONE_NSH_MAPPING, mp);
15711   /* send it... */
15712   S (mp);
15713
15714   /* Wait for a reply... */
15715   W (ret);
15716   return ret;
15717 }
15718
15719 static int
15720 api_show_one_use_petr (vat_main_t * vam)
15721 {
15722   vl_api_show_one_use_petr_t *mp;
15723   int ret;
15724
15725   if (!vam->json_output)
15726     {
15727       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15728     }
15729
15730   M (SHOW_ONE_USE_PETR, mp);
15731   /* send it... */
15732   S (mp);
15733
15734   /* Wait for a reply... */
15735   W (ret);
15736   return ret;
15737 }
15738
15739 #define api_show_lisp_use_petr api_show_one_use_petr
15740
15741 /**
15742  * Add/delete mapping between vni and vrf
15743  */
15744 static int
15745 api_one_eid_table_add_del_map (vat_main_t * vam)
15746 {
15747   unformat_input_t *input = vam->input;
15748   vl_api_one_eid_table_add_del_map_t *mp;
15749   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15750   u32 vni, vrf, bd_index;
15751   int ret;
15752
15753   /* Parse args required to build the message */
15754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15755     {
15756       if (unformat (input, "del"))
15757         is_add = 0;
15758       else if (unformat (input, "vrf %d", &vrf))
15759         vrf_set = 1;
15760       else if (unformat (input, "bd_index %d", &bd_index))
15761         bd_index_set = 1;
15762       else if (unformat (input, "vni %d", &vni))
15763         vni_set = 1;
15764       else
15765         break;
15766     }
15767
15768   if (!vni_set || (!vrf_set && !bd_index_set))
15769     {
15770       errmsg ("missing arguments!");
15771       return -99;
15772     }
15773
15774   if (vrf_set && bd_index_set)
15775     {
15776       errmsg ("error: both vrf and bd entered!");
15777       return -99;
15778     }
15779
15780   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15781
15782   mp->is_add = is_add;
15783   mp->vni = htonl (vni);
15784   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15785   mp->is_l2 = bd_index_set;
15786
15787   /* send */
15788   S (mp);
15789
15790   /* wait for reply */
15791   W (ret);
15792   return ret;
15793 }
15794
15795 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15796
15797 uword
15798 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15799 {
15800   u32 *action = va_arg (*args, u32 *);
15801   u8 *s = 0;
15802
15803   if (unformat (input, "%s", &s))
15804     {
15805       if (!strcmp ((char *) s, "no-action"))
15806         action[0] = 0;
15807       else if (!strcmp ((char *) s, "natively-forward"))
15808         action[0] = 1;
15809       else if (!strcmp ((char *) s, "send-map-request"))
15810         action[0] = 2;
15811       else if (!strcmp ((char *) s, "drop"))
15812         action[0] = 3;
15813       else
15814         {
15815           clib_warning ("invalid action: '%s'", s);
15816           action[0] = 3;
15817         }
15818     }
15819   else
15820     return 0;
15821
15822   vec_free (s);
15823   return 1;
15824 }
15825
15826 /**
15827  * Add/del remote mapping to/from ONE control plane
15828  *
15829  * @param vam vpp API test context
15830  * @return return code
15831  */
15832 static int
15833 api_one_add_del_remote_mapping (vat_main_t * vam)
15834 {
15835   unformat_input_t *input = vam->input;
15836   vl_api_one_add_del_remote_mapping_t *mp;
15837   u32 vni = 0;
15838   lisp_eid_vat_t _eid, *eid = &_eid;
15839   lisp_eid_vat_t _seid, *seid = &_seid;
15840   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15841   u32 action = ~0, p, w, data_len;
15842   ip4_address_t rloc4;
15843   ip6_address_t rloc6;
15844   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15845   int ret;
15846
15847   clib_memset (&rloc, 0, sizeof (rloc));
15848
15849   /* Parse args required to build the message */
15850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15851     {
15852       if (unformat (input, "del-all"))
15853         {
15854           del_all = 1;
15855         }
15856       else if (unformat (input, "del"))
15857         {
15858           is_add = 0;
15859         }
15860       else if (unformat (input, "add"))
15861         {
15862           is_add = 1;
15863         }
15864       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15865         {
15866           eid_set = 1;
15867         }
15868       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15869         {
15870           seid_set = 1;
15871         }
15872       else if (unformat (input, "vni %d", &vni))
15873         {
15874           ;
15875         }
15876       else if (unformat (input, "p %d w %d", &p, &w))
15877         {
15878           if (!curr_rloc)
15879             {
15880               errmsg ("No RLOC configured for setting priority/weight!");
15881               return -99;
15882             }
15883           curr_rloc->priority = p;
15884           curr_rloc->weight = w;
15885         }
15886       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15887         {
15888           rloc.ip_address.af = 0;
15889           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15890           vec_add1 (rlocs, rloc);
15891           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15892         }
15893       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15894         {
15895           rloc.ip_address.af = 1;
15896           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15897           vec_add1 (rlocs, rloc);
15898           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15899         }
15900       else if (unformat (input, "action %U",
15901                          unformat_negative_mapping_action, &action))
15902         {
15903           ;
15904         }
15905       else
15906         {
15907           clib_warning ("parse error '%U'", format_unformat_error, input);
15908           return -99;
15909         }
15910     }
15911
15912   if (0 == eid_set)
15913     {
15914       errmsg ("missing params!");
15915       return -99;
15916     }
15917
15918   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15919     {
15920       errmsg ("no action set for negative map-reply!");
15921       return -99;
15922     }
15923
15924   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15925
15926   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15927   mp->is_add = is_add;
15928   mp->vni = htonl (vni);
15929   mp->action = (u8) action;
15930   mp->is_src_dst = seid_set;
15931   mp->del_all = del_all;
15932   lisp_eid_put_vat (&mp->deid, eid);
15933   lisp_eid_put_vat (&mp->seid, seid);
15934
15935   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15936   clib_memcpy (mp->rlocs, rlocs, data_len);
15937   vec_free (rlocs);
15938
15939   /* send it... */
15940   S (mp);
15941
15942   /* Wait for a reply... */
15943   W (ret);
15944   return ret;
15945 }
15946
15947 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15948
15949 /**
15950  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15951  * forwarding entries in data-plane accordingly.
15952  *
15953  * @param vam vpp API test context
15954  * @return return code
15955  */
15956 static int
15957 api_one_add_del_adjacency (vat_main_t * vam)
15958 {
15959   unformat_input_t *input = vam->input;
15960   vl_api_one_add_del_adjacency_t *mp;
15961   u32 vni = 0;
15962   u8 is_add = 1;
15963   int ret;
15964   lisp_eid_vat_t leid, reid;
15965
15966   leid.type = reid.type = (u8) ~ 0;
15967
15968   /* Parse args required to build the message */
15969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15970     {
15971       if (unformat (input, "del"))
15972         {
15973           is_add = 0;
15974         }
15975       else if (unformat (input, "add"))
15976         {
15977           is_add = 1;
15978         }
15979       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15980                          &reid.addr.ip, &reid.len))
15981         {
15982           reid.type = 0;        /* ipv4 */
15983         }
15984       else if (unformat (input, "reid %U", unformat_ethernet_address,
15985                          &reid.addr.mac))
15986         {
15987           reid.type = 1;        /* mac */
15988         }
15989       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
15990                          &leid.addr.ip, &leid.len))
15991         {
15992           leid.type = 0;        /* ipv4 */
15993         }
15994       else if (unformat (input, "leid %U", unformat_ethernet_address,
15995                          &leid.addr.mac))
15996         {
15997           leid.type = 1;        /* mac */
15998         }
15999       else if (unformat (input, "vni %d", &vni))
16000         {
16001           ;
16002         }
16003       else
16004         {
16005           errmsg ("parse error '%U'", format_unformat_error, input);
16006           return -99;
16007         }
16008     }
16009
16010   if ((u8) ~ 0 == reid.type)
16011     {
16012       errmsg ("missing params!");
16013       return -99;
16014     }
16015
16016   if (leid.type != reid.type)
16017     {
16018       errmsg ("remote and local EIDs are of different types!");
16019       return -99;
16020     }
16021
16022   M (ONE_ADD_DEL_ADJACENCY, mp);
16023   mp->is_add = is_add;
16024   mp->vni = htonl (vni);
16025   lisp_eid_put_vat (&mp->leid, &leid);
16026   lisp_eid_put_vat (&mp->reid, &reid);
16027
16028   /* send it... */
16029   S (mp);
16030
16031   /* Wait for a reply... */
16032   W (ret);
16033   return ret;
16034 }
16035
16036 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16037
16038 uword
16039 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16040 {
16041   u32 *mode = va_arg (*args, u32 *);
16042
16043   if (unformat (input, "lisp"))
16044     *mode = 0;
16045   else if (unformat (input, "vxlan"))
16046     *mode = 1;
16047   else
16048     return 0;
16049
16050   return 1;
16051 }
16052
16053 static int
16054 api_gpe_get_encap_mode (vat_main_t * vam)
16055 {
16056   vl_api_gpe_get_encap_mode_t *mp;
16057   int ret;
16058
16059   /* Construct the API message */
16060   M (GPE_GET_ENCAP_MODE, mp);
16061
16062   /* send it... */
16063   S (mp);
16064
16065   /* Wait for a reply... */
16066   W (ret);
16067   return ret;
16068 }
16069
16070 static int
16071 api_gpe_set_encap_mode (vat_main_t * vam)
16072 {
16073   unformat_input_t *input = vam->input;
16074   vl_api_gpe_set_encap_mode_t *mp;
16075   int ret;
16076   u32 mode = 0;
16077
16078   /* Parse args required to build the message */
16079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16080     {
16081       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16082         ;
16083       else
16084         break;
16085     }
16086
16087   /* Construct the API message */
16088   M (GPE_SET_ENCAP_MODE, mp);
16089
16090   mp->is_vxlan = mode;
16091
16092   /* send it... */
16093   S (mp);
16094
16095   /* Wait for a reply... */
16096   W (ret);
16097   return ret;
16098 }
16099
16100 static int
16101 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16102 {
16103   unformat_input_t *input = vam->input;
16104   vl_api_gpe_add_del_iface_t *mp;
16105   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16106   u32 dp_table = 0, vni = 0;
16107   int ret;
16108
16109   /* Parse args required to build the message */
16110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16111     {
16112       if (unformat (input, "up"))
16113         {
16114           action_set = 1;
16115           is_add = 1;
16116         }
16117       else if (unformat (input, "down"))
16118         {
16119           action_set = 1;
16120           is_add = 0;
16121         }
16122       else if (unformat (input, "table_id %d", &dp_table))
16123         {
16124           dp_table_set = 1;
16125         }
16126       else if (unformat (input, "bd_id %d", &dp_table))
16127         {
16128           dp_table_set = 1;
16129           is_l2 = 1;
16130         }
16131       else if (unformat (input, "vni %d", &vni))
16132         {
16133           vni_set = 1;
16134         }
16135       else
16136         break;
16137     }
16138
16139   if (action_set == 0)
16140     {
16141       errmsg ("Action not set");
16142       return -99;
16143     }
16144   if (dp_table_set == 0 || vni_set == 0)
16145     {
16146       errmsg ("vni and dp_table must be set");
16147       return -99;
16148     }
16149
16150   /* Construct the API message */
16151   M (GPE_ADD_DEL_IFACE, mp);
16152
16153   mp->is_add = is_add;
16154   mp->dp_table = clib_host_to_net_u32 (dp_table);
16155   mp->is_l2 = is_l2;
16156   mp->vni = clib_host_to_net_u32 (vni);
16157
16158   /* send it... */
16159   S (mp);
16160
16161   /* Wait for a reply... */
16162   W (ret);
16163   return ret;
16164 }
16165
16166 static int
16167 api_one_map_register_fallback_threshold (vat_main_t * vam)
16168 {
16169   unformat_input_t *input = vam->input;
16170   vl_api_one_map_register_fallback_threshold_t *mp;
16171   u32 value = 0;
16172   u8 is_set = 0;
16173   int ret;
16174
16175   /* Parse args required to build the message */
16176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16177     {
16178       if (unformat (input, "%u", &value))
16179         is_set = 1;
16180       else
16181         {
16182           clib_warning ("parse error '%U'", format_unformat_error, input);
16183           return -99;
16184         }
16185     }
16186
16187   if (!is_set)
16188     {
16189       errmsg ("fallback threshold value is missing!");
16190       return -99;
16191     }
16192
16193   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16194   mp->value = clib_host_to_net_u32 (value);
16195
16196   /* send it... */
16197   S (mp);
16198
16199   /* Wait for a reply... */
16200   W (ret);
16201   return ret;
16202 }
16203
16204 static int
16205 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16206 {
16207   vl_api_show_one_map_register_fallback_threshold_t *mp;
16208   int ret;
16209
16210   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16211
16212   /* send it... */
16213   S (mp);
16214
16215   /* Wait for a reply... */
16216   W (ret);
16217   return ret;
16218 }
16219
16220 uword
16221 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16222 {
16223   u32 *proto = va_arg (*args, u32 *);
16224
16225   if (unformat (input, "udp"))
16226     *proto = 1;
16227   else if (unformat (input, "api"))
16228     *proto = 2;
16229   else
16230     return 0;
16231
16232   return 1;
16233 }
16234
16235 static int
16236 api_one_set_transport_protocol (vat_main_t * vam)
16237 {
16238   unformat_input_t *input = vam->input;
16239   vl_api_one_set_transport_protocol_t *mp;
16240   u8 is_set = 0;
16241   u32 protocol = 0;
16242   int ret;
16243
16244   /* Parse args required to build the message */
16245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16246     {
16247       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16248         is_set = 1;
16249       else
16250         {
16251           clib_warning ("parse error '%U'", format_unformat_error, input);
16252           return -99;
16253         }
16254     }
16255
16256   if (!is_set)
16257     {
16258       errmsg ("Transport protocol missing!");
16259       return -99;
16260     }
16261
16262   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16263   mp->protocol = (u8) protocol;
16264
16265   /* send it... */
16266   S (mp);
16267
16268   /* Wait for a reply... */
16269   W (ret);
16270   return ret;
16271 }
16272
16273 static int
16274 api_one_get_transport_protocol (vat_main_t * vam)
16275 {
16276   vl_api_one_get_transport_protocol_t *mp;
16277   int ret;
16278
16279   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16280
16281   /* send it... */
16282   S (mp);
16283
16284   /* Wait for a reply... */
16285   W (ret);
16286   return ret;
16287 }
16288
16289 static int
16290 api_one_map_register_set_ttl (vat_main_t * vam)
16291 {
16292   unformat_input_t *input = vam->input;
16293   vl_api_one_map_register_set_ttl_t *mp;
16294   u32 ttl = 0;
16295   u8 is_set = 0;
16296   int ret;
16297
16298   /* Parse args required to build the message */
16299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16300     {
16301       if (unformat (input, "%u", &ttl))
16302         is_set = 1;
16303       else
16304         {
16305           clib_warning ("parse error '%U'", format_unformat_error, input);
16306           return -99;
16307         }
16308     }
16309
16310   if (!is_set)
16311     {
16312       errmsg ("TTL value missing!");
16313       return -99;
16314     }
16315
16316   M (ONE_MAP_REGISTER_SET_TTL, mp);
16317   mp->ttl = clib_host_to_net_u32 (ttl);
16318
16319   /* send it... */
16320   S (mp);
16321
16322   /* Wait for a reply... */
16323   W (ret);
16324   return ret;
16325 }
16326
16327 static int
16328 api_show_one_map_register_ttl (vat_main_t * vam)
16329 {
16330   vl_api_show_one_map_register_ttl_t *mp;
16331   int ret;
16332
16333   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16334
16335   /* send it... */
16336   S (mp);
16337
16338   /* Wait for a reply... */
16339   W (ret);
16340   return ret;
16341 }
16342
16343 /**
16344  * Add/del map request itr rlocs from ONE control plane and updates
16345  *
16346  * @param vam vpp API test context
16347  * @return return code
16348  */
16349 static int
16350 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16351 {
16352   unformat_input_t *input = vam->input;
16353   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16354   u8 *locator_set_name = 0;
16355   u8 locator_set_name_set = 0;
16356   u8 is_add = 1;
16357   int ret;
16358
16359   /* Parse args required to build the message */
16360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16361     {
16362       if (unformat (input, "del"))
16363         {
16364           is_add = 0;
16365         }
16366       else if (unformat (input, "%_%v%_", &locator_set_name))
16367         {
16368           locator_set_name_set = 1;
16369         }
16370       else
16371         {
16372           clib_warning ("parse error '%U'", format_unformat_error, input);
16373           return -99;
16374         }
16375     }
16376
16377   if (is_add && !locator_set_name_set)
16378     {
16379       errmsg ("itr-rloc is not set!");
16380       return -99;
16381     }
16382
16383   if (is_add && vec_len (locator_set_name) > 64)
16384     {
16385       errmsg ("itr-rloc locator-set name too long");
16386       vec_free (locator_set_name);
16387       return -99;
16388     }
16389
16390   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16391   mp->is_add = is_add;
16392   if (is_add)
16393     {
16394       clib_memcpy (mp->locator_set_name, locator_set_name,
16395                    vec_len (locator_set_name));
16396     }
16397   else
16398     {
16399       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16400     }
16401   vec_free (locator_set_name);
16402
16403   /* send it... */
16404   S (mp);
16405
16406   /* Wait for a reply... */
16407   W (ret);
16408   return ret;
16409 }
16410
16411 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16412
16413 static int
16414 api_one_locator_dump (vat_main_t * vam)
16415 {
16416   unformat_input_t *input = vam->input;
16417   vl_api_one_locator_dump_t *mp;
16418   vl_api_control_ping_t *mp_ping;
16419   u8 is_index_set = 0, is_name_set = 0;
16420   u8 *ls_name = 0;
16421   u32 ls_index = ~0;
16422   int ret;
16423
16424   /* Parse args required to build the message */
16425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16426     {
16427       if (unformat (input, "ls_name %_%v%_", &ls_name))
16428         {
16429           is_name_set = 1;
16430         }
16431       else if (unformat (input, "ls_index %d", &ls_index))
16432         {
16433           is_index_set = 1;
16434         }
16435       else
16436         {
16437           errmsg ("parse error '%U'", format_unformat_error, input);
16438           return -99;
16439         }
16440     }
16441
16442   if (!is_index_set && !is_name_set)
16443     {
16444       errmsg ("error: expected one of index or name!");
16445       return -99;
16446     }
16447
16448   if (is_index_set && is_name_set)
16449     {
16450       errmsg ("error: only one param expected!");
16451       return -99;
16452     }
16453
16454   if (vec_len (ls_name) > 62)
16455     {
16456       errmsg ("error: locator set name too long!");
16457       return -99;
16458     }
16459
16460   if (!vam->json_output)
16461     {
16462       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16463     }
16464
16465   M (ONE_LOCATOR_DUMP, mp);
16466   mp->is_index_set = is_index_set;
16467
16468   if (is_index_set)
16469     mp->ls_index = clib_host_to_net_u32 (ls_index);
16470   else
16471     {
16472       vec_add1 (ls_name, 0);
16473       strncpy ((char *) mp->ls_name, (char *) ls_name,
16474                sizeof (mp->ls_name) - 1);
16475     }
16476
16477   /* send it... */
16478   S (mp);
16479
16480   /* Use a control ping for synchronization */
16481   MPING (CONTROL_PING, mp_ping);
16482   S (mp_ping);
16483
16484   /* Wait for a reply... */
16485   W (ret);
16486   return ret;
16487 }
16488
16489 #define api_lisp_locator_dump api_one_locator_dump
16490
16491 static int
16492 api_one_locator_set_dump (vat_main_t * vam)
16493 {
16494   vl_api_one_locator_set_dump_t *mp;
16495   vl_api_control_ping_t *mp_ping;
16496   unformat_input_t *input = vam->input;
16497   u8 filter = 0;
16498   int ret;
16499
16500   /* Parse args required to build the message */
16501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16502     {
16503       if (unformat (input, "local"))
16504         {
16505           filter = 1;
16506         }
16507       else if (unformat (input, "remote"))
16508         {
16509           filter = 2;
16510         }
16511       else
16512         {
16513           errmsg ("parse error '%U'", format_unformat_error, input);
16514           return -99;
16515         }
16516     }
16517
16518   if (!vam->json_output)
16519     {
16520       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16521     }
16522
16523   M (ONE_LOCATOR_SET_DUMP, mp);
16524
16525   mp->filter = filter;
16526
16527   /* send it... */
16528   S (mp);
16529
16530   /* Use a control ping for synchronization */
16531   MPING (CONTROL_PING, mp_ping);
16532   S (mp_ping);
16533
16534   /* Wait for a reply... */
16535   W (ret);
16536   return ret;
16537 }
16538
16539 #define api_lisp_locator_set_dump api_one_locator_set_dump
16540
16541 static int
16542 api_one_eid_table_map_dump (vat_main_t * vam)
16543 {
16544   u8 is_l2 = 0;
16545   u8 mode_set = 0;
16546   unformat_input_t *input = vam->input;
16547   vl_api_one_eid_table_map_dump_t *mp;
16548   vl_api_control_ping_t *mp_ping;
16549   int ret;
16550
16551   /* Parse args required to build the message */
16552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16553     {
16554       if (unformat (input, "l2"))
16555         {
16556           is_l2 = 1;
16557           mode_set = 1;
16558         }
16559       else if (unformat (input, "l3"))
16560         {
16561           is_l2 = 0;
16562           mode_set = 1;
16563         }
16564       else
16565         {
16566           errmsg ("parse error '%U'", format_unformat_error, input);
16567           return -99;
16568         }
16569     }
16570
16571   if (!mode_set)
16572     {
16573       errmsg ("expected one of 'l2' or 'l3' parameter!");
16574       return -99;
16575     }
16576
16577   if (!vam->json_output)
16578     {
16579       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16580     }
16581
16582   M (ONE_EID_TABLE_MAP_DUMP, mp);
16583   mp->is_l2 = is_l2;
16584
16585   /* send it... */
16586   S (mp);
16587
16588   /* Use a control ping for synchronization */
16589   MPING (CONTROL_PING, mp_ping);
16590   S (mp_ping);
16591
16592   /* Wait for a reply... */
16593   W (ret);
16594   return ret;
16595 }
16596
16597 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16598
16599 static int
16600 api_one_eid_table_vni_dump (vat_main_t * vam)
16601 {
16602   vl_api_one_eid_table_vni_dump_t *mp;
16603   vl_api_control_ping_t *mp_ping;
16604   int ret;
16605
16606   if (!vam->json_output)
16607     {
16608       print (vam->ofp, "VNI");
16609     }
16610
16611   M (ONE_EID_TABLE_VNI_DUMP, mp);
16612
16613   /* send it... */
16614   S (mp);
16615
16616   /* Use a control ping for synchronization */
16617   MPING (CONTROL_PING, mp_ping);
16618   S (mp_ping);
16619
16620   /* Wait for a reply... */
16621   W (ret);
16622   return ret;
16623 }
16624
16625 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16626
16627 static int
16628 api_one_eid_table_dump (vat_main_t * vam)
16629 {
16630   unformat_input_t *i = vam->input;
16631   vl_api_one_eid_table_dump_t *mp;
16632   vl_api_control_ping_t *mp_ping;
16633   u8 filter = 0;
16634   int ret;
16635   u32 vni, t = 0;
16636   lisp_eid_vat_t eid;
16637   u8 eid_set = 0;
16638
16639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16640     {
16641       if (unformat
16642           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16643         {
16644           eid_set = 1;
16645           eid.type = 0;
16646         }
16647       else
16648         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16649         {
16650           eid_set = 1;
16651           eid.type = 1;
16652         }
16653       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16654         {
16655           eid_set = 1;
16656           eid.type = 2;
16657         }
16658       else if (unformat (i, "vni %d", &t))
16659         {
16660           vni = t;
16661         }
16662       else if (unformat (i, "local"))
16663         {
16664           filter = 1;
16665         }
16666       else if (unformat (i, "remote"))
16667         {
16668           filter = 2;
16669         }
16670       else
16671         {
16672           errmsg ("parse error '%U'", format_unformat_error, i);
16673           return -99;
16674         }
16675     }
16676
16677   if (!vam->json_output)
16678     {
16679       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16680              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16681     }
16682
16683   M (ONE_EID_TABLE_DUMP, mp);
16684
16685   mp->filter = filter;
16686   if (eid_set)
16687     {
16688       mp->eid_set = 1;
16689       mp->vni = htonl (vni);
16690       lisp_eid_put_vat (&mp->eid, &eid);
16691     }
16692
16693   /* send it... */
16694   S (mp);
16695
16696   /* Use a control ping for synchronization */
16697   MPING (CONTROL_PING, mp_ping);
16698   S (mp_ping);
16699
16700   /* Wait for a reply... */
16701   W (ret);
16702   return ret;
16703 }
16704
16705 #define api_lisp_eid_table_dump api_one_eid_table_dump
16706
16707 static int
16708 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16709 {
16710   unformat_input_t *i = vam->input;
16711   vl_api_gpe_fwd_entries_get_t *mp;
16712   u8 vni_set = 0;
16713   u32 vni = ~0;
16714   int ret;
16715
16716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (unformat (i, "vni %d", &vni))
16719         {
16720           vni_set = 1;
16721         }
16722       else
16723         {
16724           errmsg ("parse error '%U'", format_unformat_error, i);
16725           return -99;
16726         }
16727     }
16728
16729   if (!vni_set)
16730     {
16731       errmsg ("vni not set!");
16732       return -99;
16733     }
16734
16735   if (!vam->json_output)
16736     {
16737       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16738              "leid", "reid");
16739     }
16740
16741   M (GPE_FWD_ENTRIES_GET, mp);
16742   mp->vni = clib_host_to_net_u32 (vni);
16743
16744   /* send it... */
16745   S (mp);
16746
16747   /* Wait for a reply... */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16753 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16754 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16755 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16756 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16757 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16758 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16759 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16760
16761 static int
16762 api_one_adjacencies_get (vat_main_t * vam)
16763 {
16764   unformat_input_t *i = vam->input;
16765   vl_api_one_adjacencies_get_t *mp;
16766   u8 vni_set = 0;
16767   u32 vni = ~0;
16768   int ret;
16769
16770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16771     {
16772       if (unformat (i, "vni %d", &vni))
16773         {
16774           vni_set = 1;
16775         }
16776       else
16777         {
16778           errmsg ("parse error '%U'", format_unformat_error, i);
16779           return -99;
16780         }
16781     }
16782
16783   if (!vni_set)
16784     {
16785       errmsg ("vni not set!");
16786       return -99;
16787     }
16788
16789   if (!vam->json_output)
16790     {
16791       print (vam->ofp, "%s %40s", "leid", "reid");
16792     }
16793
16794   M (ONE_ADJACENCIES_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 api_lisp_adjacencies_get api_one_adjacencies_get
16806
16807 static int
16808 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16809 {
16810   unformat_input_t *i = vam->input;
16811   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16812   int ret;
16813   u8 ip_family_set = 0, is_ip4 = 1;
16814
16815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (i, "ip4"))
16818         {
16819           ip_family_set = 1;
16820           is_ip4 = 1;
16821         }
16822       else if (unformat (i, "ip6"))
16823         {
16824           ip_family_set = 1;
16825           is_ip4 = 0;
16826         }
16827       else
16828         {
16829           errmsg ("parse error '%U'", format_unformat_error, i);
16830           return -99;
16831         }
16832     }
16833
16834   if (!ip_family_set)
16835     {
16836       errmsg ("ip family not set!");
16837       return -99;
16838     }
16839
16840   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16841   mp->is_ip4 = is_ip4;
16842
16843   /* send it... */
16844   S (mp);
16845
16846   /* Wait for a reply... */
16847   W (ret);
16848   return ret;
16849 }
16850
16851 static int
16852 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16853 {
16854   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16855   int ret;
16856
16857   if (!vam->json_output)
16858     {
16859       print (vam->ofp, "VNIs");
16860     }
16861
16862   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16863
16864   /* send it... */
16865   S (mp);
16866
16867   /* Wait for a reply... */
16868   W (ret);
16869   return ret;
16870 }
16871
16872 static int
16873 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16874 {
16875   unformat_input_t *i = vam->input;
16876   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16877   int ret = 0;
16878   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16879   struct in_addr ip4;
16880   struct in6_addr ip6;
16881   u32 table_id = 0, nh_sw_if_index = ~0;
16882
16883   clib_memset (&ip4, 0, sizeof (ip4));
16884   clib_memset (&ip6, 0, sizeof (ip6));
16885
16886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16887     {
16888       if (unformat (i, "del"))
16889         is_add = 0;
16890       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16891                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16892         {
16893           ip_set = 1;
16894           is_ip4 = 1;
16895         }
16896       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16897                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16898         {
16899           ip_set = 1;
16900           is_ip4 = 0;
16901         }
16902       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16903         {
16904           ip_set = 1;
16905           is_ip4 = 1;
16906           nh_sw_if_index = ~0;
16907         }
16908       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16909         {
16910           ip_set = 1;
16911           is_ip4 = 0;
16912           nh_sw_if_index = ~0;
16913         }
16914       else if (unformat (i, "table %d", &table_id))
16915         ;
16916       else
16917         {
16918           errmsg ("parse error '%U'", format_unformat_error, i);
16919           return -99;
16920         }
16921     }
16922
16923   if (!ip_set)
16924     {
16925       errmsg ("nh addr not set!");
16926       return -99;
16927     }
16928
16929   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16930   mp->is_add = is_add;
16931   mp->table_id = clib_host_to_net_u32 (table_id);
16932   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16933   mp->nh_addr.af = is_ip4 ? 0 : 1;
16934   if (is_ip4)
16935     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16936   else
16937     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16938
16939   /* send it... */
16940   S (mp);
16941
16942   /* Wait for a reply... */
16943   W (ret);
16944   return ret;
16945 }
16946
16947 static int
16948 api_one_map_server_dump (vat_main_t * vam)
16949 {
16950   vl_api_one_map_server_dump_t *mp;
16951   vl_api_control_ping_t *mp_ping;
16952   int ret;
16953
16954   if (!vam->json_output)
16955     {
16956       print (vam->ofp, "%=20s", "Map server");
16957     }
16958
16959   M (ONE_MAP_SERVER_DUMP, mp);
16960   /* send it... */
16961   S (mp);
16962
16963   /* Use a control ping for synchronization */
16964   MPING (CONTROL_PING, mp_ping);
16965   S (mp_ping);
16966
16967   /* Wait for a reply... */
16968   W (ret);
16969   return ret;
16970 }
16971
16972 #define api_lisp_map_server_dump api_one_map_server_dump
16973
16974 static int
16975 api_one_map_resolver_dump (vat_main_t * vam)
16976 {
16977   vl_api_one_map_resolver_dump_t *mp;
16978   vl_api_control_ping_t *mp_ping;
16979   int ret;
16980
16981   if (!vam->json_output)
16982     {
16983       print (vam->ofp, "%=20s", "Map resolver");
16984     }
16985
16986   M (ONE_MAP_RESOLVER_DUMP, mp);
16987   /* send it... */
16988   S (mp);
16989
16990   /* Use a control ping for synchronization */
16991   MPING (CONTROL_PING, mp_ping);
16992   S (mp_ping);
16993
16994   /* Wait for a reply... */
16995   W (ret);
16996   return ret;
16997 }
16998
16999 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17000
17001 static int
17002 api_one_stats_flush (vat_main_t * vam)
17003 {
17004   vl_api_one_stats_flush_t *mp;
17005   int ret = 0;
17006
17007   M (ONE_STATS_FLUSH, mp);
17008   S (mp);
17009   W (ret);
17010   return ret;
17011 }
17012
17013 static int
17014 api_one_stats_dump (vat_main_t * vam)
17015 {
17016   vl_api_one_stats_dump_t *mp;
17017   vl_api_control_ping_t *mp_ping;
17018   int ret;
17019
17020   M (ONE_STATS_DUMP, mp);
17021   /* send it... */
17022   S (mp);
17023
17024   /* Use a control ping for synchronization */
17025   MPING (CONTROL_PING, mp_ping);
17026   S (mp_ping);
17027
17028   /* Wait for a reply... */
17029   W (ret);
17030   return ret;
17031 }
17032
17033 static int
17034 api_show_one_status (vat_main_t * vam)
17035 {
17036   vl_api_show_one_status_t *mp;
17037   int ret;
17038
17039   if (!vam->json_output)
17040     {
17041       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17042     }
17043
17044   M (SHOW_ONE_STATUS, mp);
17045   /* send it... */
17046   S (mp);
17047   /* Wait for a reply... */
17048   W (ret);
17049   return ret;
17050 }
17051
17052 #define api_show_lisp_status api_show_one_status
17053
17054 static int
17055 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17056 {
17057   vl_api_gpe_fwd_entry_path_dump_t *mp;
17058   vl_api_control_ping_t *mp_ping;
17059   unformat_input_t *i = vam->input;
17060   u32 fwd_entry_index = ~0;
17061   int ret;
17062
17063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17064     {
17065       if (unformat (i, "index %d", &fwd_entry_index))
17066         ;
17067       else
17068         break;
17069     }
17070
17071   if (~0 == fwd_entry_index)
17072     {
17073       errmsg ("no index specified!");
17074       return -99;
17075     }
17076
17077   if (!vam->json_output)
17078     {
17079       print (vam->ofp, "first line");
17080     }
17081
17082   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17083
17084   /* send it... */
17085   S (mp);
17086   /* Use a control ping for synchronization */
17087   MPING (CONTROL_PING, mp_ping);
17088   S (mp_ping);
17089
17090   /* Wait for a reply... */
17091   W (ret);
17092   return ret;
17093 }
17094
17095 static int
17096 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17097 {
17098   vl_api_one_get_map_request_itr_rlocs_t *mp;
17099   int ret;
17100
17101   if (!vam->json_output)
17102     {
17103       print (vam->ofp, "%=20s", "itr-rlocs:");
17104     }
17105
17106   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17107   /* send it... */
17108   S (mp);
17109   /* Wait for a reply... */
17110   W (ret);
17111   return ret;
17112 }
17113
17114 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17115
17116 static int
17117 api_af_packet_create (vat_main_t * vam)
17118 {
17119   unformat_input_t *i = vam->input;
17120   vl_api_af_packet_create_t *mp;
17121   u8 *host_if_name = 0;
17122   u8 hw_addr[6];
17123   u8 random_hw_addr = 1;
17124   int ret;
17125
17126   clib_memset (hw_addr, 0, sizeof (hw_addr));
17127
17128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17129     {
17130       if (unformat (i, "name %s", &host_if_name))
17131         vec_add1 (host_if_name, 0);
17132       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17133         random_hw_addr = 0;
17134       else
17135         break;
17136     }
17137
17138   if (!vec_len (host_if_name))
17139     {
17140       errmsg ("host-interface name must be specified");
17141       return -99;
17142     }
17143
17144   if (vec_len (host_if_name) > 64)
17145     {
17146       errmsg ("host-interface name too long");
17147       return -99;
17148     }
17149
17150   M (AF_PACKET_CREATE, mp);
17151
17152   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17153   clib_memcpy (mp->hw_addr, hw_addr, 6);
17154   mp->use_random_hw_addr = random_hw_addr;
17155   vec_free (host_if_name);
17156
17157   S (mp);
17158
17159   /* *INDENT-OFF* */
17160   W2 (ret,
17161       ({
17162         if (ret == 0)
17163           fprintf (vam->ofp ? vam->ofp : stderr,
17164                    " new sw_if_index = %d\n", vam->sw_if_index);
17165       }));
17166   /* *INDENT-ON* */
17167   return ret;
17168 }
17169
17170 static int
17171 api_af_packet_delete (vat_main_t * vam)
17172 {
17173   unformat_input_t *i = vam->input;
17174   vl_api_af_packet_delete_t *mp;
17175   u8 *host_if_name = 0;
17176   int ret;
17177
17178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17179     {
17180       if (unformat (i, "name %s", &host_if_name))
17181         vec_add1 (host_if_name, 0);
17182       else
17183         break;
17184     }
17185
17186   if (!vec_len (host_if_name))
17187     {
17188       errmsg ("host-interface name must be specified");
17189       return -99;
17190     }
17191
17192   if (vec_len (host_if_name) > 64)
17193     {
17194       errmsg ("host-interface name too long");
17195       return -99;
17196     }
17197
17198   M (AF_PACKET_DELETE, mp);
17199
17200   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17201   vec_free (host_if_name);
17202
17203   S (mp);
17204   W (ret);
17205   return ret;
17206 }
17207
17208 static void vl_api_af_packet_details_t_handler
17209   (vl_api_af_packet_details_t * mp)
17210 {
17211   vat_main_t *vam = &vat_main;
17212
17213   print (vam->ofp, "%-16s %d",
17214          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17215 }
17216
17217 static void vl_api_af_packet_details_t_handler_json
17218   (vl_api_af_packet_details_t * mp)
17219 {
17220   vat_main_t *vam = &vat_main;
17221   vat_json_node_t *node = NULL;
17222
17223   if (VAT_JSON_ARRAY != vam->json_tree.type)
17224     {
17225       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17226       vat_json_init_array (&vam->json_tree);
17227     }
17228   node = vat_json_array_add (&vam->json_tree);
17229
17230   vat_json_init_object (node);
17231   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17232   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17233 }
17234
17235 static int
17236 api_af_packet_dump (vat_main_t * vam)
17237 {
17238   vl_api_af_packet_dump_t *mp;
17239   vl_api_control_ping_t *mp_ping;
17240   int ret;
17241
17242   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17243   /* Get list of tap interfaces */
17244   M (AF_PACKET_DUMP, mp);
17245   S (mp);
17246
17247   /* Use a control ping for synchronization */
17248   MPING (CONTROL_PING, mp_ping);
17249   S (mp_ping);
17250
17251   W (ret);
17252   return ret;
17253 }
17254
17255 static int
17256 api_policer_add_del (vat_main_t * vam)
17257 {
17258   unformat_input_t *i = vam->input;
17259   vl_api_policer_add_del_t *mp;
17260   u8 is_add = 1;
17261   u8 *name = 0;
17262   u32 cir = 0;
17263   u32 eir = 0;
17264   u64 cb = 0;
17265   u64 eb = 0;
17266   u8 rate_type = 0;
17267   u8 round_type = 0;
17268   u8 type = 0;
17269   u8 color_aware = 0;
17270   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17271   int ret;
17272
17273   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17274   conform_action.dscp = 0;
17275   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17276   exceed_action.dscp = 0;
17277   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17278   violate_action.dscp = 0;
17279
17280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17281     {
17282       if (unformat (i, "del"))
17283         is_add = 0;
17284       else if (unformat (i, "name %s", &name))
17285         vec_add1 (name, 0);
17286       else if (unformat (i, "cir %u", &cir))
17287         ;
17288       else if (unformat (i, "eir %u", &eir))
17289         ;
17290       else if (unformat (i, "cb %u", &cb))
17291         ;
17292       else if (unformat (i, "eb %u", &eb))
17293         ;
17294       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17295                          &rate_type))
17296         ;
17297       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17298                          &round_type))
17299         ;
17300       else if (unformat (i, "type %U", unformat_policer_type, &type))
17301         ;
17302       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17303                          &conform_action))
17304         ;
17305       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17306                          &exceed_action))
17307         ;
17308       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17309                          &violate_action))
17310         ;
17311       else if (unformat (i, "color-aware"))
17312         color_aware = 1;
17313       else
17314         break;
17315     }
17316
17317   if (!vec_len (name))
17318     {
17319       errmsg ("policer name must be specified");
17320       return -99;
17321     }
17322
17323   if (vec_len (name) > 64)
17324     {
17325       errmsg ("policer name too long");
17326       return -99;
17327     }
17328
17329   M (POLICER_ADD_DEL, mp);
17330
17331   clib_memcpy (mp->name, name, vec_len (name));
17332   vec_free (name);
17333   mp->is_add = is_add;
17334   mp->cir = ntohl (cir);
17335   mp->eir = ntohl (eir);
17336   mp->cb = clib_net_to_host_u64 (cb);
17337   mp->eb = clib_net_to_host_u64 (eb);
17338   mp->rate_type = rate_type;
17339   mp->round_type = round_type;
17340   mp->type = type;
17341   mp->conform_action.type = conform_action.action_type;
17342   mp->conform_action.dscp = conform_action.dscp;
17343   mp->exceed_action.type = exceed_action.action_type;
17344   mp->exceed_action.dscp = exceed_action.dscp;
17345   mp->violate_action.type = violate_action.action_type;
17346   mp->violate_action.dscp = violate_action.dscp;
17347   mp->color_aware = color_aware;
17348
17349   S (mp);
17350   W (ret);
17351   return ret;
17352 }
17353
17354 static int
17355 api_policer_dump (vat_main_t * vam)
17356 {
17357   unformat_input_t *i = vam->input;
17358   vl_api_policer_dump_t *mp;
17359   vl_api_control_ping_t *mp_ping;
17360   u8 *match_name = 0;
17361   u8 match_name_valid = 0;
17362   int ret;
17363
17364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17365     {
17366       if (unformat (i, "name %s", &match_name))
17367         {
17368           vec_add1 (match_name, 0);
17369           match_name_valid = 1;
17370         }
17371       else
17372         break;
17373     }
17374
17375   M (POLICER_DUMP, mp);
17376   mp->match_name_valid = match_name_valid;
17377   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17378   vec_free (match_name);
17379   /* send it... */
17380   S (mp);
17381
17382   /* Use a control ping for synchronization */
17383   MPING (CONTROL_PING, mp_ping);
17384   S (mp_ping);
17385
17386   /* Wait for a reply... */
17387   W (ret);
17388   return ret;
17389 }
17390
17391 static int
17392 api_policer_classify_set_interface (vat_main_t * vam)
17393 {
17394   unformat_input_t *i = vam->input;
17395   vl_api_policer_classify_set_interface_t *mp;
17396   u32 sw_if_index;
17397   int sw_if_index_set;
17398   u32 ip4_table_index = ~0;
17399   u32 ip6_table_index = ~0;
17400   u32 l2_table_index = ~0;
17401   u8 is_add = 1;
17402   int ret;
17403
17404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17405     {
17406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17407         sw_if_index_set = 1;
17408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17409         sw_if_index_set = 1;
17410       else if (unformat (i, "del"))
17411         is_add = 0;
17412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17413         ;
17414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17415         ;
17416       else if (unformat (i, "l2-table %d", &l2_table_index))
17417         ;
17418       else
17419         {
17420           clib_warning ("parse error '%U'", format_unformat_error, i);
17421           return -99;
17422         }
17423     }
17424
17425   if (sw_if_index_set == 0)
17426     {
17427       errmsg ("missing interface name or sw_if_index");
17428       return -99;
17429     }
17430
17431   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17432
17433   mp->sw_if_index = ntohl (sw_if_index);
17434   mp->ip4_table_index = ntohl (ip4_table_index);
17435   mp->ip6_table_index = ntohl (ip6_table_index);
17436   mp->l2_table_index = ntohl (l2_table_index);
17437   mp->is_add = is_add;
17438
17439   S (mp);
17440   W (ret);
17441   return ret;
17442 }
17443
17444 static int
17445 api_policer_classify_dump (vat_main_t * vam)
17446 {
17447   unformat_input_t *i = vam->input;
17448   vl_api_policer_classify_dump_t *mp;
17449   vl_api_control_ping_t *mp_ping;
17450   u8 type = POLICER_CLASSIFY_N_TABLES;
17451   int ret;
17452
17453   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17454     ;
17455   else
17456     {
17457       errmsg ("classify table type must be specified");
17458       return -99;
17459     }
17460
17461   if (!vam->json_output)
17462     {
17463       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17464     }
17465
17466   M (POLICER_CLASSIFY_DUMP, mp);
17467   mp->type = type;
17468   /* send it... */
17469   S (mp);
17470
17471   /* Use a control ping for synchronization */
17472   MPING (CONTROL_PING, mp_ping);
17473   S (mp_ping);
17474
17475   /* Wait for a reply... */
17476   W (ret);
17477   return ret;
17478 }
17479
17480 static u8 *
17481 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17482 {
17483   vl_api_fib_path_nh_proto_t proto =
17484     va_arg (*args, vl_api_fib_path_nh_proto_t);
17485
17486   switch (proto)
17487     {
17488     case FIB_API_PATH_NH_PROTO_IP4:
17489       s = format (s, "ip4");
17490       break;
17491     case FIB_API_PATH_NH_PROTO_IP6:
17492       s = format (s, "ip6");
17493       break;
17494     case FIB_API_PATH_NH_PROTO_MPLS:
17495       s = format (s, "mpls");
17496       break;
17497     case FIB_API_PATH_NH_PROTO_BIER:
17498       s = format (s, "bier");
17499       break;
17500     case FIB_API_PATH_NH_PROTO_ETHERNET:
17501       s = format (s, "ethernet");
17502       break;
17503     }
17504
17505   return (s);
17506 }
17507
17508 static u8 *
17509 format_vl_api_ip_address_union (u8 * s, va_list * args)
17510 {
17511   vl_api_address_family_t af = va_arg (*args, int);
17512   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17513
17514   switch (af)
17515     {
17516     case ADDRESS_IP4:
17517       s = format (s, "%U", format_ip4_address, u->ip4);
17518       break;
17519     case ADDRESS_IP6:
17520       s = format (s, "%U", format_ip6_address, u->ip6);
17521       break;
17522     }
17523   return (s);
17524 }
17525
17526 static u8 *
17527 format_vl_api_fib_path_type (u8 * s, va_list * args)
17528 {
17529   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17530
17531   switch (t)
17532     {
17533     case FIB_API_PATH_TYPE_NORMAL:
17534       s = format (s, "normal");
17535       break;
17536     case FIB_API_PATH_TYPE_LOCAL:
17537       s = format (s, "local");
17538       break;
17539     case FIB_API_PATH_TYPE_DROP:
17540       s = format (s, "drop");
17541       break;
17542     case FIB_API_PATH_TYPE_UDP_ENCAP:
17543       s = format (s, "udp-encap");
17544       break;
17545     case FIB_API_PATH_TYPE_BIER_IMP:
17546       s = format (s, "bier-imp");
17547       break;
17548     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17549       s = format (s, "unreach");
17550       break;
17551     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17552       s = format (s, "prohibit");
17553       break;
17554     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17555       s = format (s, "src-lookup");
17556       break;
17557     case FIB_API_PATH_TYPE_DVR:
17558       s = format (s, "dvr");
17559       break;
17560     case FIB_API_PATH_TYPE_INTERFACE_RX:
17561       s = format (s, "interface-rx");
17562       break;
17563     case FIB_API_PATH_TYPE_CLASSIFY:
17564       s = format (s, "classify");
17565       break;
17566     }
17567
17568   return (s);
17569 }
17570
17571 static void
17572 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17573 {
17574   print (vam->ofp,
17575          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17576          ntohl (fp->weight), ntohl (fp->sw_if_index),
17577          format_vl_api_fib_path_type, fp->type,
17578          format_fib_api_path_nh_proto, fp->proto,
17579          format_vl_api_ip_address_union, &fp->nh.address);
17580 }
17581
17582 static void
17583 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17584                                  vl_api_fib_path_t * fp)
17585 {
17586   struct in_addr ip4;
17587   struct in6_addr ip6;
17588
17589   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17590   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17591   vat_json_object_add_uint (node, "type", fp->type);
17592   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17593   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17594     {
17595       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17596       vat_json_object_add_ip4 (node, "next_hop", ip4);
17597     }
17598   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17599     {
17600       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17601       vat_json_object_add_ip6 (node, "next_hop", ip6);
17602     }
17603 }
17604
17605 static void
17606 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17607 {
17608   vat_main_t *vam = &vat_main;
17609   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17610   vl_api_fib_path_t *fp;
17611   i32 i;
17612
17613   print (vam->ofp, "sw_if_index %d via:",
17614          ntohl (mp->mt_tunnel.mt_sw_if_index));
17615   fp = mp->mt_tunnel.mt_paths;
17616   for (i = 0; i < count; i++)
17617     {
17618       vl_api_fib_path_print (vam, fp);
17619       fp++;
17620     }
17621
17622   print (vam->ofp, "");
17623 }
17624
17625 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17626 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17627
17628 static void
17629 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17630 {
17631   vat_main_t *vam = &vat_main;
17632   vat_json_node_t *node = NULL;
17633   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17634   vl_api_fib_path_t *fp;
17635   i32 i;
17636
17637   if (VAT_JSON_ARRAY != vam->json_tree.type)
17638     {
17639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17640       vat_json_init_array (&vam->json_tree);
17641     }
17642   node = vat_json_array_add (&vam->json_tree);
17643
17644   vat_json_init_object (node);
17645   vat_json_object_add_uint (node, "sw_if_index",
17646                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17647
17648   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17649
17650   fp = mp->mt_tunnel.mt_paths;
17651   for (i = 0; i < count; i++)
17652     {
17653       vl_api_mpls_fib_path_json_print (node, fp);
17654       fp++;
17655     }
17656 }
17657
17658 static int
17659 api_mpls_tunnel_dump (vat_main_t * vam)
17660 {
17661   vl_api_mpls_tunnel_dump_t *mp;
17662   vl_api_control_ping_t *mp_ping;
17663   int ret;
17664
17665   M (MPLS_TUNNEL_DUMP, mp);
17666
17667   S (mp);
17668
17669   /* Use a control ping for synchronization */
17670   MPING (CONTROL_PING, mp_ping);
17671   S (mp_ping);
17672
17673   W (ret);
17674   return ret;
17675 }
17676
17677 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17678 #define vl_api_mpls_table_details_t_print vl_noop_handler
17679
17680
17681 static void
17682 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17683 {
17684   vat_main_t *vam = &vat_main;
17685
17686   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17687 }
17688
17689 static void vl_api_mpls_table_details_t_handler_json
17690   (vl_api_mpls_table_details_t * mp)
17691 {
17692   vat_main_t *vam = &vat_main;
17693   vat_json_node_t *node = NULL;
17694
17695   if (VAT_JSON_ARRAY != vam->json_tree.type)
17696     {
17697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17698       vat_json_init_array (&vam->json_tree);
17699     }
17700   node = vat_json_array_add (&vam->json_tree);
17701
17702   vat_json_init_object (node);
17703   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17704 }
17705
17706 static int
17707 api_mpls_table_dump (vat_main_t * vam)
17708 {
17709   vl_api_mpls_table_dump_t *mp;
17710   vl_api_control_ping_t *mp_ping;
17711   int ret;
17712
17713   M (MPLS_TABLE_DUMP, mp);
17714   S (mp);
17715
17716   /* Use a control ping for synchronization */
17717   MPING (CONTROL_PING, mp_ping);
17718   S (mp_ping);
17719
17720   W (ret);
17721   return ret;
17722 }
17723
17724 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17725 #define vl_api_mpls_route_details_t_print vl_noop_handler
17726
17727 static void
17728 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17729 {
17730   vat_main_t *vam = &vat_main;
17731   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17732   vl_api_fib_path_t *fp;
17733   int i;
17734
17735   print (vam->ofp,
17736          "table-id %d, label %u, ess_bit %u",
17737          ntohl (mp->mr_route.mr_table_id),
17738          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17739   fp = mp->mr_route.mr_paths;
17740   for (i = 0; i < count; i++)
17741     {
17742       vl_api_fib_path_print (vam, fp);
17743       fp++;
17744     }
17745 }
17746
17747 static void vl_api_mpls_route_details_t_handler_json
17748   (vl_api_mpls_route_details_t * mp)
17749 {
17750   vat_main_t *vam = &vat_main;
17751   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17752   vat_json_node_t *node = NULL;
17753   vl_api_fib_path_t *fp;
17754   int i;
17755
17756   if (VAT_JSON_ARRAY != vam->json_tree.type)
17757     {
17758       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17759       vat_json_init_array (&vam->json_tree);
17760     }
17761   node = vat_json_array_add (&vam->json_tree);
17762
17763   vat_json_init_object (node);
17764   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17765   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17766   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17767   vat_json_object_add_uint (node, "path_count", count);
17768   fp = mp->mr_route.mr_paths;
17769   for (i = 0; i < count; i++)
17770     {
17771       vl_api_mpls_fib_path_json_print (node, fp);
17772       fp++;
17773     }
17774 }
17775
17776 static int
17777 api_mpls_route_dump (vat_main_t * vam)
17778 {
17779   unformat_input_t *input = vam->input;
17780   vl_api_mpls_route_dump_t *mp;
17781   vl_api_control_ping_t *mp_ping;
17782   u32 table_id;
17783   int ret;
17784
17785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17786     {
17787       if (unformat (input, "table_id %d", &table_id))
17788         ;
17789       else
17790         break;
17791     }
17792   if (table_id == ~0)
17793     {
17794       errmsg ("missing table id");
17795       return -99;
17796     }
17797
17798   M (MPLS_ROUTE_DUMP, mp);
17799
17800   mp->table.mt_table_id = ntohl (table_id);
17801   S (mp);
17802
17803   /* Use a control ping for synchronization */
17804   MPING (CONTROL_PING, mp_ping);
17805   S (mp_ping);
17806
17807   W (ret);
17808   return ret;
17809 }
17810
17811 #define vl_api_ip_table_details_t_endian vl_noop_handler
17812 #define vl_api_ip_table_details_t_print vl_noop_handler
17813
17814 static void
17815 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17816 {
17817   vat_main_t *vam = &vat_main;
17818
17819   print (vam->ofp,
17820          "%s; table-id %d, prefix %U/%d",
17821          mp->table.name, ntohl (mp->table.table_id));
17822 }
17823
17824
17825 static void vl_api_ip_table_details_t_handler_json
17826   (vl_api_ip_table_details_t * mp)
17827 {
17828   vat_main_t *vam = &vat_main;
17829   vat_json_node_t *node = NULL;
17830
17831   if (VAT_JSON_ARRAY != vam->json_tree.type)
17832     {
17833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17834       vat_json_init_array (&vam->json_tree);
17835     }
17836   node = vat_json_array_add (&vam->json_tree);
17837
17838   vat_json_init_object (node);
17839   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17840 }
17841
17842 static int
17843 api_ip_table_dump (vat_main_t * vam)
17844 {
17845   vl_api_ip_table_dump_t *mp;
17846   vl_api_control_ping_t *mp_ping;
17847   int ret;
17848
17849   M (IP_TABLE_DUMP, mp);
17850   S (mp);
17851
17852   /* Use a control ping for synchronization */
17853   MPING (CONTROL_PING, mp_ping);
17854   S (mp_ping);
17855
17856   W (ret);
17857   return ret;
17858 }
17859
17860 static int
17861 api_ip_mtable_dump (vat_main_t * vam)
17862 {
17863   vl_api_ip_mtable_dump_t *mp;
17864   vl_api_control_ping_t *mp_ping;
17865   int ret;
17866
17867   M (IP_MTABLE_DUMP, mp);
17868   S (mp);
17869
17870   /* Use a control ping for synchronization */
17871   MPING (CONTROL_PING, mp_ping);
17872   S (mp_ping);
17873
17874   W (ret);
17875   return ret;
17876 }
17877
17878 static int
17879 api_ip_mroute_dump (vat_main_t * vam)
17880 {
17881   unformat_input_t *input = vam->input;
17882   vl_api_control_ping_t *mp_ping;
17883   vl_api_ip_mroute_dump_t *mp;
17884   int ret, is_ip6;
17885   u32 table_id;
17886
17887   is_ip6 = 0;
17888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17889     {
17890       if (unformat (input, "table_id %d", &table_id))
17891         ;
17892       else if (unformat (input, "ip6"))
17893         is_ip6 = 1;
17894       else if (unformat (input, "ip4"))
17895         is_ip6 = 0;
17896       else
17897         break;
17898     }
17899   if (table_id == ~0)
17900     {
17901       errmsg ("missing table id");
17902       return -99;
17903     }
17904
17905   M (IP_MROUTE_DUMP, mp);
17906   mp->table.table_id = table_id;
17907   mp->table.is_ip6 = is_ip6;
17908   S (mp);
17909
17910   /* Use a control ping for synchronization */
17911   MPING (CONTROL_PING, mp_ping);
17912   S (mp_ping);
17913
17914   W (ret);
17915   return ret;
17916 }
17917
17918 #define vl_api_ip_route_details_t_endian vl_noop_handler
17919 #define vl_api_ip_route_details_t_print vl_noop_handler
17920
17921 static void
17922 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17923 {
17924   vat_main_t *vam = &vat_main;
17925   u8 count = mp->route.n_paths;
17926   vl_api_fib_path_t *fp;
17927   int i;
17928
17929   print (vam->ofp,
17930          "table-id %d, prefix %U/%d",
17931          ntohl (mp->route.table_id),
17932          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17933   for (i = 0; i < count; i++)
17934     {
17935       fp = &mp->route.paths[i];
17936
17937       vl_api_fib_path_print (vam, fp);
17938       fp++;
17939     }
17940 }
17941
17942 static void vl_api_ip_route_details_t_handler_json
17943   (vl_api_ip_route_details_t * mp)
17944 {
17945   vat_main_t *vam = &vat_main;
17946   u8 count = mp->route.n_paths;
17947   vat_json_node_t *node = NULL;
17948   struct in_addr ip4;
17949   struct in6_addr ip6;
17950   vl_api_fib_path_t *fp;
17951   int i;
17952
17953   if (VAT_JSON_ARRAY != vam->json_tree.type)
17954     {
17955       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17956       vat_json_init_array (&vam->json_tree);
17957     }
17958   node = vat_json_array_add (&vam->json_tree);
17959
17960   vat_json_init_object (node);
17961   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17962   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17963     {
17964       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17965       vat_json_object_add_ip6 (node, "prefix", ip6);
17966     }
17967   else
17968     {
17969       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17970       vat_json_object_add_ip4 (node, "prefix", ip4);
17971     }
17972   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17973   vat_json_object_add_uint (node, "path_count", count);
17974   for (i = 0; i < count; i++)
17975     {
17976       fp = &mp->route.paths[i];
17977       vl_api_mpls_fib_path_json_print (node, fp);
17978     }
17979 }
17980
17981 static int
17982 api_ip_route_dump (vat_main_t * vam)
17983 {
17984   unformat_input_t *input = vam->input;
17985   vl_api_ip_route_dump_t *mp;
17986   vl_api_control_ping_t *mp_ping;
17987   u32 table_id;
17988   u8 is_ip6;
17989   int ret;
17990
17991   is_ip6 = 0;
17992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17993     {
17994       if (unformat (input, "table_id %d", &table_id))
17995         ;
17996       else if (unformat (input, "ip6"))
17997         is_ip6 = 1;
17998       else if (unformat (input, "ip4"))
17999         is_ip6 = 0;
18000       else
18001         break;
18002     }
18003   if (table_id == ~0)
18004     {
18005       errmsg ("missing table id");
18006       return -99;
18007     }
18008
18009   M (IP_ROUTE_DUMP, mp);
18010
18011   mp->table.table_id = table_id;
18012   mp->table.is_ip6 = is_ip6;
18013
18014   S (mp);
18015
18016   /* Use a control ping for synchronization */
18017   MPING (CONTROL_PING, mp_ping);
18018   S (mp_ping);
18019
18020   W (ret);
18021   return ret;
18022 }
18023
18024 int
18025 api_classify_table_ids (vat_main_t * vam)
18026 {
18027   vl_api_classify_table_ids_t *mp;
18028   int ret;
18029
18030   /* Construct the API message */
18031   M (CLASSIFY_TABLE_IDS, mp);
18032   mp->context = 0;
18033
18034   S (mp);
18035   W (ret);
18036   return ret;
18037 }
18038
18039 int
18040 api_classify_table_by_interface (vat_main_t * vam)
18041 {
18042   unformat_input_t *input = vam->input;
18043   vl_api_classify_table_by_interface_t *mp;
18044
18045   u32 sw_if_index = ~0;
18046   int ret;
18047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18048     {
18049       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18050         ;
18051       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18052         ;
18053       else
18054         break;
18055     }
18056   if (sw_if_index == ~0)
18057     {
18058       errmsg ("missing interface name or sw_if_index");
18059       return -99;
18060     }
18061
18062   /* Construct the API message */
18063   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18064   mp->context = 0;
18065   mp->sw_if_index = ntohl (sw_if_index);
18066
18067   S (mp);
18068   W (ret);
18069   return ret;
18070 }
18071
18072 int
18073 api_classify_table_info (vat_main_t * vam)
18074 {
18075   unformat_input_t *input = vam->input;
18076   vl_api_classify_table_info_t *mp;
18077
18078   u32 table_id = ~0;
18079   int ret;
18080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18081     {
18082       if (unformat (input, "table_id %d", &table_id))
18083         ;
18084       else
18085         break;
18086     }
18087   if (table_id == ~0)
18088     {
18089       errmsg ("missing table id");
18090       return -99;
18091     }
18092
18093   /* Construct the API message */
18094   M (CLASSIFY_TABLE_INFO, mp);
18095   mp->context = 0;
18096   mp->table_id = ntohl (table_id);
18097
18098   S (mp);
18099   W (ret);
18100   return ret;
18101 }
18102
18103 int
18104 api_classify_session_dump (vat_main_t * vam)
18105 {
18106   unformat_input_t *input = vam->input;
18107   vl_api_classify_session_dump_t *mp;
18108   vl_api_control_ping_t *mp_ping;
18109
18110   u32 table_id = ~0;
18111   int ret;
18112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18113     {
18114       if (unformat (input, "table_id %d", &table_id))
18115         ;
18116       else
18117         break;
18118     }
18119   if (table_id == ~0)
18120     {
18121       errmsg ("missing table id");
18122       return -99;
18123     }
18124
18125   /* Construct the API message */
18126   M (CLASSIFY_SESSION_DUMP, mp);
18127   mp->context = 0;
18128   mp->table_id = ntohl (table_id);
18129   S (mp);
18130
18131   /* Use a control ping for synchronization */
18132   MPING (CONTROL_PING, mp_ping);
18133   S (mp_ping);
18134
18135   W (ret);
18136   return ret;
18137 }
18138
18139 static void
18140 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18141 {
18142   vat_main_t *vam = &vat_main;
18143
18144   print (vam->ofp, "collector_address %U, collector_port %d, "
18145          "src_address %U, vrf_id %d, path_mtu %u, "
18146          "template_interval %u, udp_checksum %d",
18147          format_ip4_address, mp->collector_address,
18148          ntohs (mp->collector_port),
18149          format_ip4_address, mp->src_address,
18150          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18151          ntohl (mp->template_interval), mp->udp_checksum);
18152
18153   vam->retval = 0;
18154   vam->result_ready = 1;
18155 }
18156
18157 static void
18158   vl_api_ipfix_exporter_details_t_handler_json
18159   (vl_api_ipfix_exporter_details_t * mp)
18160 {
18161   vat_main_t *vam = &vat_main;
18162   vat_json_node_t node;
18163   struct in_addr collector_address;
18164   struct in_addr src_address;
18165
18166   vat_json_init_object (&node);
18167   clib_memcpy (&collector_address, &mp->collector_address,
18168                sizeof (collector_address));
18169   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18170   vat_json_object_add_uint (&node, "collector_port",
18171                             ntohs (mp->collector_port));
18172   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18173   vat_json_object_add_ip4 (&node, "src_address", src_address);
18174   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18175   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18176   vat_json_object_add_uint (&node, "template_interval",
18177                             ntohl (mp->template_interval));
18178   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18179
18180   vat_json_print (vam->ofp, &node);
18181   vat_json_free (&node);
18182   vam->retval = 0;
18183   vam->result_ready = 1;
18184 }
18185
18186 int
18187 api_ipfix_exporter_dump (vat_main_t * vam)
18188 {
18189   vl_api_ipfix_exporter_dump_t *mp;
18190   int ret;
18191
18192   /* Construct the API message */
18193   M (IPFIX_EXPORTER_DUMP, mp);
18194   mp->context = 0;
18195
18196   S (mp);
18197   W (ret);
18198   return ret;
18199 }
18200
18201 static int
18202 api_ipfix_classify_stream_dump (vat_main_t * vam)
18203 {
18204   vl_api_ipfix_classify_stream_dump_t *mp;
18205   int ret;
18206
18207   /* Construct the API message */
18208   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18209   mp->context = 0;
18210
18211   S (mp);
18212   W (ret);
18213   return ret;
18214   /* NOTREACHED */
18215   return 0;
18216 }
18217
18218 static void
18219   vl_api_ipfix_classify_stream_details_t_handler
18220   (vl_api_ipfix_classify_stream_details_t * mp)
18221 {
18222   vat_main_t *vam = &vat_main;
18223   print (vam->ofp, "domain_id %d, src_port %d",
18224          ntohl (mp->domain_id), ntohs (mp->src_port));
18225   vam->retval = 0;
18226   vam->result_ready = 1;
18227 }
18228
18229 static void
18230   vl_api_ipfix_classify_stream_details_t_handler_json
18231   (vl_api_ipfix_classify_stream_details_t * mp)
18232 {
18233   vat_main_t *vam = &vat_main;
18234   vat_json_node_t node;
18235
18236   vat_json_init_object (&node);
18237   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18238   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18239
18240   vat_json_print (vam->ofp, &node);
18241   vat_json_free (&node);
18242   vam->retval = 0;
18243   vam->result_ready = 1;
18244 }
18245
18246 static int
18247 api_ipfix_classify_table_dump (vat_main_t * vam)
18248 {
18249   vl_api_ipfix_classify_table_dump_t *mp;
18250   vl_api_control_ping_t *mp_ping;
18251   int ret;
18252
18253   if (!vam->json_output)
18254     {
18255       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18256              "transport_protocol");
18257     }
18258
18259   /* Construct the API message */
18260   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18261
18262   /* send it... */
18263   S (mp);
18264
18265   /* Use a control ping for synchronization */
18266   MPING (CONTROL_PING, mp_ping);
18267   S (mp_ping);
18268
18269   W (ret);
18270   return ret;
18271 }
18272
18273 static void
18274   vl_api_ipfix_classify_table_details_t_handler
18275   (vl_api_ipfix_classify_table_details_t * mp)
18276 {
18277   vat_main_t *vam = &vat_main;
18278   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18279          mp->transport_protocol);
18280 }
18281
18282 static void
18283   vl_api_ipfix_classify_table_details_t_handler_json
18284   (vl_api_ipfix_classify_table_details_t * mp)
18285 {
18286   vat_json_node_t *node = NULL;
18287   vat_main_t *vam = &vat_main;
18288
18289   if (VAT_JSON_ARRAY != vam->json_tree.type)
18290     {
18291       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18292       vat_json_init_array (&vam->json_tree);
18293     }
18294
18295   node = vat_json_array_add (&vam->json_tree);
18296   vat_json_init_object (node);
18297
18298   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18299   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18300   vat_json_object_add_uint (node, "transport_protocol",
18301                             mp->transport_protocol);
18302 }
18303
18304 static int
18305 api_sw_interface_span_enable_disable (vat_main_t * vam)
18306 {
18307   unformat_input_t *i = vam->input;
18308   vl_api_sw_interface_span_enable_disable_t *mp;
18309   u32 src_sw_if_index = ~0;
18310   u32 dst_sw_if_index = ~0;
18311   u8 state = 3;
18312   int ret;
18313   u8 is_l2 = 0;
18314
18315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18316     {
18317       if (unformat
18318           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18319         ;
18320       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18321         ;
18322       else
18323         if (unformat
18324             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18325         ;
18326       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18327         ;
18328       else if (unformat (i, "disable"))
18329         state = 0;
18330       else if (unformat (i, "rx"))
18331         state = 1;
18332       else if (unformat (i, "tx"))
18333         state = 2;
18334       else if (unformat (i, "both"))
18335         state = 3;
18336       else if (unformat (i, "l2"))
18337         is_l2 = 1;
18338       else
18339         break;
18340     }
18341
18342   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18343
18344   mp->sw_if_index_from = htonl (src_sw_if_index);
18345   mp->sw_if_index_to = htonl (dst_sw_if_index);
18346   mp->state = state;
18347   mp->is_l2 = is_l2;
18348
18349   S (mp);
18350   W (ret);
18351   return ret;
18352 }
18353
18354 static void
18355 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18356                                             * mp)
18357 {
18358   vat_main_t *vam = &vat_main;
18359   u8 *sw_if_from_name = 0;
18360   u8 *sw_if_to_name = 0;
18361   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18362   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18363   char *states[] = { "none", "rx", "tx", "both" };
18364   hash_pair_t *p;
18365
18366   /* *INDENT-OFF* */
18367   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18368   ({
18369     if ((u32) p->value[0] == sw_if_index_from)
18370       {
18371         sw_if_from_name = (u8 *)(p->key);
18372         if (sw_if_to_name)
18373           break;
18374       }
18375     if ((u32) p->value[0] == sw_if_index_to)
18376       {
18377         sw_if_to_name = (u8 *)(p->key);
18378         if (sw_if_from_name)
18379           break;
18380       }
18381   }));
18382   /* *INDENT-ON* */
18383   print (vam->ofp, "%20s => %20s (%s) %s",
18384          sw_if_from_name, sw_if_to_name, states[mp->state],
18385          mp->is_l2 ? "l2" : "device");
18386 }
18387
18388 static void
18389   vl_api_sw_interface_span_details_t_handler_json
18390   (vl_api_sw_interface_span_details_t * mp)
18391 {
18392   vat_main_t *vam = &vat_main;
18393   vat_json_node_t *node = NULL;
18394   u8 *sw_if_from_name = 0;
18395   u8 *sw_if_to_name = 0;
18396   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18397   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18398   hash_pair_t *p;
18399
18400   /* *INDENT-OFF* */
18401   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18402   ({
18403     if ((u32) p->value[0] == sw_if_index_from)
18404       {
18405         sw_if_from_name = (u8 *)(p->key);
18406         if (sw_if_to_name)
18407           break;
18408       }
18409     if ((u32) p->value[0] == sw_if_index_to)
18410       {
18411         sw_if_to_name = (u8 *)(p->key);
18412         if (sw_if_from_name)
18413           break;
18414       }
18415   }));
18416   /* *INDENT-ON* */
18417
18418   if (VAT_JSON_ARRAY != vam->json_tree.type)
18419     {
18420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18421       vat_json_init_array (&vam->json_tree);
18422     }
18423   node = vat_json_array_add (&vam->json_tree);
18424
18425   vat_json_init_object (node);
18426   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18427   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18428   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18429   if (0 != sw_if_to_name)
18430     {
18431       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18432     }
18433   vat_json_object_add_uint (node, "state", mp->state);
18434   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18435 }
18436
18437 static int
18438 api_sw_interface_span_dump (vat_main_t * vam)
18439 {
18440   unformat_input_t *input = vam->input;
18441   vl_api_sw_interface_span_dump_t *mp;
18442   vl_api_control_ping_t *mp_ping;
18443   u8 is_l2 = 0;
18444   int ret;
18445
18446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18447     {
18448       if (unformat (input, "l2"))
18449         is_l2 = 1;
18450       else
18451         break;
18452     }
18453
18454   M (SW_INTERFACE_SPAN_DUMP, mp);
18455   mp->is_l2 = is_l2;
18456   S (mp);
18457
18458   /* Use a control ping for synchronization */
18459   MPING (CONTROL_PING, mp_ping);
18460   S (mp_ping);
18461
18462   W (ret);
18463   return ret;
18464 }
18465
18466 int
18467 api_pg_create_interface (vat_main_t * vam)
18468 {
18469   unformat_input_t *input = vam->input;
18470   vl_api_pg_create_interface_t *mp;
18471
18472   u32 if_id = ~0, gso_size = 0;
18473   u8 gso_enabled = 0;
18474   int ret;
18475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18476     {
18477       if (unformat (input, "if_id %d", &if_id))
18478         ;
18479       else if (unformat (input, "gso-enabled"))
18480         {
18481           gso_enabled = 1;
18482           if (unformat (input, "gso-size %u", &gso_size))
18483             ;
18484           else
18485             {
18486               errmsg ("missing gso-size");
18487               return -99;
18488             }
18489         }
18490       else
18491         break;
18492     }
18493   if (if_id == ~0)
18494     {
18495       errmsg ("missing pg interface index");
18496       return -99;
18497     }
18498
18499   /* Construct the API message */
18500   M (PG_CREATE_INTERFACE, mp);
18501   mp->context = 0;
18502   mp->interface_id = ntohl (if_id);
18503   mp->gso_enabled = gso_enabled;
18504
18505   S (mp);
18506   W (ret);
18507   return ret;
18508 }
18509
18510 int
18511 api_pg_capture (vat_main_t * vam)
18512 {
18513   unformat_input_t *input = vam->input;
18514   vl_api_pg_capture_t *mp;
18515
18516   u32 if_id = ~0;
18517   u8 enable = 1;
18518   u32 count = 1;
18519   u8 pcap_file_set = 0;
18520   u8 *pcap_file = 0;
18521   int ret;
18522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18523     {
18524       if (unformat (input, "if_id %d", &if_id))
18525         ;
18526       else if (unformat (input, "pcap %s", &pcap_file))
18527         pcap_file_set = 1;
18528       else if (unformat (input, "count %d", &count))
18529         ;
18530       else if (unformat (input, "disable"))
18531         enable = 0;
18532       else
18533         break;
18534     }
18535   if (if_id == ~0)
18536     {
18537       errmsg ("missing pg interface index");
18538       return -99;
18539     }
18540   if (pcap_file_set > 0)
18541     {
18542       if (vec_len (pcap_file) > 255)
18543         {
18544           errmsg ("pcap file name is too long");
18545           return -99;
18546         }
18547     }
18548
18549   /* Construct the API message */
18550   M (PG_CAPTURE, mp);
18551   mp->context = 0;
18552   mp->interface_id = ntohl (if_id);
18553   mp->is_enabled = enable;
18554   mp->count = ntohl (count);
18555   if (pcap_file_set != 0)
18556     {
18557       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18558     }
18559   vec_free (pcap_file);
18560
18561   S (mp);
18562   W (ret);
18563   return ret;
18564 }
18565
18566 int
18567 api_pg_enable_disable (vat_main_t * vam)
18568 {
18569   unformat_input_t *input = vam->input;
18570   vl_api_pg_enable_disable_t *mp;
18571
18572   u8 enable = 1;
18573   u8 stream_name_set = 0;
18574   u8 *stream_name = 0;
18575   int ret;
18576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18577     {
18578       if (unformat (input, "stream %s", &stream_name))
18579         stream_name_set = 1;
18580       else if (unformat (input, "disable"))
18581         enable = 0;
18582       else
18583         break;
18584     }
18585
18586   if (stream_name_set > 0)
18587     {
18588       if (vec_len (stream_name) > 255)
18589         {
18590           errmsg ("stream name too long");
18591           return -99;
18592         }
18593     }
18594
18595   /* Construct the API message */
18596   M (PG_ENABLE_DISABLE, mp);
18597   mp->context = 0;
18598   mp->is_enabled = enable;
18599   if (stream_name_set != 0)
18600     {
18601       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18602     }
18603   vec_free (stream_name);
18604
18605   S (mp);
18606   W (ret);
18607   return ret;
18608 }
18609
18610 int
18611 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18612 {
18613   unformat_input_t *input = vam->input;
18614   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18615
18616   u16 *low_ports = 0;
18617   u16 *high_ports = 0;
18618   u16 this_low;
18619   u16 this_hi;
18620   vl_api_prefix_t prefix;
18621   u32 tmp, tmp2;
18622   u8 prefix_set = 0;
18623   u32 vrf_id = ~0;
18624   u8 is_add = 1;
18625   int ret;
18626
18627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18628     {
18629       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18630         prefix_set = 1;
18631       else if (unformat (input, "vrf %d", &vrf_id))
18632         ;
18633       else if (unformat (input, "del"))
18634         is_add = 0;
18635       else if (unformat (input, "port %d", &tmp))
18636         {
18637           if (tmp == 0 || tmp > 65535)
18638             {
18639               errmsg ("port %d out of range", tmp);
18640               return -99;
18641             }
18642           this_low = tmp;
18643           this_hi = this_low + 1;
18644           vec_add1 (low_ports, this_low);
18645           vec_add1 (high_ports, this_hi);
18646         }
18647       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18648         {
18649           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18650             {
18651               errmsg ("incorrect range parameters");
18652               return -99;
18653             }
18654           this_low = tmp;
18655           /* Note: in debug CLI +1 is added to high before
18656              passing to real fn that does "the work"
18657              (ip_source_and_port_range_check_add_del).
18658              This fn is a wrapper around the binary API fn a
18659              control plane will call, which expects this increment
18660              to have occurred. Hence letting the binary API control
18661              plane fn do the increment for consistency between VAT
18662              and other control planes.
18663            */
18664           this_hi = tmp2;
18665           vec_add1 (low_ports, this_low);
18666           vec_add1 (high_ports, this_hi);
18667         }
18668       else
18669         break;
18670     }
18671
18672   if (prefix_set == 0)
18673     {
18674       errmsg ("<address>/<mask> not specified");
18675       return -99;
18676     }
18677
18678   if (vrf_id == ~0)
18679     {
18680       errmsg ("VRF ID required, not specified");
18681       return -99;
18682     }
18683
18684   if (vrf_id == 0)
18685     {
18686       errmsg
18687         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18688       return -99;
18689     }
18690
18691   if (vec_len (low_ports) == 0)
18692     {
18693       errmsg ("At least one port or port range required");
18694       return -99;
18695     }
18696
18697   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18698
18699   mp->is_add = is_add;
18700
18701   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18702
18703   mp->number_of_ranges = vec_len (low_ports);
18704
18705   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18706   vec_free (low_ports);
18707
18708   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18709   vec_free (high_ports);
18710
18711   mp->vrf_id = ntohl (vrf_id);
18712
18713   S (mp);
18714   W (ret);
18715   return ret;
18716 }
18717
18718 int
18719 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18720 {
18721   unformat_input_t *input = vam->input;
18722   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18723   u32 sw_if_index = ~0;
18724   int vrf_set = 0;
18725   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18726   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18727   u8 is_add = 1;
18728   int ret;
18729
18730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18731     {
18732       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18733         ;
18734       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18735         ;
18736       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18737         vrf_set = 1;
18738       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18739         vrf_set = 1;
18740       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18741         vrf_set = 1;
18742       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18743         vrf_set = 1;
18744       else if (unformat (input, "del"))
18745         is_add = 0;
18746       else
18747         break;
18748     }
18749
18750   if (sw_if_index == ~0)
18751     {
18752       errmsg ("Interface required but not specified");
18753       return -99;
18754     }
18755
18756   if (vrf_set == 0)
18757     {
18758       errmsg ("VRF ID required but not specified");
18759       return -99;
18760     }
18761
18762   if (tcp_out_vrf_id == 0
18763       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18764     {
18765       errmsg
18766         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18767       return -99;
18768     }
18769
18770   /* Construct the API message */
18771   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18772
18773   mp->sw_if_index = ntohl (sw_if_index);
18774   mp->is_add = is_add;
18775   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18776   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18777   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18778   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18779
18780   /* send it... */
18781   S (mp);
18782
18783   /* Wait for a reply... */
18784   W (ret);
18785   return ret;
18786 }
18787
18788 static int
18789 api_set_punt (vat_main_t * vam)
18790 {
18791   unformat_input_t *i = vam->input;
18792   vl_api_address_family_t af;
18793   vl_api_set_punt_t *mp;
18794   u32 protocol = ~0;
18795   u32 port = ~0;
18796   int is_add = 1;
18797   int ret;
18798
18799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18800     {
18801       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18802         ;
18803       else if (unformat (i, "protocol %d", &protocol))
18804         ;
18805       else if (unformat (i, "port %d", &port))
18806         ;
18807       else if (unformat (i, "del"))
18808         is_add = 0;
18809       else
18810         {
18811           clib_warning ("parse error '%U'", format_unformat_error, i);
18812           return -99;
18813         }
18814     }
18815
18816   M (SET_PUNT, mp);
18817
18818   mp->is_add = (u8) is_add;
18819   mp->punt.type = PUNT_API_TYPE_L4;
18820   mp->punt.punt.l4.af = af;
18821   mp->punt.punt.l4.protocol = (u8) protocol;
18822   mp->punt.punt.l4.port = htons ((u16) port);
18823
18824   S (mp);
18825   W (ret);
18826   return ret;
18827 }
18828
18829 static int
18830 api_delete_subif (vat_main_t * vam)
18831 {
18832   unformat_input_t *i = vam->input;
18833   vl_api_delete_subif_t *mp;
18834   u32 sw_if_index = ~0;
18835   int ret;
18836
18837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18838     {
18839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18840         ;
18841       if (unformat (i, "sw_if_index %d", &sw_if_index))
18842         ;
18843       else
18844         break;
18845     }
18846
18847   if (sw_if_index == ~0)
18848     {
18849       errmsg ("missing sw_if_index");
18850       return -99;
18851     }
18852
18853   /* Construct the API message */
18854   M (DELETE_SUBIF, mp);
18855   mp->sw_if_index = ntohl (sw_if_index);
18856
18857   S (mp);
18858   W (ret);
18859   return ret;
18860 }
18861
18862 #define foreach_pbb_vtr_op      \
18863 _("disable",  L2_VTR_DISABLED)  \
18864 _("pop",  L2_VTR_POP_2)         \
18865 _("push",  L2_VTR_PUSH_2)
18866
18867 static int
18868 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18869 {
18870   unformat_input_t *i = vam->input;
18871   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18872   u32 sw_if_index = ~0, vtr_op = ~0;
18873   u16 outer_tag = ~0;
18874   u8 dmac[6], smac[6];
18875   u8 dmac_set = 0, smac_set = 0;
18876   u16 vlanid = 0;
18877   u32 sid = ~0;
18878   u32 tmp;
18879   int ret;
18880
18881   /* Shut up coverity */
18882   clib_memset (dmac, 0, sizeof (dmac));
18883   clib_memset (smac, 0, sizeof (smac));
18884
18885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18886     {
18887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18888         ;
18889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18890         ;
18891       else if (unformat (i, "vtr_op %d", &vtr_op))
18892         ;
18893 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18894       foreach_pbb_vtr_op
18895 #undef _
18896         else if (unformat (i, "translate_pbb_stag"))
18897         {
18898           if (unformat (i, "%d", &tmp))
18899             {
18900               vtr_op = L2_VTR_TRANSLATE_2_1;
18901               outer_tag = tmp;
18902             }
18903           else
18904             {
18905               errmsg
18906                 ("translate_pbb_stag operation requires outer tag definition");
18907               return -99;
18908             }
18909         }
18910       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18911         dmac_set++;
18912       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18913         smac_set++;
18914       else if (unformat (i, "sid %d", &sid))
18915         ;
18916       else if (unformat (i, "vlanid %d", &tmp))
18917         vlanid = tmp;
18918       else
18919         {
18920           clib_warning ("parse error '%U'", format_unformat_error, i);
18921           return -99;
18922         }
18923     }
18924
18925   if ((sw_if_index == ~0) || (vtr_op == ~0))
18926     {
18927       errmsg ("missing sw_if_index or vtr operation");
18928       return -99;
18929     }
18930   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18931       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18932     {
18933       errmsg
18934         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18935       return -99;
18936     }
18937
18938   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18939   mp->sw_if_index = ntohl (sw_if_index);
18940   mp->vtr_op = ntohl (vtr_op);
18941   mp->outer_tag = ntohs (outer_tag);
18942   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18943   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18944   mp->b_vlanid = ntohs (vlanid);
18945   mp->i_sid = ntohl (sid);
18946
18947   S (mp);
18948   W (ret);
18949   return ret;
18950 }
18951
18952 static int
18953 api_flow_classify_set_interface (vat_main_t * vam)
18954 {
18955   unformat_input_t *i = vam->input;
18956   vl_api_flow_classify_set_interface_t *mp;
18957   u32 sw_if_index;
18958   int sw_if_index_set;
18959   u32 ip4_table_index = ~0;
18960   u32 ip6_table_index = ~0;
18961   u8 is_add = 1;
18962   int ret;
18963
18964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18965     {
18966       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18967         sw_if_index_set = 1;
18968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18969         sw_if_index_set = 1;
18970       else if (unformat (i, "del"))
18971         is_add = 0;
18972       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18973         ;
18974       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18975         ;
18976       else
18977         {
18978           clib_warning ("parse error '%U'", format_unformat_error, i);
18979           return -99;
18980         }
18981     }
18982
18983   if (sw_if_index_set == 0)
18984     {
18985       errmsg ("missing interface name or sw_if_index");
18986       return -99;
18987     }
18988
18989   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18990
18991   mp->sw_if_index = ntohl (sw_if_index);
18992   mp->ip4_table_index = ntohl (ip4_table_index);
18993   mp->ip6_table_index = ntohl (ip6_table_index);
18994   mp->is_add = is_add;
18995
18996   S (mp);
18997   W (ret);
18998   return ret;
18999 }
19000
19001 static int
19002 api_flow_classify_dump (vat_main_t * vam)
19003 {
19004   unformat_input_t *i = vam->input;
19005   vl_api_flow_classify_dump_t *mp;
19006   vl_api_control_ping_t *mp_ping;
19007   u8 type = FLOW_CLASSIFY_N_TABLES;
19008   int ret;
19009
19010   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19011     ;
19012   else
19013     {
19014       errmsg ("classify table type must be specified");
19015       return -99;
19016     }
19017
19018   if (!vam->json_output)
19019     {
19020       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19021     }
19022
19023   M (FLOW_CLASSIFY_DUMP, mp);
19024   mp->type = type;
19025   /* send it... */
19026   S (mp);
19027
19028   /* Use a control ping for synchronization */
19029   MPING (CONTROL_PING, mp_ping);
19030   S (mp_ping);
19031
19032   /* Wait for a reply... */
19033   W (ret);
19034   return ret;
19035 }
19036
19037 static int
19038 api_feature_enable_disable (vat_main_t * vam)
19039 {
19040   unformat_input_t *i = vam->input;
19041   vl_api_feature_enable_disable_t *mp;
19042   u8 *arc_name = 0;
19043   u8 *feature_name = 0;
19044   u32 sw_if_index = ~0;
19045   u8 enable = 1;
19046   int ret;
19047
19048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19049     {
19050       if (unformat (i, "arc_name %s", &arc_name))
19051         ;
19052       else if (unformat (i, "feature_name %s", &feature_name))
19053         ;
19054       else
19055         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19056         ;
19057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19058         ;
19059       else if (unformat (i, "disable"))
19060         enable = 0;
19061       else
19062         break;
19063     }
19064
19065   if (arc_name == 0)
19066     {
19067       errmsg ("missing arc name");
19068       return -99;
19069     }
19070   if (vec_len (arc_name) > 63)
19071     {
19072       errmsg ("arc name too long");
19073     }
19074
19075   if (feature_name == 0)
19076     {
19077       errmsg ("missing feature name");
19078       return -99;
19079     }
19080   if (vec_len (feature_name) > 63)
19081     {
19082       errmsg ("feature name too long");
19083     }
19084
19085   if (sw_if_index == ~0)
19086     {
19087       errmsg ("missing interface name or sw_if_index");
19088       return -99;
19089     }
19090
19091   /* Construct the API message */
19092   M (FEATURE_ENABLE_DISABLE, mp);
19093   mp->sw_if_index = ntohl (sw_if_index);
19094   mp->enable = enable;
19095   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19096   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19097   vec_free (arc_name);
19098   vec_free (feature_name);
19099
19100   S (mp);
19101   W (ret);
19102   return ret;
19103 }
19104
19105 static int
19106 api_feature_gso_enable_disable (vat_main_t * vam)
19107 {
19108   unformat_input_t *i = vam->input;
19109   vl_api_feature_gso_enable_disable_t *mp;
19110   u32 sw_if_index = ~0;
19111   u8 enable = 1;
19112   int ret;
19113
19114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19115     {
19116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19117         ;
19118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19119         ;
19120       else if (unformat (i, "enable"))
19121         enable = 1;
19122       else if (unformat (i, "disable"))
19123         enable = 0;
19124       else
19125         break;
19126     }
19127
19128   if (sw_if_index == ~0)
19129     {
19130       errmsg ("missing interface name or sw_if_index");
19131       return -99;
19132     }
19133
19134   /* Construct the API message */
19135   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19136   mp->sw_if_index = ntohl (sw_if_index);
19137   mp->enable_disable = enable;
19138
19139   S (mp);
19140   W (ret);
19141   return ret;
19142 }
19143
19144 static int
19145 api_sw_interface_tag_add_del (vat_main_t * vam)
19146 {
19147   unformat_input_t *i = vam->input;
19148   vl_api_sw_interface_tag_add_del_t *mp;
19149   u32 sw_if_index = ~0;
19150   u8 *tag = 0;
19151   u8 enable = 1;
19152   int ret;
19153
19154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19155     {
19156       if (unformat (i, "tag %s", &tag))
19157         ;
19158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19159         ;
19160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19161         ;
19162       else if (unformat (i, "del"))
19163         enable = 0;
19164       else
19165         break;
19166     }
19167
19168   if (sw_if_index == ~0)
19169     {
19170       errmsg ("missing interface name or sw_if_index");
19171       return -99;
19172     }
19173
19174   if (enable && (tag == 0))
19175     {
19176       errmsg ("no tag specified");
19177       return -99;
19178     }
19179
19180   /* Construct the API message */
19181   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19182   mp->sw_if_index = ntohl (sw_if_index);
19183   mp->is_add = enable;
19184   if (enable)
19185     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19186   vec_free (tag);
19187
19188   S (mp);
19189   W (ret);
19190   return ret;
19191 }
19192
19193 static int
19194 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19195 {
19196   unformat_input_t *i = vam->input;
19197   vl_api_mac_address_t mac = { 0 };
19198   vl_api_sw_interface_add_del_mac_address_t *mp;
19199   u32 sw_if_index = ~0;
19200   u8 is_add = 1;
19201   u8 mac_set = 0;
19202   int ret;
19203
19204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19205     {
19206       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19207         ;
19208       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19209         ;
19210       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19211         mac_set++;
19212       else if (unformat (i, "del"))
19213         is_add = 0;
19214       else
19215         break;
19216     }
19217
19218   if (sw_if_index == ~0)
19219     {
19220       errmsg ("missing interface name or sw_if_index");
19221       return -99;
19222     }
19223
19224   if (!mac_set)
19225     {
19226       errmsg ("missing MAC address");
19227       return -99;
19228     }
19229
19230   /* Construct the API message */
19231   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19232   mp->sw_if_index = ntohl (sw_if_index);
19233   mp->is_add = is_add;
19234   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19235
19236   S (mp);
19237   W (ret);
19238   return ret;
19239 }
19240
19241 static void vl_api_l2_xconnect_details_t_handler
19242   (vl_api_l2_xconnect_details_t * mp)
19243 {
19244   vat_main_t *vam = &vat_main;
19245
19246   print (vam->ofp, "%15d%15d",
19247          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19248 }
19249
19250 static void vl_api_l2_xconnect_details_t_handler_json
19251   (vl_api_l2_xconnect_details_t * mp)
19252 {
19253   vat_main_t *vam = &vat_main;
19254   vat_json_node_t *node = NULL;
19255
19256   if (VAT_JSON_ARRAY != vam->json_tree.type)
19257     {
19258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19259       vat_json_init_array (&vam->json_tree);
19260     }
19261   node = vat_json_array_add (&vam->json_tree);
19262
19263   vat_json_init_object (node);
19264   vat_json_object_add_uint (node, "rx_sw_if_index",
19265                             ntohl (mp->rx_sw_if_index));
19266   vat_json_object_add_uint (node, "tx_sw_if_index",
19267                             ntohl (mp->tx_sw_if_index));
19268 }
19269
19270 static int
19271 api_l2_xconnect_dump (vat_main_t * vam)
19272 {
19273   vl_api_l2_xconnect_dump_t *mp;
19274   vl_api_control_ping_t *mp_ping;
19275   int ret;
19276
19277   if (!vam->json_output)
19278     {
19279       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19280     }
19281
19282   M (L2_XCONNECT_DUMP, mp);
19283
19284   S (mp);
19285
19286   /* Use a control ping for synchronization */
19287   MPING (CONTROL_PING, mp_ping);
19288   S (mp_ping);
19289
19290   W (ret);
19291   return ret;
19292 }
19293
19294 static int
19295 api_hw_interface_set_mtu (vat_main_t * vam)
19296 {
19297   unformat_input_t *i = vam->input;
19298   vl_api_hw_interface_set_mtu_t *mp;
19299   u32 sw_if_index = ~0;
19300   u32 mtu = 0;
19301   int ret;
19302
19303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19304     {
19305       if (unformat (i, "mtu %d", &mtu))
19306         ;
19307       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19308         ;
19309       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19310         ;
19311       else
19312         break;
19313     }
19314
19315   if (sw_if_index == ~0)
19316     {
19317       errmsg ("missing interface name or sw_if_index");
19318       return -99;
19319     }
19320
19321   if (mtu == 0)
19322     {
19323       errmsg ("no mtu specified");
19324       return -99;
19325     }
19326
19327   /* Construct the API message */
19328   M (HW_INTERFACE_SET_MTU, mp);
19329   mp->sw_if_index = ntohl (sw_if_index);
19330   mp->mtu = ntohs ((u16) mtu);
19331
19332   S (mp);
19333   W (ret);
19334   return ret;
19335 }
19336
19337 static int
19338 api_p2p_ethernet_add (vat_main_t * vam)
19339 {
19340   unformat_input_t *i = vam->input;
19341   vl_api_p2p_ethernet_add_t *mp;
19342   u32 parent_if_index = ~0;
19343   u32 sub_id = ~0;
19344   u8 remote_mac[6];
19345   u8 mac_set = 0;
19346   int ret;
19347
19348   clib_memset (remote_mac, 0, sizeof (remote_mac));
19349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19350     {
19351       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19352         ;
19353       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19354         ;
19355       else
19356         if (unformat
19357             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19358         mac_set++;
19359       else if (unformat (i, "sub_id %d", &sub_id))
19360         ;
19361       else
19362         {
19363           clib_warning ("parse error '%U'", format_unformat_error, i);
19364           return -99;
19365         }
19366     }
19367
19368   if (parent_if_index == ~0)
19369     {
19370       errmsg ("missing interface name or sw_if_index");
19371       return -99;
19372     }
19373   if (mac_set == 0)
19374     {
19375       errmsg ("missing remote mac address");
19376       return -99;
19377     }
19378   if (sub_id == ~0)
19379     {
19380       errmsg ("missing sub-interface id");
19381       return -99;
19382     }
19383
19384   M (P2P_ETHERNET_ADD, mp);
19385   mp->parent_if_index = ntohl (parent_if_index);
19386   mp->subif_id = ntohl (sub_id);
19387   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19388
19389   S (mp);
19390   W (ret);
19391   return ret;
19392 }
19393
19394 static int
19395 api_p2p_ethernet_del (vat_main_t * vam)
19396 {
19397   unformat_input_t *i = vam->input;
19398   vl_api_p2p_ethernet_del_t *mp;
19399   u32 parent_if_index = ~0;
19400   u8 remote_mac[6];
19401   u8 mac_set = 0;
19402   int ret;
19403
19404   clib_memset (remote_mac, 0, sizeof (remote_mac));
19405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19406     {
19407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19408         ;
19409       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19410         ;
19411       else
19412         if (unformat
19413             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19414         mac_set++;
19415       else
19416         {
19417           clib_warning ("parse error '%U'", format_unformat_error, i);
19418           return -99;
19419         }
19420     }
19421
19422   if (parent_if_index == ~0)
19423     {
19424       errmsg ("missing interface name or sw_if_index");
19425       return -99;
19426     }
19427   if (mac_set == 0)
19428     {
19429       errmsg ("missing remote mac address");
19430       return -99;
19431     }
19432
19433   M (P2P_ETHERNET_DEL, mp);
19434   mp->parent_if_index = ntohl (parent_if_index);
19435   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19436
19437   S (mp);
19438   W (ret);
19439   return ret;
19440 }
19441
19442 static int
19443 api_lldp_config (vat_main_t * vam)
19444 {
19445   unformat_input_t *i = vam->input;
19446   vl_api_lldp_config_t *mp;
19447   int tx_hold = 0;
19448   int tx_interval = 0;
19449   u8 *sys_name = NULL;
19450   int ret;
19451
19452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19453     {
19454       if (unformat (i, "system-name %s", &sys_name))
19455         ;
19456       else if (unformat (i, "tx-hold %d", &tx_hold))
19457         ;
19458       else if (unformat (i, "tx-interval %d", &tx_interval))
19459         ;
19460       else
19461         {
19462           clib_warning ("parse error '%U'", format_unformat_error, i);
19463           return -99;
19464         }
19465     }
19466
19467   vec_add1 (sys_name, 0);
19468
19469   M (LLDP_CONFIG, mp);
19470   mp->tx_hold = htonl (tx_hold);
19471   mp->tx_interval = htonl (tx_interval);
19472   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19473   vec_free (sys_name);
19474
19475   S (mp);
19476   W (ret);
19477   return ret;
19478 }
19479
19480 static int
19481 api_sw_interface_set_lldp (vat_main_t * vam)
19482 {
19483   unformat_input_t *i = vam->input;
19484   vl_api_sw_interface_set_lldp_t *mp;
19485   u32 sw_if_index = ~0;
19486   u32 enable = 1;
19487   u8 *port_desc = NULL, *mgmt_oid = NULL;
19488   ip4_address_t ip4_addr;
19489   ip6_address_t ip6_addr;
19490   int ret;
19491
19492   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19493   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19494
19495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19496     {
19497       if (unformat (i, "disable"))
19498         enable = 0;
19499       else
19500         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19501         ;
19502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19503         ;
19504       else if (unformat (i, "port-desc %s", &port_desc))
19505         ;
19506       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19507         ;
19508       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19509         ;
19510       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19511         ;
19512       else
19513         break;
19514     }
19515
19516   if (sw_if_index == ~0)
19517     {
19518       errmsg ("missing interface name or sw_if_index");
19519       return -99;
19520     }
19521
19522   /* Construct the API message */
19523   vec_add1 (port_desc, 0);
19524   vec_add1 (mgmt_oid, 0);
19525   M (SW_INTERFACE_SET_LLDP, mp);
19526   mp->sw_if_index = ntohl (sw_if_index);
19527   mp->enable = enable;
19528   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19529   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19530   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19531   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19532   vec_free (port_desc);
19533   vec_free (mgmt_oid);
19534
19535   S (mp);
19536   W (ret);
19537   return ret;
19538 }
19539
19540 static int
19541 api_tcp_configure_src_addresses (vat_main_t * vam)
19542 {
19543   vl_api_tcp_configure_src_addresses_t *mp;
19544   unformat_input_t *i = vam->input;
19545   vl_api_address_t first, last;
19546   u8 range_set = 0;
19547   u32 vrf_id = 0;
19548   int ret;
19549
19550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19551     {
19552       if (unformat (i, "%U - %U",
19553                     unformat_vl_api_address, &first,
19554                     unformat_vl_api_address, &last))
19555         {
19556           if (range_set)
19557             {
19558               errmsg ("one range per message (range already set)");
19559               return -99;
19560             }
19561           range_set = 1;
19562         }
19563       else if (unformat (i, "vrf %d", &vrf_id))
19564         ;
19565       else
19566         break;
19567     }
19568
19569   if (range_set == 0)
19570     {
19571       errmsg ("address range not set");
19572       return -99;
19573     }
19574
19575   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19576
19577   mp->vrf_id = ntohl (vrf_id);
19578   clib_memcpy (&mp->first_address, &first, sizeof (first));
19579   clib_memcpy (&mp->last_address, &last, sizeof (last));
19580
19581   S (mp);
19582   W (ret);
19583   return ret;
19584 }
19585
19586 static void vl_api_app_namespace_add_del_reply_t_handler
19587   (vl_api_app_namespace_add_del_reply_t * mp)
19588 {
19589   vat_main_t *vam = &vat_main;
19590   i32 retval = ntohl (mp->retval);
19591   if (vam->async_mode)
19592     {
19593       vam->async_errors += (retval < 0);
19594     }
19595   else
19596     {
19597       vam->retval = retval;
19598       if (retval == 0)
19599         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19600       vam->result_ready = 1;
19601     }
19602 }
19603
19604 static void vl_api_app_namespace_add_del_reply_t_handler_json
19605   (vl_api_app_namespace_add_del_reply_t * mp)
19606 {
19607   vat_main_t *vam = &vat_main;
19608   vat_json_node_t node;
19609
19610   vat_json_init_object (&node);
19611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19612   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19613
19614   vat_json_print (vam->ofp, &node);
19615   vat_json_free (&node);
19616
19617   vam->retval = ntohl (mp->retval);
19618   vam->result_ready = 1;
19619 }
19620
19621 static int
19622 api_app_namespace_add_del (vat_main_t * vam)
19623 {
19624   vl_api_app_namespace_add_del_t *mp;
19625   unformat_input_t *i = vam->input;
19626   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19627   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19628   u64 secret;
19629   int ret;
19630
19631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19632     {
19633       if (unformat (i, "id %_%v%_", &ns_id))
19634         ;
19635       else if (unformat (i, "secret %lu", &secret))
19636         secret_set = 1;
19637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19638         sw_if_index_set = 1;
19639       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19640         ;
19641       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19642         ;
19643       else
19644         break;
19645     }
19646   if (!ns_id || !secret_set || !sw_if_index_set)
19647     {
19648       errmsg ("namespace id, secret and sw_if_index must be set");
19649       return -99;
19650     }
19651   if (vec_len (ns_id) > 64)
19652     {
19653       errmsg ("namespace id too long");
19654       return -99;
19655     }
19656   M (APP_NAMESPACE_ADD_DEL, mp);
19657
19658   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19659   mp->secret = clib_host_to_net_u64 (secret);
19660   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19661   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19662   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19663   vec_free (ns_id);
19664   S (mp);
19665   W (ret);
19666   return ret;
19667 }
19668
19669 static int
19670 api_sock_init_shm (vat_main_t * vam)
19671 {
19672 #if VPP_API_TEST_BUILTIN == 0
19673   unformat_input_t *i = vam->input;
19674   vl_api_shm_elem_config_t *config = 0;
19675   u64 size = 64 << 20;
19676   int rv;
19677
19678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19679     {
19680       if (unformat (i, "size %U", unformat_memory_size, &size))
19681         ;
19682       else
19683         break;
19684     }
19685
19686   /*
19687    * Canned custom ring allocator config.
19688    * Should probably parse all of this
19689    */
19690   vec_validate (config, 6);
19691   config[0].type = VL_API_VLIB_RING;
19692   config[0].size = 256;
19693   config[0].count = 32;
19694
19695   config[1].type = VL_API_VLIB_RING;
19696   config[1].size = 1024;
19697   config[1].count = 16;
19698
19699   config[2].type = VL_API_VLIB_RING;
19700   config[2].size = 4096;
19701   config[2].count = 2;
19702
19703   config[3].type = VL_API_CLIENT_RING;
19704   config[3].size = 256;
19705   config[3].count = 32;
19706
19707   config[4].type = VL_API_CLIENT_RING;
19708   config[4].size = 1024;
19709   config[4].count = 16;
19710
19711   config[5].type = VL_API_CLIENT_RING;
19712   config[5].size = 4096;
19713   config[5].count = 2;
19714
19715   config[6].type = VL_API_QUEUE;
19716   config[6].count = 128;
19717   config[6].size = sizeof (uword);
19718
19719   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19720   if (!rv)
19721     vam->client_index_invalid = 1;
19722   return rv;
19723 #else
19724   return -99;
19725 #endif
19726 }
19727
19728 static void
19729 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19730 {
19731   vat_main_t *vam = &vat_main;
19732   fib_prefix_t lcl, rmt;
19733
19734   ip_prefix_decode (&mp->lcl, &lcl);
19735   ip_prefix_decode (&mp->rmt, &rmt);
19736
19737   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19738     {
19739       print (vam->ofp,
19740              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19741              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19742              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19743              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19744              &rmt.fp_addr.ip4, rmt.fp_len,
19745              clib_net_to_host_u16 (mp->rmt_port),
19746              clib_net_to_host_u32 (mp->action_index), mp->tag);
19747     }
19748   else
19749     {
19750       print (vam->ofp,
19751              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19752              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19753              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19754              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19755              &rmt.fp_addr.ip6, rmt.fp_len,
19756              clib_net_to_host_u16 (mp->rmt_port),
19757              clib_net_to_host_u32 (mp->action_index), mp->tag);
19758     }
19759 }
19760
19761 static void
19762 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19763                                              mp)
19764 {
19765   vat_main_t *vam = &vat_main;
19766   vat_json_node_t *node = NULL;
19767   struct in6_addr ip6;
19768   struct in_addr ip4;
19769
19770   fib_prefix_t lcl, rmt;
19771
19772   ip_prefix_decode (&mp->lcl, &lcl);
19773   ip_prefix_decode (&mp->rmt, &rmt);
19774
19775   if (VAT_JSON_ARRAY != vam->json_tree.type)
19776     {
19777       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19778       vat_json_init_array (&vam->json_tree);
19779     }
19780   node = vat_json_array_add (&vam->json_tree);
19781   vat_json_init_object (node);
19782
19783   vat_json_object_add_uint (node, "appns_index",
19784                             clib_net_to_host_u32 (mp->appns_index));
19785   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19786   vat_json_object_add_uint (node, "scope", mp->scope);
19787   vat_json_object_add_uint (node, "action_index",
19788                             clib_net_to_host_u32 (mp->action_index));
19789   vat_json_object_add_uint (node, "lcl_port",
19790                             clib_net_to_host_u16 (mp->lcl_port));
19791   vat_json_object_add_uint (node, "rmt_port",
19792                             clib_net_to_host_u16 (mp->rmt_port));
19793   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19794   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19795   vat_json_object_add_string_copy (node, "tag", mp->tag);
19796   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19797     {
19798       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19799       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19800       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19801       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19802     }
19803   else
19804     {
19805       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19806       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19807       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19808       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19809     }
19810 }
19811
19812 static int
19813 api_session_rule_add_del (vat_main_t * vam)
19814 {
19815   vl_api_session_rule_add_del_t *mp;
19816   unformat_input_t *i = vam->input;
19817   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19818   u32 appns_index = 0, scope = 0;
19819   ip4_address_t lcl_ip4, rmt_ip4;
19820   ip6_address_t lcl_ip6, rmt_ip6;
19821   u8 is_ip4 = 1, conn_set = 0;
19822   u8 is_add = 1, *tag = 0;
19823   int ret;
19824   fib_prefix_t lcl, rmt;
19825
19826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19827     {
19828       if (unformat (i, "del"))
19829         is_add = 0;
19830       else if (unformat (i, "add"))
19831         ;
19832       else if (unformat (i, "proto tcp"))
19833         proto = 0;
19834       else if (unformat (i, "proto udp"))
19835         proto = 1;
19836       else if (unformat (i, "appns %d", &appns_index))
19837         ;
19838       else if (unformat (i, "scope %d", &scope))
19839         ;
19840       else if (unformat (i, "tag %_%v%_", &tag))
19841         ;
19842       else
19843         if (unformat
19844             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19845              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19846              &rmt_port))
19847         {
19848           is_ip4 = 1;
19849           conn_set = 1;
19850         }
19851       else
19852         if (unformat
19853             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19854              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19855              &rmt_port))
19856         {
19857           is_ip4 = 0;
19858           conn_set = 1;
19859         }
19860       else if (unformat (i, "action %d", &action))
19861         ;
19862       else
19863         break;
19864     }
19865   if (proto == ~0 || !conn_set || action == ~0)
19866     {
19867       errmsg ("transport proto, connection and action must be set");
19868       return -99;
19869     }
19870
19871   if (scope > 3)
19872     {
19873       errmsg ("scope should be 0-3");
19874       return -99;
19875     }
19876
19877   M (SESSION_RULE_ADD_DEL, mp);
19878
19879   clib_memset (&lcl, 0, sizeof (lcl));
19880   clib_memset (&rmt, 0, sizeof (rmt));
19881   if (is_ip4)
19882     {
19883       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19884       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19885       lcl.fp_len = lcl_plen;
19886       rmt.fp_len = rmt_plen;
19887     }
19888   else
19889     {
19890       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19891       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19892       lcl.fp_len = lcl_plen;
19893       rmt.fp_len = rmt_plen;
19894     }
19895
19896
19897   ip_prefix_encode (&lcl, &mp->lcl);
19898   ip_prefix_encode (&rmt, &mp->rmt);
19899   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19900   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19901   mp->transport_proto =
19902     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19903   mp->action_index = clib_host_to_net_u32 (action);
19904   mp->appns_index = clib_host_to_net_u32 (appns_index);
19905   mp->scope = scope;
19906   mp->is_add = is_add;
19907   if (tag)
19908     {
19909       clib_memcpy (mp->tag, tag, vec_len (tag));
19910       vec_free (tag);
19911     }
19912
19913   S (mp);
19914   W (ret);
19915   return ret;
19916 }
19917
19918 static int
19919 api_session_rules_dump (vat_main_t * vam)
19920 {
19921   vl_api_session_rules_dump_t *mp;
19922   vl_api_control_ping_t *mp_ping;
19923   int ret;
19924
19925   if (!vam->json_output)
19926     {
19927       print (vam->ofp, "%=20s", "Session Rules");
19928     }
19929
19930   M (SESSION_RULES_DUMP, mp);
19931   /* send it... */
19932   S (mp);
19933
19934   /* Use a control ping for synchronization */
19935   MPING (CONTROL_PING, mp_ping);
19936   S (mp_ping);
19937
19938   /* Wait for a reply... */
19939   W (ret);
19940   return ret;
19941 }
19942
19943 static int
19944 api_ip_container_proxy_add_del (vat_main_t * vam)
19945 {
19946   vl_api_ip_container_proxy_add_del_t *mp;
19947   unformat_input_t *i = vam->input;
19948   u32 sw_if_index = ~0;
19949   vl_api_prefix_t pfx = { };
19950   u8 is_add = 1;
19951   int ret;
19952
19953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19954     {
19955       if (unformat (i, "del"))
19956         is_add = 0;
19957       else if (unformat (i, "add"))
19958         ;
19959       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19960         ;
19961       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19962         ;
19963       else
19964         break;
19965     }
19966   if (sw_if_index == ~0 || pfx.len == 0)
19967     {
19968       errmsg ("address and sw_if_index must be set");
19969       return -99;
19970     }
19971
19972   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19973
19974   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19975   mp->is_add = is_add;
19976   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19977
19978   S (mp);
19979   W (ret);
19980   return ret;
19981 }
19982
19983 static int
19984 api_qos_record_enable_disable (vat_main_t * vam)
19985 {
19986   unformat_input_t *i = vam->input;
19987   vl_api_qos_record_enable_disable_t *mp;
19988   u32 sw_if_index, qs = 0xff;
19989   u8 sw_if_index_set = 0;
19990   u8 enable = 1;
19991   int ret;
19992
19993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19994     {
19995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19996         sw_if_index_set = 1;
19997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19998         sw_if_index_set = 1;
19999       else if (unformat (i, "%U", unformat_qos_source, &qs))
20000         ;
20001       else if (unformat (i, "disable"))
20002         enable = 0;
20003       else
20004         {
20005           clib_warning ("parse error '%U'", format_unformat_error, i);
20006           return -99;
20007         }
20008     }
20009
20010   if (sw_if_index_set == 0)
20011     {
20012       errmsg ("missing interface name or sw_if_index");
20013       return -99;
20014     }
20015   if (qs == 0xff)
20016     {
20017       errmsg ("input location must be specified");
20018       return -99;
20019     }
20020
20021   M (QOS_RECORD_ENABLE_DISABLE, mp);
20022
20023   mp->record.sw_if_index = ntohl (sw_if_index);
20024   mp->record.input_source = qs;
20025   mp->enable = enable;
20026
20027   S (mp);
20028   W (ret);
20029   return ret;
20030 }
20031
20032
20033 static int
20034 q_or_quit (vat_main_t * vam)
20035 {
20036 #if VPP_API_TEST_BUILTIN == 0
20037   longjmp (vam->jump_buf, 1);
20038 #endif
20039   return 0;                     /* not so much */
20040 }
20041
20042 static int
20043 q (vat_main_t * vam)
20044 {
20045   return q_or_quit (vam);
20046 }
20047
20048 static int
20049 quit (vat_main_t * vam)
20050 {
20051   return q_or_quit (vam);
20052 }
20053
20054 static int
20055 comment (vat_main_t * vam)
20056 {
20057   return 0;
20058 }
20059
20060 static int
20061 elog_save (vat_main_t * vam)
20062 {
20063 #if VPP_API_TEST_BUILTIN == 0
20064   elog_main_t *em = &vam->elog_main;
20065   unformat_input_t *i = vam->input;
20066   char *file, *chroot_file;
20067   clib_error_t *error;
20068
20069   if (!unformat (i, "%s", &file))
20070     {
20071       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20072       return 0;
20073     }
20074
20075   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20076   if (strstr (file, "..") || index (file, '/'))
20077     {
20078       errmsg ("illegal characters in filename '%s'", file);
20079       return 0;
20080     }
20081
20082   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20083
20084   vec_free (file);
20085
20086   errmsg ("Saving %wd of %wd events to %s",
20087           elog_n_events_in_buffer (em),
20088           elog_buffer_capacity (em), chroot_file);
20089
20090   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20091   vec_free (chroot_file);
20092
20093   if (error)
20094     clib_error_report (error);
20095 #else
20096   errmsg ("Use the vpp event loger...");
20097 #endif
20098
20099   return 0;
20100 }
20101
20102 static int
20103 elog_setup (vat_main_t * vam)
20104 {
20105 #if VPP_API_TEST_BUILTIN == 0
20106   elog_main_t *em = &vam->elog_main;
20107   unformat_input_t *i = vam->input;
20108   u32 nevents = 128 << 10;
20109
20110   (void) unformat (i, "nevents %d", &nevents);
20111
20112   elog_init (em, nevents);
20113   vl_api_set_elog_main (em);
20114   vl_api_set_elog_trace_api_messages (1);
20115   errmsg ("Event logger initialized with %u events", nevents);
20116 #else
20117   errmsg ("Use the vpp event loger...");
20118 #endif
20119   return 0;
20120 }
20121
20122 static int
20123 elog_enable (vat_main_t * vam)
20124 {
20125 #if VPP_API_TEST_BUILTIN == 0
20126   elog_main_t *em = &vam->elog_main;
20127
20128   elog_enable_disable (em, 1 /* enable */ );
20129   vl_api_set_elog_trace_api_messages (1);
20130   errmsg ("Event logger enabled...");
20131 #else
20132   errmsg ("Use the vpp event loger...");
20133 #endif
20134   return 0;
20135 }
20136
20137 static int
20138 elog_disable (vat_main_t * vam)
20139 {
20140 #if VPP_API_TEST_BUILTIN == 0
20141   elog_main_t *em = &vam->elog_main;
20142
20143   elog_enable_disable (em, 0 /* enable */ );
20144   vl_api_set_elog_trace_api_messages (1);
20145   errmsg ("Event logger disabled...");
20146 #else
20147   errmsg ("Use the vpp event loger...");
20148 #endif
20149   return 0;
20150 }
20151
20152 static int
20153 statseg (vat_main_t * vam)
20154 {
20155   ssvm_private_t *ssvmp = &vam->stat_segment;
20156   ssvm_shared_header_t *shared_header = ssvmp->sh;
20157   vlib_counter_t **counters;
20158   u64 thread0_index1_packets;
20159   u64 thread0_index1_bytes;
20160   f64 vector_rate, input_rate;
20161   uword *p;
20162
20163   uword *counter_vector_by_name;
20164   if (vam->stat_segment_lockp == 0)
20165     {
20166       errmsg ("Stat segment not mapped...");
20167       return -99;
20168     }
20169
20170   /* look up "/if/rx for sw_if_index 1 as a test */
20171
20172   clib_spinlock_lock (vam->stat_segment_lockp);
20173
20174   counter_vector_by_name = (uword *) shared_header->opaque[1];
20175
20176   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20177   if (p == 0)
20178     {
20179       clib_spinlock_unlock (vam->stat_segment_lockp);
20180       errmsg ("/if/tx not found?");
20181       return -99;
20182     }
20183
20184   /* Fish per-thread vector of combined counters from shared memory */
20185   counters = (vlib_counter_t **) p[0];
20186
20187   if (vec_len (counters[0]) < 2)
20188     {
20189       clib_spinlock_unlock (vam->stat_segment_lockp);
20190       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20191       return -99;
20192     }
20193
20194   /* Read thread 0 sw_if_index 1 counter */
20195   thread0_index1_packets = counters[0][1].packets;
20196   thread0_index1_bytes = counters[0][1].bytes;
20197
20198   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20199   if (p == 0)
20200     {
20201       clib_spinlock_unlock (vam->stat_segment_lockp);
20202       errmsg ("vector_rate not found?");
20203       return -99;
20204     }
20205
20206   vector_rate = *(f64 *) (p[0]);
20207   p = hash_get_mem (counter_vector_by_name, "input_rate");
20208   if (p == 0)
20209     {
20210       clib_spinlock_unlock (vam->stat_segment_lockp);
20211       errmsg ("input_rate not found?");
20212       return -99;
20213     }
20214   input_rate = *(f64 *) (p[0]);
20215
20216   clib_spinlock_unlock (vam->stat_segment_lockp);
20217
20218   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20219          vector_rate, input_rate);
20220   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20221          thread0_index1_packets, thread0_index1_bytes);
20222
20223   return 0;
20224 }
20225
20226 static int
20227 cmd_cmp (void *a1, void *a2)
20228 {
20229   u8 **c1 = a1;
20230   u8 **c2 = a2;
20231
20232   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20233 }
20234
20235 static int
20236 help (vat_main_t * vam)
20237 {
20238   u8 **cmds = 0;
20239   u8 *name = 0;
20240   hash_pair_t *p;
20241   unformat_input_t *i = vam->input;
20242   int j;
20243
20244   if (unformat (i, "%s", &name))
20245     {
20246       uword *hs;
20247
20248       vec_add1 (name, 0);
20249
20250       hs = hash_get_mem (vam->help_by_name, name);
20251       if (hs)
20252         print (vam->ofp, "usage: %s %s", name, hs[0]);
20253       else
20254         print (vam->ofp, "No such msg / command '%s'", name);
20255       vec_free (name);
20256       return 0;
20257     }
20258
20259   print (vam->ofp, "Help is available for the following:");
20260
20261     /* *INDENT-OFF* */
20262     hash_foreach_pair (p, vam->function_by_name,
20263     ({
20264       vec_add1 (cmds, (u8 *)(p->key));
20265     }));
20266     /* *INDENT-ON* */
20267
20268   vec_sort_with_function (cmds, cmd_cmp);
20269
20270   for (j = 0; j < vec_len (cmds); j++)
20271     print (vam->ofp, "%s", cmds[j]);
20272
20273   vec_free (cmds);
20274   return 0;
20275 }
20276
20277 static int
20278 set (vat_main_t * vam)
20279 {
20280   u8 *name = 0, *value = 0;
20281   unformat_input_t *i = vam->input;
20282
20283   if (unformat (i, "%s", &name))
20284     {
20285       /* The input buffer is a vector, not a string. */
20286       value = vec_dup (i->buffer);
20287       vec_delete (value, i->index, 0);
20288       /* Almost certainly has a trailing newline */
20289       if (value[vec_len (value) - 1] == '\n')
20290         value[vec_len (value) - 1] = 0;
20291       /* Make sure it's a proper string, one way or the other */
20292       vec_add1 (value, 0);
20293       (void) clib_macro_set_value (&vam->macro_main,
20294                                    (char *) name, (char *) value);
20295     }
20296   else
20297     errmsg ("usage: set <name> <value>");
20298
20299   vec_free (name);
20300   vec_free (value);
20301   return 0;
20302 }
20303
20304 static int
20305 unset (vat_main_t * vam)
20306 {
20307   u8 *name = 0;
20308
20309   if (unformat (vam->input, "%s", &name))
20310     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20311       errmsg ("unset: %s wasn't set", name);
20312   vec_free (name);
20313   return 0;
20314 }
20315
20316 typedef struct
20317 {
20318   u8 *name;
20319   u8 *value;
20320 } macro_sort_t;
20321
20322
20323 static int
20324 macro_sort_cmp (void *a1, void *a2)
20325 {
20326   macro_sort_t *s1 = a1;
20327   macro_sort_t *s2 = a2;
20328
20329   return strcmp ((char *) (s1->name), (char *) (s2->name));
20330 }
20331
20332 static int
20333 dump_macro_table (vat_main_t * vam)
20334 {
20335   macro_sort_t *sort_me = 0, *sm;
20336   int i;
20337   hash_pair_t *p;
20338
20339     /* *INDENT-OFF* */
20340     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20341     ({
20342       vec_add2 (sort_me, sm, 1);
20343       sm->name = (u8 *)(p->key);
20344       sm->value = (u8 *) (p->value[0]);
20345     }));
20346     /* *INDENT-ON* */
20347
20348   vec_sort_with_function (sort_me, macro_sort_cmp);
20349
20350   if (vec_len (sort_me))
20351     print (vam->ofp, "%-15s%s", "Name", "Value");
20352   else
20353     print (vam->ofp, "The macro table is empty...");
20354
20355   for (i = 0; i < vec_len (sort_me); i++)
20356     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20357   return 0;
20358 }
20359
20360 static int
20361 dump_node_table (vat_main_t * vam)
20362 {
20363   int i, j;
20364   vlib_node_t *node, *next_node;
20365
20366   if (vec_len (vam->graph_nodes) == 0)
20367     {
20368       print (vam->ofp, "Node table empty, issue get_node_graph...");
20369       return 0;
20370     }
20371
20372   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20373     {
20374       node = vam->graph_nodes[0][i];
20375       print (vam->ofp, "[%d] %s", i, node->name);
20376       for (j = 0; j < vec_len (node->next_nodes); j++)
20377         {
20378           if (node->next_nodes[j] != ~0)
20379             {
20380               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20381               print (vam->ofp, "  [%d] %s", j, next_node->name);
20382             }
20383         }
20384     }
20385   return 0;
20386 }
20387
20388 static int
20389 value_sort_cmp (void *a1, void *a2)
20390 {
20391   name_sort_t *n1 = a1;
20392   name_sort_t *n2 = a2;
20393
20394   if (n1->value < n2->value)
20395     return -1;
20396   if (n1->value > n2->value)
20397     return 1;
20398   return 0;
20399 }
20400
20401
20402 static int
20403 dump_msg_api_table (vat_main_t * vam)
20404 {
20405   api_main_t *am = vlibapi_get_main ();
20406   name_sort_t *nses = 0, *ns;
20407   hash_pair_t *hp;
20408   int i;
20409
20410   /* *INDENT-OFF* */
20411   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20412   ({
20413     vec_add2 (nses, ns, 1);
20414     ns->name = (u8 *)(hp->key);
20415     ns->value = (u32) hp->value[0];
20416   }));
20417   /* *INDENT-ON* */
20418
20419   vec_sort_with_function (nses, value_sort_cmp);
20420
20421   for (i = 0; i < vec_len (nses); i++)
20422     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20423   vec_free (nses);
20424   return 0;
20425 }
20426
20427 static int
20428 get_msg_id (vat_main_t * vam)
20429 {
20430   u8 *name_and_crc;
20431   u32 message_index;
20432
20433   if (unformat (vam->input, "%s", &name_and_crc))
20434     {
20435       message_index = vl_msg_api_get_msg_index (name_and_crc);
20436       if (message_index == ~0)
20437         {
20438           print (vam->ofp, " '%s' not found", name_and_crc);
20439           return 0;
20440         }
20441       print (vam->ofp, " '%s' has message index %d",
20442              name_and_crc, message_index);
20443       return 0;
20444     }
20445   errmsg ("name_and_crc required...");
20446   return 0;
20447 }
20448
20449 static int
20450 search_node_table (vat_main_t * vam)
20451 {
20452   unformat_input_t *line_input = vam->input;
20453   u8 *node_to_find;
20454   int j;
20455   vlib_node_t *node, *next_node;
20456   uword *p;
20457
20458   if (vam->graph_node_index_by_name == 0)
20459     {
20460       print (vam->ofp, "Node table empty, issue get_node_graph...");
20461       return 0;
20462     }
20463
20464   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20465     {
20466       if (unformat (line_input, "%s", &node_to_find))
20467         {
20468           vec_add1 (node_to_find, 0);
20469           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20470           if (p == 0)
20471             {
20472               print (vam->ofp, "%s not found...", node_to_find);
20473               goto out;
20474             }
20475           node = vam->graph_nodes[0][p[0]];
20476           print (vam->ofp, "[%d] %s", p[0], node->name);
20477           for (j = 0; j < vec_len (node->next_nodes); j++)
20478             {
20479               if (node->next_nodes[j] != ~0)
20480                 {
20481                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20482                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20483                 }
20484             }
20485         }
20486
20487       else
20488         {
20489           clib_warning ("parse error '%U'", format_unformat_error,
20490                         line_input);
20491           return -99;
20492         }
20493
20494     out:
20495       vec_free (node_to_find);
20496
20497     }
20498
20499   return 0;
20500 }
20501
20502
20503 static int
20504 script (vat_main_t * vam)
20505 {
20506 #if (VPP_API_TEST_BUILTIN==0)
20507   u8 *s = 0;
20508   char *save_current_file;
20509   unformat_input_t save_input;
20510   jmp_buf save_jump_buf;
20511   u32 save_line_number;
20512
20513   FILE *new_fp, *save_ifp;
20514
20515   if (unformat (vam->input, "%s", &s))
20516     {
20517       new_fp = fopen ((char *) s, "r");
20518       if (new_fp == 0)
20519         {
20520           errmsg ("Couldn't open script file %s", s);
20521           vec_free (s);
20522           return -99;
20523         }
20524     }
20525   else
20526     {
20527       errmsg ("Missing script name");
20528       return -99;
20529     }
20530
20531   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20532   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20533   save_ifp = vam->ifp;
20534   save_line_number = vam->input_line_number;
20535   save_current_file = (char *) vam->current_file;
20536
20537   vam->input_line_number = 0;
20538   vam->ifp = new_fp;
20539   vam->current_file = s;
20540   do_one_file (vam);
20541
20542   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20543   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20544   vam->ifp = save_ifp;
20545   vam->input_line_number = save_line_number;
20546   vam->current_file = (u8 *) save_current_file;
20547   vec_free (s);
20548
20549   return 0;
20550 #else
20551   clib_warning ("use the exec command...");
20552   return -99;
20553 #endif
20554 }
20555
20556 static int
20557 echo (vat_main_t * vam)
20558 {
20559   print (vam->ofp, "%v", vam->input->buffer);
20560   return 0;
20561 }
20562
20563 /* List of API message constructors, CLI names map to api_xxx */
20564 #define foreach_vpe_api_msg                                             \
20565 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20566 _(sw_interface_dump,"")                                                 \
20567 _(sw_interface_set_flags,                                               \
20568   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20569 _(sw_interface_add_del_address,                                         \
20570   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20571 _(sw_interface_set_rx_mode,                                             \
20572   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20573 _(sw_interface_set_rx_placement,                                        \
20574   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20575 _(sw_interface_rx_placement_dump,                                       \
20576   "[<intfc> | sw_if_index <id>]")                                         \
20577 _(sw_interface_set_table,                                               \
20578   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20579 _(sw_interface_set_mpls_enable,                                         \
20580   "<intfc> | sw_if_index [disable | dis]")                              \
20581 _(sw_interface_set_vpath,                                               \
20582   "<intfc> | sw_if_index <id> enable | disable")                        \
20583 _(sw_interface_set_vxlan_bypass,                                        \
20584   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20585 _(sw_interface_set_geneve_bypass,                                       \
20586   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20587 _(sw_interface_set_l2_xconnect,                                         \
20588   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20589   "enable | disable")                                                   \
20590 _(sw_interface_set_l2_bridge,                                           \
20591   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20592   "[shg <split-horizon-group>] [bvi]\n"                                 \
20593   "enable | disable")                                                   \
20594 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20595 _(bridge_domain_add_del,                                                \
20596   "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") \
20597 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20598 _(l2fib_add_del,                                                        \
20599   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20600 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20601 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20602 _(l2_flags,                                                             \
20603   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20604 _(bridge_flags,                                                         \
20605   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20606 _(tap_create_v2,                                                        \
20607   "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 | gro-coalesce] [persist] [attach] [tun]") \
20608 _(tap_delete_v2,                                                        \
20609   "<vpp-if-name> | sw_if_index <id>")                                   \
20610 _(sw_interface_tap_v2_dump, "")                                         \
20611 _(virtio_pci_create,                                                    \
20612   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20613 _(virtio_pci_delete,                                                    \
20614   "<vpp-if-name> | sw_if_index <id>")                                   \
20615 _(sw_interface_virtio_pci_dump, "")                                     \
20616 _(bond_create,                                                          \
20617   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20618   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20619   "[id <if-id>]")                                                       \
20620 _(bond_delete,                                                          \
20621   "<vpp-if-name> | sw_if_index <id>")                                   \
20622 _(bond_enslave,                                                         \
20623   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20624 _(bond_detach_slave,                                                    \
20625   "sw_if_index <n>")                                                    \
20626  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20627 _(sw_interface_bond_dump, "")                                           \
20628 _(sw_interface_slave_dump,                                              \
20629   "<vpp-if-name> | sw_if_index <id>")                                   \
20630 _(ip_table_add_del,                                                     \
20631   "table <n> [ipv6] [add | del]\n")                                     \
20632 _(ip_route_add_del,                                                     \
20633   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20634   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20635   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20636   "[multipath] [count <n>] [del]")                                      \
20637 _(ip_mroute_add_del,                                                    \
20638   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20639   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20640 _(mpls_table_add_del,                                                   \
20641   "table <n> [add | del]\n")                                            \
20642 _(mpls_route_add_del,                                                   \
20643   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20644   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20645   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20646   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20647   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20648   "[count <n>] [del]")                                                  \
20649 _(mpls_ip_bind_unbind,                                                  \
20650   "<label> <addr/len>")                                                 \
20651 _(mpls_tunnel_add_del,                                                  \
20652   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20653   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20654   "[l2-only]  [out-label <n>]")                                         \
20655 _(sr_mpls_policy_add,                                                   \
20656   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20657 _(sr_mpls_policy_del,                                                   \
20658   "bsid <id>")                                                          \
20659 _(bier_table_add_del,                                                   \
20660   "<label> <sub-domain> <set> <bsl> [del]")                             \
20661 _(bier_route_add_del,                                                   \
20662   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20663   "[<intfc> | sw_if_index <id>]"                                        \
20664   "[weight <n>] [del] [multipath]")                                     \
20665 _(sw_interface_set_unnumbered,                                          \
20666   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20667 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20668 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20669   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20670   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20671   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20672 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20673 _(ip_table_flush, "table <n> [ipv6]")                                   \
20674 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20675 _(set_ip_flow_hash,                                                     \
20676   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20677 _(sw_interface_ip6_enable_disable,                                      \
20678   "<intfc> | sw_if_index <id> enable | disable")                        \
20679 _(l2_patch_add_del,                                                     \
20680   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20681   "enable | disable")                                                   \
20682 _(sr_localsid_add_del,                                                  \
20683   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20684   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20685 _(classify_add_del_table,                                               \
20686   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20687   " [del] [del-chain] mask <mask-value>\n"                              \
20688   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20689   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20690 _(classify_add_del_session,                                             \
20691   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20692   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20693   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20694   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20695 _(classify_set_interface_ip_table,                                      \
20696   "<intfc> | sw_if_index <nn> table <nn>")                              \
20697 _(classify_set_interface_l2_tables,                                     \
20698   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20699   "  [other-table <nn>]")                                               \
20700 _(get_node_index, "node <node-name")                                    \
20701 _(add_node_next, "node <node-name> next <next-node-name>")              \
20702 _(l2tpv3_create_tunnel,                                                 \
20703   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20704   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20705   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20706 _(l2tpv3_set_tunnel_cookies,                                            \
20707   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20708   "[new_remote_cookie <nn>]\n")                                         \
20709 _(l2tpv3_interface_enable_disable,                                      \
20710   "<intfc> | sw_if_index <nn> enable | disable")                        \
20711 _(l2tpv3_set_lookup_key,                                                \
20712   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20713 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20714 _(vxlan_offload_rx,                                                     \
20715   "hw { <interface name> | hw_if_index <nn>} "                          \
20716   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20717 _(vxlan_add_del_tunnel,                                                 \
20718   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20719   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20720   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20721 _(geneve_add_del_tunnel,                                                \
20722   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20723   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20724   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20725 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20726 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20727 _(gre_tunnel_add_del,                                                   \
20728   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20729   "[teb | erspan <session-id>] [del]")                                  \
20730 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20731 _(l2_fib_clear_table, "")                                               \
20732 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20733 _(l2_interface_vlan_tag_rewrite,                                        \
20734   "<intfc> | sw_if_index <nn> \n"                                       \
20735   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20736   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20737 _(create_vhost_user_if,                                                 \
20738         "socket <filename> [server] [renumber <dev_instance>] "         \
20739         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20740         "[mac <mac_address>] [packed]")                                 \
20741 _(modify_vhost_user_if,                                                 \
20742         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20743         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20744 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20745 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20746 _(show_version, "")                                                     \
20747 _(show_threads, "")                                                     \
20748 _(vxlan_gpe_add_del_tunnel,                                             \
20749   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20750   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20751   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20752   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20753 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20754 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20755 _(interface_name_renumber,                                              \
20756   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20757 _(input_acl_set_interface,                                              \
20758   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20759   "  [l2-table <nn>] [del]")                                            \
20760 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20761 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20762 _(ip_dump, "ipv4 | ipv6")                                               \
20763 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20764 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20765   "  spid_id <n> ")                                                     \
20766 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20767   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20768   "  integ_alg <alg> integ_key <hex>")                                  \
20769 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20770   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20771   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20772   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20773 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20774   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20775   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20776   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20777   "  [instance <n>]")     \
20778 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20779 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20780 _(delete_loopback,"sw_if_index <nn>")                                   \
20781 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20782 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20783 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20784 _(want_interface_events,  "enable|disable")                             \
20785 _(get_first_msg_id, "client <name>")                                    \
20786 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20787 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20788   "fib-id <nn> [ip4][ip6][default]")                                    \
20789 _(get_node_graph, " ")                                                  \
20790 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20791 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20792 _(ioam_disable, "")                                                     \
20793 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20794                             " sw_if_index <sw_if_index> p <priority> "  \
20795                             "w <weight>] [del]")                        \
20796 _(one_add_del_locator, "locator-set <locator_name> "                    \
20797                         "iface <intf> | sw_if_index <sw_if_index> "     \
20798                         "p <priority> w <weight> [del]")                \
20799 _(one_add_del_local_eid,"vni <vni> eid "                                \
20800                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20801                          "locator-set <locator_name> [del]"             \
20802                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20803 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20804 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20805 _(one_enable_disable, "enable|disable")                                 \
20806 _(one_map_register_enable_disable, "enable|disable")                    \
20807 _(one_map_register_fallback_threshold, "<value>")                       \
20808 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20809 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20810                                "[seid <seid>] "                         \
20811                                "rloc <locator> p <prio> "               \
20812                                "w <weight> [rloc <loc> ... ] "          \
20813                                "action <action> [del-all]")             \
20814 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20815                           "<local-eid>")                                \
20816 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20817 _(one_use_petr, "ip-address> | disable")                                \
20818 _(one_map_request_mode, "src-dst|dst-only")                             \
20819 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20820 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20821 _(one_locator_set_dump, "[local | remote]")                             \
20822 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20823 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20824                        "[local] | [remote]")                            \
20825 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20826 _(one_ndp_bd_get, "")                                                   \
20827 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20828 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20829 _(one_l2_arp_bd_get, "")                                                \
20830 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20831 _(one_stats_enable_disable, "enable|disable")                           \
20832 _(show_one_stats_enable_disable, "")                                    \
20833 _(one_eid_table_vni_dump, "")                                           \
20834 _(one_eid_table_map_dump, "l2|l3")                                      \
20835 _(one_map_resolver_dump, "")                                            \
20836 _(one_map_server_dump, "")                                              \
20837 _(one_adjacencies_get, "vni <vni>")                                     \
20838 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20839 _(show_one_rloc_probe_state, "")                                        \
20840 _(show_one_map_register_state, "")                                      \
20841 _(show_one_status, "")                                                  \
20842 _(one_stats_dump, "")                                                   \
20843 _(one_stats_flush, "")                                                  \
20844 _(one_get_map_request_itr_rlocs, "")                                    \
20845 _(one_map_register_set_ttl, "<ttl>")                                    \
20846 _(one_set_transport_protocol, "udp|api")                                \
20847 _(one_get_transport_protocol, "")                                       \
20848 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20849 _(one_show_xtr_mode, "")                                                \
20850 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20851 _(one_show_pitr_mode, "")                                               \
20852 _(one_enable_disable_petr_mode, "enable|disable")                       \
20853 _(one_show_petr_mode, "")                                               \
20854 _(show_one_nsh_mapping, "")                                             \
20855 _(show_one_pitr, "")                                                    \
20856 _(show_one_use_petr, "")                                                \
20857 _(show_one_map_request_mode, "")                                        \
20858 _(show_one_map_register_ttl, "")                                        \
20859 _(show_one_map_register_fallback_threshold, "")                         \
20860 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20861                             " sw_if_index <sw_if_index> p <priority> "  \
20862                             "w <weight>] [del]")                        \
20863 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20864                         "iface <intf> | sw_if_index <sw_if_index> "     \
20865                         "p <priority> w <weight> [del]")                \
20866 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20867                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20868                          "locator-set <locator_name> [del]"             \
20869                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20870 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20871 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20872 _(lisp_enable_disable, "enable|disable")                                \
20873 _(lisp_map_register_enable_disable, "enable|disable")                   \
20874 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20875 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20876                                "[seid <seid>] "                         \
20877                                "rloc <locator> p <prio> "               \
20878                                "w <weight> [rloc <loc> ... ] "          \
20879                                "action <action> [del-all]")             \
20880 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20881                           "<local-eid>")                                \
20882 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20883 _(lisp_use_petr, "<ip-address> | disable")                              \
20884 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20885 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20886 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20887 _(lisp_locator_set_dump, "[local | remote]")                            \
20888 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20889 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20890                        "[local] | [remote]")                            \
20891 _(lisp_eid_table_vni_dump, "")                                          \
20892 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20893 _(lisp_map_resolver_dump, "")                                           \
20894 _(lisp_map_server_dump, "")                                             \
20895 _(lisp_adjacencies_get, "vni <vni>")                                    \
20896 _(gpe_fwd_entry_vnis_get, "")                                           \
20897 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20898 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20899                                 "[table <table-id>]")                   \
20900 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20901 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20902 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20903 _(gpe_get_encap_mode, "")                                               \
20904 _(lisp_gpe_add_del_iface, "up|down")                                    \
20905 _(lisp_gpe_enable_disable, "enable|disable")                            \
20906 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20907   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20908 _(show_lisp_rloc_probe_state, "")                                       \
20909 _(show_lisp_map_register_state, "")                                     \
20910 _(show_lisp_status, "")                                                 \
20911 _(lisp_get_map_request_itr_rlocs, "")                                   \
20912 _(show_lisp_pitr, "")                                                   \
20913 _(show_lisp_use_petr, "")                                               \
20914 _(show_lisp_map_request_mode, "")                                       \
20915 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20916 _(af_packet_delete, "name <host interface name>")                       \
20917 _(af_packet_dump, "")                                                   \
20918 _(policer_add_del, "name <policer name> <params> [del]")                \
20919 _(policer_dump, "[name <policer name>]")                                \
20920 _(policer_classify_set_interface,                                       \
20921   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20922   "  [l2-table <nn>] [del]")                                            \
20923 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20924 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20925 _(mpls_table_dump, "")                                                  \
20926 _(mpls_route_dump, "table-id <ID>")                                     \
20927 _(classify_table_ids, "")                                               \
20928 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20929 _(classify_table_info, "table_id <nn>")                                 \
20930 _(classify_session_dump, "table_id <nn>")                               \
20931 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20932     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20933     "[template_interval <nn>] [udp_checksum]")                          \
20934 _(ipfix_exporter_dump, "")                                              \
20935 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20936 _(ipfix_classify_stream_dump, "")                                       \
20937 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20938 _(ipfix_classify_table_dump, "")                                        \
20939 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20940 _(sw_interface_span_dump, "[l2]")                                           \
20941 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20942 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20943 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20944 _(pg_enable_disable, "[stream <id>] disable")                           \
20945 _(ip_source_and_port_range_check_add_del,                               \
20946   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20947 _(ip_source_and_port_range_check_interface_add_del,                     \
20948   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20949   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20950 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20951 _(l2_interface_pbb_tag_rewrite,                                         \
20952   "<intfc> | sw_if_index <nn> \n"                                       \
20953   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20954   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20955 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20956 _(flow_classify_set_interface,                                          \
20957   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20958 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20959 _(ip_table_dump, "")                                                    \
20960 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20961 _(ip_mtable_dump, "")                                                   \
20962 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20963 _(feature_enable_disable, "arc_name <arc_name> "                        \
20964   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20965 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20966   "[enable | disable] ")                                                \
20967 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20968 "[disable]")                                                            \
20969 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20970   "mac <mac-address> [del]")                                            \
20971 _(l2_xconnect_dump, "")                                                 \
20972 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20973 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20974 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20975 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20976 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20977 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
20978   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
20979 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20980 _(sock_init_shm, "size <nnn>")                                          \
20981 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20982 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20983   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20984 _(session_rules_dump, "")                                               \
20985 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20986 _(output_acl_set_interface,                                             \
20987   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20988   "  [l2-table <nn>] [del]")                                            \
20989 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
20990
20991 /* List of command functions, CLI names map directly to functions */
20992 #define foreach_cli_function                                    \
20993 _(comment, "usage: comment <ignore-rest-of-line>")              \
20994 _(dump_interface_table, "usage: dump_interface_table")          \
20995 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20996 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20997 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20998 _(dump_macro_table, "usage: dump_macro_table ")                 \
20999 _(dump_node_table, "usage: dump_node_table")                    \
21000 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21001 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21002 _(elog_disable, "usage: elog_disable")                          \
21003 _(elog_enable, "usage: elog_enable")                            \
21004 _(elog_save, "usage: elog_save <filename>")                     \
21005 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21006 _(echo, "usage: echo <message>")                                \
21007 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21008 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21009 _(help, "usage: help")                                          \
21010 _(q, "usage: quit")                                             \
21011 _(quit, "usage: quit")                                          \
21012 _(search_node_table, "usage: search_node_table <name>...")      \
21013 _(set, "usage: set <variable-name> <value>")                    \
21014 _(script, "usage: script <file-name>")                          \
21015 _(statseg, "usage: statseg")                                    \
21016 _(unset, "usage: unset <variable-name>")
21017
21018 #define _(N,n)                                  \
21019     static void vl_api_##n##_t_handler_uni      \
21020     (vl_api_##n##_t * mp)                       \
21021     {                                           \
21022         vat_main_t * vam = &vat_main;           \
21023         if (vam->json_output) {                 \
21024             vl_api_##n##_t_handler_json(mp);    \
21025         } else {                                \
21026             vl_api_##n##_t_handler(mp);         \
21027         }                                       \
21028     }
21029 foreach_vpe_api_reply_msg;
21030 #if VPP_API_TEST_BUILTIN == 0
21031 foreach_standalone_reply_msg;
21032 #endif
21033 #undef _
21034
21035 void
21036 vat_api_hookup (vat_main_t * vam)
21037 {
21038 #define _(N,n)                                                  \
21039     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21040                            vl_api_##n##_t_handler_uni,          \
21041                            vl_noop_handler,                     \
21042                            vl_api_##n##_t_endian,               \
21043                            vl_api_##n##_t_print,                \
21044                            sizeof(vl_api_##n##_t), 1);
21045   foreach_vpe_api_reply_msg;
21046 #if VPP_API_TEST_BUILTIN == 0
21047   foreach_standalone_reply_msg;
21048 #endif
21049 #undef _
21050
21051 #if (VPP_API_TEST_BUILTIN==0)
21052   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21053
21054   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21055
21056   vam->function_by_name = hash_create_string (0, sizeof (uword));
21057
21058   vam->help_by_name = hash_create_string (0, sizeof (uword));
21059 #endif
21060
21061   /* API messages we can send */
21062 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21063   foreach_vpe_api_msg;
21064 #undef _
21065
21066   /* Help strings */
21067 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21068   foreach_vpe_api_msg;
21069 #undef _
21070
21071   /* CLI functions */
21072 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21073   foreach_cli_function;
21074 #undef _
21075
21076   /* Help strings */
21077 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21078   foreach_cli_function;
21079 #undef _
21080 }
21081
21082 #if VPP_API_TEST_BUILTIN
21083 static clib_error_t *
21084 vat_api_hookup_shim (vlib_main_t * vm)
21085 {
21086   vat_api_hookup (&vat_main);
21087   return 0;
21088 }
21089
21090 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21091 #endif
21092
21093 /*
21094  * fd.io coding-style-patch-verification: ON
21095  *
21096  * Local Variables:
21097  * eval: (c-set-style "gnu")
21098  * End:
21099  */